Back to Projects Beginner

Countdown Timer

Set a time in minutes and seconds, press start, and watch it count down to zero. A fun, visual project that teaches you timers and live DOM updates.

HTML, CSS, JavaScript ~1-2 hours to build Free source code

What You'll Learn

  • How to use setInterval() to run code repeatedly every second
  • How to use clearInterval() to stop a running timer
  • How to read values from input fields with JavaScript
  • How to convert between minutes and seconds using basic math
  • How to update text content on the page in real time

How It Works

User enters a time

Two input fields let the user type in minutes and seconds. JavaScript reads those values and converts them into a single total-seconds number to count down from.

setInterval ticks every second

setInterval() runs a function once every 1000 milliseconds. Each tick subtracts one from the total, then updates the display. When it hits zero the interval is cleared.

Reset brings everything back

The reset button clears the interval, sets the counter back to zero, empties the input fields, and clears any messages - ready for another countdown.

Source Code

HTML Structure

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Countdown Timer</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="timer-app">
    <h1>Countdown Timer</h1>
    <p class="subtitle">Set a time and watch it count down</p>
    <div class="time-display">
      <div class="time-box">
        <span class="value" id="displayMin">00</span>
        <span class="label">Minutes</span>
      </div>
      <div class="time-box">
        <span class="value" id="displaySec">00</span>
        <span class="label">Seconds</span>
      </div>
    </div>
    <div class="input-row">
      <input type="number" id="inputMin" placeholder="Min" min="0" max="99">
      <input type="number" id="inputSec" placeholder="Sec" min="0" max="59">
    </div>
    <div class="btn-row">
      <button class="btn btn-start" id="startBtn">Start</button>
      <button class="btn btn-reset" id="resetBtn">Reset</button>
    </div>
    <p class="message" id="message"></p>
  </div>
  <script src="script.js"></script>
</body>
</html>

CSS Styling

CSS
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
  min-height: 100vh; display: flex; align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  font-family: 'Segoe UI', sans-serif;
}
.timer-app { text-align: center; color: #fff; }
h1 { font-size: 2rem; font-weight: 800; margin-bottom: 8px; letter-spacing: 1px; }
.subtitle { font-size: 1rem; color: rgba(255,255,255,0.7); margin-bottom: 32px; }
.time-display { display: flex; justify-content: center; gap: 16px; margin-bottom: 32px; }
.time-box {
  background: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 16px; padding: 20px 24px; min-width: 90px;
  backdrop-filter: blur(8px);
}
.time-box .value { font-size: 2.8rem; font-weight: 800; line-height: 1; display: block; }
.time-box .label {
  font-size: 0.75rem; text-transform: uppercase; letter-spacing: 2px;
  color: rgba(255,255,255,0.7); margin-top: 6px; display: block;
}
.input-row { display: flex; justify-content: center; gap: 12px; margin-bottom: 24px; }
.input-row input {
  width: 80px; padding: 10px; font-size: 1rem; font-weight: 600;
  text-align: center; border: 2px solid rgba(255,255,255,0.3);
  border-radius: 10px; background: rgba(255,255,255,0.1);
  color: #fff; outline: none;
}
.input-row input:focus { border-color: rgba(255,255,255,0.7); }
.btn-row { display: flex; justify-content: center; gap: 12px; }
.btn {
  padding: 12px 32px; font-size: 1rem; font-weight: 700;
  border: none; border-radius: 50px; cursor: pointer;
}
.btn-start { background: #fff; color: #764ba2; }
.btn-start:hover { transform: scale(1.05); }
.btn-reset {
  background: rgba(255,255,255,0.15); color: #fff;
  border: 2px solid rgba(255,255,255,0.3);
}
.btn-reset:hover { background: rgba(255,255,255,0.25); }
.message { margin-top: 24px; font-size: 1.1rem; font-weight: 600; min-height: 1.5em; }

JavaScript Logic

JavaScript
let timer = null;
let totalSeconds = 0;

const displayMin = document.getElementById('displayMin');
const displaySec = document.getElementById('displaySec');
const inputMin   = document.getElementById('inputMin');
const inputSec   = document.getElementById('inputSec');
const startBtn   = document.getElementById('startBtn');
const resetBtn   = document.getElementById('resetBtn');
const message    = document.getElementById('message');

function updateDisplay() {
  const m = Math.floor(totalSeconds / 60);
  const s = totalSeconds % 60;
  displayMin.textContent = String(m).padStart(2, '0');
  displaySec.textContent = String(s).padStart(2, '0');
}

startBtn.addEventListener('click', function () {
  if (timer) return;                       // already running
  const m = parseInt(inputMin.value) || 0;
  const s = parseInt(inputSec.value) || 0;
  totalSeconds = m * 60 + s;

  if (totalSeconds <= 0) {
    message.textContent = 'Please enter a time!';
    return;
  }
  message.textContent = '';
  updateDisplay();

  timer = setInterval(function () {
    totalSeconds--;
    updateDisplay();
    if (totalSeconds <= 0) {
      clearInterval(timer);
      timer = null;
      message.textContent = "Time's up!";
    }
  }, 1000);
});

resetBtn.addEventListener('click', function () {
  clearInterval(timer);
  timer = null;
  totalSeconds = 0;
  updateDisplay();
  inputMin.value = '';
  inputSec.value = '';
  message.textContent = '';
});

Download Source Code

Single ready-to-run HTML file. Open it in any browser instantly!

Download Project

Single HTML file · All code included