Like / Dislike Counter System with HTML, CSS & JavaScript

30 DAYS 30 PROJECT CHALLENGE

Day #13

Project Overview

A Like / Dislike Counter System built using HTML, CSS, and JavaScript that allows users to react to content with a like or dislike.
The system updates reaction counts instantly and manages user interaction state to prevent multiple or conflicting actions, providing a smooth and intuitive feedback mechanism.

Key Features

  • Like and Dislike buttons with real-time count updates.
  • Prevents multiple selections of the same reaction.
  • Automatically switches state when changing from like to dislike (and vice versa).
  • Visual indication of the active reaction.
  • Clean, responsive, and user-friendly interface.
  • Easily extendable for posts, comments, or API-based systems.

HTML Code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Like / Dislike Counter</title>
  <link rel="stylesheet" href="style.css" />
</head>
<body>

  <div class="counter-container">
    <h2>Like / Dislike System</h2>

    <div class="buttons">
      <button id="likeBtn">👍 Like</button>
      <button id="dislikeBtn">👎 Dislike</button>
    </div>

    <div class="counts">
      <p>Likes: <span id="likeCount">0</span></p>
      <p>Dislikes: <span id="dislikeCount">0</span></p>
    </div>
  </div>

  <script src="script.js"></script>
</body>
</html>

CSS Code

* {
  box-sizing: border-box;
  font-family: "Segoe UI", sans-serif;
}

body {
  min-height: 100vh;
  background: #042453;
  display: flex;
  justify-content: center;
  align-items: center;
}

.counter-container {
  background: #ffffff;
  width: 300px;
  padding: 25px;
  border-radius: 12px;
  text-align: center;
  box-shadow: 0 15px 30px rgba(0,0,0,0.1);
}

h2 {
  margin-bottom: 20px;
}

.buttons {
  display: flex;
  justify-content: space-between;
  margin-bottom: 15px;
}

button {
  flex: 1;
  margin: 0 5px;
  padding: 10px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
}

#likeBtn {
  background: #22c55e;
  color: white;
}

#dislikeBtn {
  background: #ef4444;
  color: white;
}

button.active {
  opacity: 0.7;
}

.counts p {
  margin: 5px 0;
  font-size: 14px;
}

Javascript Code

const likeBtn = document.getElementById("likeBtn");
const dislikeBtn = document.getElementById("dislikeBtn");
const likeCount = document.getElementById("likeCount");
const dislikeCount = document.getElementById("dislikeCount");

let likes = 0;
let dislikes = 0;
let userAction = null; // "like" or "dislike"

likeBtn.addEventListener("click", () => {
  if (userAction === "like") return;

  if (userAction === "dislike") {
    dislikes--;
    dislikeCount.innerText = dislikes;
    dislikeBtn.classList.remove("active");
  }

  likes++;
  likeCount.innerText = likes;
  likeBtn.classList.add("active");
  userAction = "like";
});

dislikeBtn.addEventListener("click", () => {
  if (userAction === "dislike") return;

  if (userAction === "like") {
    likes--;
    likeCount.innerText = likes;
    likeBtn.classList.remove("active");
  }

  dislikes++;
  dislikeCount.innerText = dislikes;
  dislikeBtn.classList.add("active");
  userAction = "dislike";
});
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Related Projects

Day 10 : Skeleton Loader (Shimmer Effect)

Displays animated placeholders while content is loading.

Concepts: Loading states, shimmer animation, UI feedback, conditional rendering.

Day 11 : User Profile Card Generator

Generates a user profile card dynamically from form inputs.

Concepts: User input processing, live UI generation, state-based rendering.

Day 15 : Email Subscription Form

Simple email subscription form with validation and feedback messages.

Concepts: Form validation, user input handling, dynamic UI feedback.