HTML countdown timer

A countdown is a target time, an interval and a format function. The part that goes wrong is the target: write it with a time zone, or every viewer sees a different number.

An HTML countdown timer is three parts: a target time, an interval that recalculates the remaining milliseconds, and a function that formats them into days, hours, minutes and seconds.

All of it runs in the browser. There is no server component, which is why a countdown is one of the few genuinely self-contained pages you can write.

A countdown page showing days, hours, minutes and seconds in four blocks.
A countdown page showing days, hours, minutes and seconds in four blocks.

A working HTML countdown timer

Short enough to read in one pass.

<div id="cd" style="font-family:system-ui,sans-serif;font-size:32px;"></div>
<script>
  var target = new Date('2026-12-01T09:00:00Z').getTime();
  var el = document.getElementById('cd');
  var tick = setInterval(function () {
    var left = target - Date.now();
    if (left <= 0) {
      clearInterval(tick);
      el.textContent = 'Now open';
      return;
    }
    var s = Math.floor(left / 1000);
    var d = Math.floor(s / 86400);
    var h = Math.floor((s % 86400) / 3600);
    var m = Math.floor((s % 3600) / 60);
    el.textContent = d + 'd ' + h + 'h ' + m + 'm ' + (s % 60) + 's';
  }, 1000);
</script>

Two details are load bearing. The Z on the target string, covered next. And clearInterval at zero, without which the page keeps running a timer that counts upward into negative numbers.

The time zone mistake

This is the failure that reaches production most often, because it is invisible to whoever wrote the page.

A string written as 2026-12-01T09:00:00 has no zone, so browsers read it against the viewer's local clock. You see the right number. A colleague eight hours away sees a number eight hours out, and both of you think the page is fine.

Target string What it means Safe to ship
2026-12-01T09:00:00Z 09:00 UTC, same moment everywhere Yes
2026-12-01T09:00:00+09:00 09:00 in a +9 zone, same moment everywhere Yes
2026-12-01T09:00:00 09:00 on the viewer's own clock No
December 1, 2026 Parsed inconsistently across browsers No

Write the offset every time, and state the zone on the page in words as well, so the reader knows which 09:00 is meant.

Formatting that does not jump

A timer that changes width every second is distracting. Two fixes, both small.

Pad each unit to two digits, so 9 becomes 09. And if the layout still shifts, set the number blocks in a monospace font or give each a fixed width.

For units, decide whether to hide leading zero days. A countdown reading 0d 0h 4m 12s is noisier than 4m 12s.

Four boxed units side by side, each with a number and a label underneath.
Four boxed units side by side, each with a number and a label underneath.

Say what the deadline is, in words

A ticking number is a countdown, not an announcement. On its own it tells the reader how long is left without telling them what the actual moment is.

Write the date, time and zone next to the timer. Readers planning around it need the fixed point, and anyone whose script failed to run still gets the information.

It also gives you a fallback. If the countdown element is empty because of a typo in an element id, the page still communicates the deadline.

The end state

Deciding what happens at zero is part of building the timer, not an afterthought.

  • A launch. Replace the timer with the link that is now live.
  • An event. Replace it with the joining details or the room.
  • An offer. Replace it with the message that applies after the deadline, not an expired timer.
  • A recurring deadline. Advance the target rather than stopping.

Leaving a stopped timer at 0d 0h 0m 0s reads as a broken page.

What a browser countdown cannot do

Be clear about the limits before you attach anything important to it.

The arithmetic uses the device clock. A viewer whose clock is wrong sees a wrong number, and a viewer who changes their clock changes what the page says.

That is fine for a launch page. It is unacceptable for anything you intend to enforce, such as closing a form at a deadline. Enforcement has to happen wherever the submission is received, not in the browser that shows the count.

Mail is a separate case entirely. Scripts do not run in mail clients, so a script based timer shows nothing. HTML countdown timer for email covers the served image approach used there.

Putting the timer where people can see it

A countdown that lives as a file on your laptop is not doing its job. It needs an address.

Paste the HTML into a NOS document. It renders as written, script included, so the timer runs for whoever opens the page. Create the share link with Share, then Share link, then Create link.

Creating the share link for the countdown document. Unlisted by default.
Creating the share link for the countdown document. Unlisted by default.

Leave it unlisted for an internal deadline. Tick Public on the web for a launch page you want indexed.

Editing later does not move the address. When the date slips, change the target string in the document and the link you already sent points at the new date.

Sending the file instead is the hard path

Emailing the .html file has the usual attachment problems, and one extra that is specific to countdowns.

A file is a frozen copy. If the date changes, every copy you sent is now wrong, and you have no way to correct the ones already downloaded. With a link there is one page, and it is always current.

Reusing the timer inside other pages

Once the countdown works, it usually wants to sit inside something else: an event invite, a launch page, a status page.

Two ways to do that. Paste the script directly into the larger page, which is the shortest route when you control the whole file.

Or keep the timer as its own page and place it in an iframe. That is the route when the host page is a tool you cannot add scripts to. HTML countdown timer embed widget covers the embed case.

The second option also survives a change of date better. One page is the source, and every page that frames it updates at once.

For the surrounding page itself, HTML for event invites and invitation to link cover the layout and the sharing route.

Questions people ask

How do I write an HTML countdown timer?

Set a target time as a Date, run a function on an interval that subtracts the current time from it, and write the remaining days, hours, minutes and seconds into the page. Clear the interval and show a finished message when the difference reaches zero.

Why does my countdown show a different time for other people?

Because the target date was written without a time zone. A string like 2026-12-01T09:00:00 is read against the viewer's local clock, so a reader several hours away counts to a different moment. Add the offset or a trailing Z for UTC.

Does a countdown timer need a server?

No. The arithmetic runs in the browser against the device clock. That also means a viewer with a wrong clock sees a wrong number, which is acceptable for launches and events and unacceptable for anything being enforced.

How do I share a countdown page with other people?

Paste the HTML into a NOS document and create a share link. The page renders as written, scripts included, so the timer runs for whoever opens the link. Editing the target date later does not change the address.

Keep reading