Đồng hồ đếm ngược là một tiện ích cực kỳ hữu ích trong nhiều tình huống như sự kiện, học tập, thể thao, hoặc đơn giản là làm công cụ nhắc nhở. Trong bài viết này, CodeTutHub sẽ hướng dẫn bạn cách tạo một Countdown Timer tùy chỉnh bằng HTML, CSS và JavaScript thuần, có đầy đủ chức năng:

  • Nhập giờ / phút / giây
  • Bắt đầu đếm ngược
  • Tạm dừng / tiếp tục
  • Đặt lại (reset)

🧱 Giao Diện Cơ Bản

Chúng ta sẽ có một giao diện thân thiện với:

  • 3 input nhập giờ, phút, giây
  • Các nút điều khiển: Start, Pause/Resume, Reset
  • Đồng hồ hiển thị đếm ngược thời gian còn lại
  • Khi hết thời gian, hiển thị thông báo "⏰ Time off" màu đỏ

📦 Mã nguồn đầy đủ

Dưới đây là mã HTML + CSS + JavaScript bạn có thể dùng ngay:

html
<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Countdown Hoàn Chỉnh - CodeTutHub</title>
  <style>
    body {
      background: #f9fafb;
      font-family: 'Segoe UI', sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      padding-top: 50px;
    }
    .input-group {
      display: flex;
      gap: 10px;
      margin-bottom: 20px;
      flex-wrap: wrap;
      justify-content: center;
    }
    input {
      width: 70px;
      padding: 8px;
      text-align: center;
      border: 1px solid #d1d5db;
      border-radius: 8px;
    }
    button {
      padding: 8px 16px;
      background-color: #2563eb;
      color: white;
      border: none;
      border-radius: 8px;
      cursor: pointer;
    }
    .countdown {
      display: flex;
      gap: 20px;
      margin-top: 20px;
      font-size: 2rem;
    }
    .message {
      margin-top: 30px;
      font-size: 1.5rem;
      font-weight: bold;
      color: red;
    }
  </style>
</head>
<body>
  <h2>Nhập thời gian đếm ngược</h2>
  <div class="input-group">
    <input type="number" id="hours" placeholder="Giờ" min="0" />
    <input type="number" id="minutes" placeholder="Phút" min="0" />
    <input type="number" id="seconds" placeholder="Giây" min="0" />
    <button onclick="startCountdown()" id="startBtn">Start</button>
    <button onclick="togglePause()" id="pauseBtn" style="display:none;">Pause</button>
    <button onclick="resetCountdown()" id="resetBtn" style="display:none;">Reset</button>
  </div>

  <div class="countdown" id="countdownDisplay" style="display: none;">
    <span id="h">00</span>:
    <span id="m">00</span>:
    <span id="s">00</span>
  </div>
  <div class="message" id="message"></div>

  <script>
    let interval;
    let totalSeconds = 0;
    let isPaused = false;

    function startCountdown() {
      clearInterval(interval);
      document.getElementById("message").textContent = "";

      const hour = parseInt(document.getElementById("hours").value) || 0;
      const minute = parseInt(document.getElementById("minutes").value) || 0;
      const second = parseInt(document.getElementById("seconds").value) || 0;

      totalSeconds = hour * 3600 + minute * 60 + second;

      if (totalSeconds <= 0) {
        alert("Vui lòng nhập thời gian lớn hơn 0!");
        return;
      }

      disableInputs(true);
      toggleButtons({ pause: true, reset: true });

      document.getElementById("countdownDisplay").style.display = "flex";
      updateDisplay();
      interval = setInterval(tick, 1000);
    }

    function tick() {
      if (!isPaused && totalSeconds > 0) {
        totalSeconds--;
        updateDisplay();
      }

      if (totalSeconds <= 0) {
        clearInterval(interval);
        document.getElementById("message").textContent = "⏰ Time off";
        toggleButtons({ pause: false, reset: true });
      }
    }

    function updateDisplay() {
      const h = Math.floor(totalSeconds / 3600);
      const m = Math.floor((totalSeconds % 3600) / 60);
      const s = totalSeconds % 60;

      document.getElementById("h").textContent = String(h).padStart(2, '0');
      document.getElementById("m").textContent = String(m).padStart(2, '0');
      document.getElementById("s").textContent = String(s).padStart(2, '0');
    }

    function togglePause() {
      isPaused = !isPaused;
      document.getElementById("pauseBtn").textContent = isPaused ? "Resume" : "Pause";
    }

    function resetCountdown() {
      clearInterval(interval);
      totalSeconds = 0;
      isPaused = false;

      document.getElementById("h").textContent = "00";
      document.getElementById("m").textContent = "00";
      document.getElementById("s").textContent = "00";
      document.getElementById("message").textContent = "";
      document.getElementById("countdownDisplay").style.display = "none";

      disableInputs(false);
      document.getElementById("pauseBtn").textContent = "Pause";
      toggleButtons({ pause: false, reset: false });
    }

    function disableInputs(disable) {
      document.getElementById("hours").disabled = disable;
      document.getElementById("minutes").disabled = disable;
      document.getElementById("seconds").disabled = disable;
      document.getElementById("startBtn").disabled = disable;
    }

    function toggleButtons({ pause = false, reset = false }) {
      document.getElementById("pauseBtn").style.display = pause ? "inline-block" : "none";
      document.getElementById("resetBtn").style.display = reset ? "inline-block" : "none";
    }
  </script>
</body>
</html>

✅ Tính năng được hỗ trợ

Tính năngTrạng thái
Nhập thời gian (giờ, phút, giây)✅ Có
Bắt đầu đếm ngược✅ Có
Tạm dừng / Tiếp tục✅ Có
Reset (đặt lại mọi thứ)✅ Có
Hiển thị “Time off” khi hết giờ✅ Có

🧠 Gợi ý mở rộng

  • ✅ Thêm âm thanh khi hết giờ
  • ✅ Hỗ trợ chạy nhiều đồng hồ cùng lúc
  • 🌙 Bật Dark Mode bằng Tailwind
  • 📦 Xuất thành React Component hoặc Vue Component
  • 🔄 Tùy chọn lặp lại sau khi đếm hết