DEV Community

loading...
Cover image for Simple Analog Clock Using Html, CSS & Javascript

Simple Analog Clock Using Html, CSS & Javascript

Foolish Developer
Updated on ・6 min read

In this article I am going to show you how to make an analog clock using HTML CSS and JavaScript code. I have already designed many types of analog clocks. This watch is made in the shape of a dark neumorphism design. Like a typical analog kite there are three hands to indicate hours minutes and seconds. Here I have used symbols instead of numbers from 1 to 12.

You can watch the live demo to see how this analog clock works. Since I made it with the help of neumorphism design, I have used the same color in the background of the clock and in the background of the page. First of all I made a box with 30 rem width and 30 rem height on a web page. Border-radius 50% has been used to round this box. I have used box-shadow here to implement neumorphism design.

It's very simple and in general I made. Below I show the complete step-by-step how I made this Javascript analog clock. First of all you create an HTML and CSS file. Be sure to attach your CSS file to the html file.

Step 1: Create the basic design of the clock

I have made the background of this analog clock using the following HTML and CSS code. I created the structure of this clock using the code <div class = "clock"></div>. First of all I gave the background color of the page (background: # 282828;) in the CSS code.

<div class="clock">

</div>

Enter fullscreen mode Exit fullscreen mode

 html {
  background: #282828;
  text-align: center;
  font-size: 10px;
}

body {
  margin: 0;
  font-size: 2rem;
  display: flex;
  flex: 1;
  min-height: 100vh;
  align-items: center;
}

.clock {
  width: 30rem;
  height: 30rem;
  position: relative;
  padding: 2rem;
  border: 7px solid #282828;
  box-shadow: -4px -4px 10px rgba(67,67,67,0.5),
                inset 4px 4px 10px rgba(0,0,0,0.5),
                inset -4px -4px 10px rgba(67,67,67,0.5),
                4px 4px 10px rgba(0,0,0,0.3);
  border-radius: 50%;
  margin: 50px auto;

}

Enter fullscreen mode Exit fullscreen mode

Create the basic design of the clock

Step 2: Draw two colorful lines in the clock

I used the following HTML and CSS codes to make the symbol that I used to indicate the time in this watch. First of all I made two lines using the following codes. I put those two lines at a 90 degree angle to each other. I used background: # 282828 to make the lines brighter.

<div class="outer-clock-face">

</div>
Enter fullscreen mode Exit fullscreen mode
.outer-clock-face {
  position: relative;
  background: #282828;
  overflow: hidden;
  width: 100%;
  height: 100%;
  border-radius: 100%;
}

.outer-clock-face::after {
  -webkit-transform: rotate(90deg);
  -moz-transform: rotate(90deg);
  transform: rotate(90deg)
}

.outer-clock-face::after,
.outer-clock-face::before,
.outer-clock-face .marking{
  content: '';
  position: absolute;
  width: 5px;
  height: 100%;
  background: #1df52f;
  z-index: 0;
  left: 49%;
}
Enter fullscreen mode Exit fullscreen mode

Draw two colorful lines in the clock

Step 3: Make four more lines

I have made four more lines in this clock using the following HTML and CSS code. Using CSS code, I have angled those lines as needed. I have used white color, you can use any other color.

<div class="marking marking-one"></div>
<div class="marking marking-two"></div>
<div class="marking marking-three"></div>
<div class="marking marking-four"></div>
Enter fullscreen mode Exit fullscreen mode
.outer-clock-face .marking {
  background: #bdbdcb;
  width: 3px;
}

.outer-clock-face .marking.marking-one {
  -webkit-transform: rotate(30deg);
  -moz-transform: rotate(30deg);
  transform: rotate(30deg)
}

.outer-clock-face .marking.marking-two {
  -webkit-transform: rotate(60deg);
  -moz-transform: rotate(60deg);
  transform: rotate(60deg)
}

.outer-clock-face .marking.marking-three {
  -webkit-transform: rotate(120deg);
  -moz-transform: rotate(120deg);
  transform: rotate(120deg)
}

.outer-clock-face .marking.marking-four {
  -webkit-transform: rotate(150deg);
  -moz-transform: rotate(150deg);
  transform: rotate(150deg)
}
Enter fullscreen mode Exit fullscreen mode

Make four more lines

Step 4: Draw a circle in the middle of the analog clock

I made a circle in the middle of this clock. This circle is at the junction of pre-drawn lines. The resulting lines have become symbols.

          <div class="inner-clock-face">

          </div>
Enter fullscreen mode Exit fullscreen mode
.inner-clock-face {
  position: absolute;
  top: 10%;
  left: 10%;
  width: 80%;
  height: 80%;
  background: #282828;
  -webkit-border-radius: 100%;
  -moz-border-radius: 100%;
  border-radius: 100%;
  z-index: 1;
}

.inner-clock-face::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 16px;
  border-radius: 18px;
  margin-left: -9px;
  margin-top: -6px;
  background: #4d4b63;
  z-index: 11;
}
Enter fullscreen mode Exit fullscreen mode

Draw a circle in the middle of the analog clock

Step 5: Make three hands in the clock

Like a normal analog clock, I have used three hands to indicate hours, minutes and seconds. I created and designed those hands using the HTML and CSS code below.

    <div class="hand hour-hand"></div>
    <div class="hand min-hand"></div>
    <div class="hand second-hand"></div>
Enter fullscreen mode Exit fullscreen mode
.hand {
  width: 50%;
  right: 50%;
  height: 6px;
  background: #61afff;
  position: absolute;
  top: 50%;
  border-radius: 6px;
  transform-origin: 100%;
  transform: rotate(90deg);
  transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}

.hand.hour-hand {
  width: 30%;
  z-index: 3;
}

.hand.min-hand {
  height: 3px;
  z-index: 10;
  width: 40%;
}

.hand.second-hand {
  background: #ee791a;
  width: 45%;
  height: 2px;
}
Enter fullscreen mode Exit fullscreen mode

Make three hands in the clock

Step 6: Activate the analog clock with JavaScript code

We have done the work of designing this analog watch. Now we will implement this watch with the help of JavaScript. In this case I did not use any plugin or JavaScript library. I have only executed the hands in this watch using JavaScript. Even if you are a beginner, you can understand this design. Below each code I have given a complete explanation of why I used that code.

We are going to grab the reference for the following using querySelector():
➤ .second-hand
➤.min-hand
➤.hour-hand

const secondHand = document.querySelector('.second-hand');
const minsHand = document.querySelector('.min-hand');
const hourHand = document.querySelector('.hour-hand');
Enter fullscreen mode Exit fullscreen mode
 function setDate() {
  const now = new Date();
Enter fullscreen mode Exit fullscreen mode

new Date() creates an instance of the Date class from which we can get all kinds of things like current date, hours, minutes, seconds, etc.

  const seconds = now.getSeconds();
  const secondsDegrees = ((seconds / 60) * 360) + 90;
  secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
Enter fullscreen mode Exit fullscreen mode

➤ I have stored in 'secondsDegrees' how the second hand will rotate.
➤ Then I use rotate(${secondsDegrees}deg) to rotate the hand.
➤ I divided by 60 because 1 minute is equal to 60 seconds.
➤ I multiplied by 360 because a circle is formed by 360 degrees.

  const mins = now.getMinutes();
  const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90;
  minsHand.style.transform = `rotate(${minsDegrees}deg)`;
Enter fullscreen mode Exit fullscreen mode

➤ I have stored in 'minsDegrees' how to turn the hand of the minute.
➤ Then userotate(${minsDegrees}deg) to rotate the hand.
➤ I divided by 60 because 1 hour is equal to 60 minutes.
➤ Added second hand position with minutes. Because the minute's hand is in the right place depending on the second.

  const hour = now.getHours();
  const hourDegrees = ((hour / 12) * 360) + ((mins/60)*30) + 90;
  hourHand.style.transform = `rotate(${hourDegrees}deg)`;
}

Enter fullscreen mode Exit fullscreen mode
setInterval(setDate, 1000);

setDate();
Enter fullscreen mode Exit fullscreen mode

➤ We need to call this rotate() function every 1 second (1000 milliseconds).

Activate the analog clock with JavaScript code

Final Javascript code

const secondHand = document.querySelector('.second-hand');
const minsHand = document.querySelector('.min-hand');
const hourHand = document.querySelector('.hour-hand');

 function setDate() {
  const now = new Date();

  const seconds = now.getSeconds();
  const secondsDegrees = ((seconds / 60) * 360) + 90;
  secondHand.style.transform = `rotate(${secondsDegrees}deg)`;

  const mins = now.getMinutes();
  const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90;
  minsHand.style.transform = `rotate(${minsDegrees}deg)`;

  const hour = now.getHours();
  const hourDegrees = ((hour / 12) * 360) + ((mins/60)*30) + 90;
  hourHand.style.transform = `rotate(${hourDegrees}deg)`;
}

setInterval(setDate, 1000);

setDate();
Enter fullscreen mode Exit fullscreen mode

Hopefully from this tutorial you have learned how to make this analog clock. If you have any questions you can ask me by commenting. Of course you can let me know if I did something wrong.

You can visit my blog for more tutorials like this.
https://www.foolishdeveloper.com/

Discussion (53)

Collapse
mayankkalbhor profile image
Mayank Kalbhor

Beautiful

Collapse
code_mystery profile image
Foolish Developer Author

Thank you

Collapse
madza profile image
Madza

Very clean, both the ui and code 👍😉

Collapse
code_mystery profile image
Foolish Developer Author

Thank you for like it

Collapse
efpage profile image
Eckehard • Edited

I rebuilt your beautiful clock in DML, just to see how compact code would be. Here is the complete website:

<!DOCTYPE html>
<html lang="de">

<head>
  <meta charset="utf-8">
  <title>title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://efpage.de/DML/DML_homepage/lib/DML-min.js"></script>
  <style>
  </style>
</head>

<body>
  <script>  "use strict";
    const cx = 100, cy = 100;  // Radius
    const _clockstyle = "width: " + (2 * cx) + "px;  height: " + (2 * cy) + "px;"
      + "border: 7px solid #282828; background: #585858;"
      + "border-radius: 50%; margin: 50px;"
      + "box-shadow: -4px -4px 10px rgba(67,67,67,0.5), inset 4px 4px 10px rgba(0,0,0,0.5),"
      + "inset -4px -4px 10px rgba(67,67,67,0.5), 4px 4px 10px rgba(0,0,0,0.3);"

    sidiv("", _clockstyle)
    let c = canvas2D({ width: px(2 * cx), height: px(2 * cy) })
    c.ctx.lineCap = "round"
    unselectBase()

    // Paint anything radial
    function tick(color, width, angle, length, innerlength = 0) {
      function ls(length) { return length * Math.sin(angle / 180.0 * Math.PI) }
      function lc(length) { return -length * Math.cos(angle / 180.0 * Math.PI) }
      c.setLineType(width, color)
      c.line(cx + ls(innerlength), cy + lc(innerlength), cx + ls(length), cy + lc(length))
    }

    // Draw clock
    function drawClock() {
      c.clear()
      // Draw ticks
      for (let i = 0; i < 360; i += 30)
        if ((i % 90) == 0) tick("#1df52f", 5, i, 88, 70)
        else tick("#bdbdcb", 3, i, 88, 75)

      // draw hands
      let t = new Date();  // get time
      tick("#61afff", 5, t.getHours() * 30, 50)  // hour
      tick("#71afff", 2, t.getMinutes() * 6, 70)  // min
      tick("#ee791a", 2, t.getSeconds() * 6, 80)  // s

      // drwa center
      c.setFillStyle("#4d4b63")
      c.circle(cx, cy, 10, { fill: true })
    }
    drawClock()
    setInterval(drawClock, 1000)
  </script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

That´s all. For practical use it would be better to put the code into a separate class for convenience, which is pretty simple in DML.

Post edit: here it is: a working clock class, can be used as Webcomponent too...

Collapse
esger profile image
Esger Jellema • Edited

Your clock is very nice, though it can be done without the JavaScript too :) (not mine)
codepen.io/nobitagit/pen/birjo

Collapse
emekaorji profile image
EmekaOrji

Yh! But that would not get the current time

Collapse
esger profile image
Esger Jellema

This one can, after setting it.. css-tricks.com/of-course-we-can-ma...

Collapse
abskr82 profile image
abskr82

Good explanation.

Collapse
code_mystery profile image
Foolish Developer Author

Thank you

Collapse
jfftck profile image
jfftck

I have some suggestions on how to improve this.

  1. Create a function that handles the redraw interval using window.requestAnimationFrame() and window.setTimeout() instead of window.setInterval() as it should cut down on rendering cycles.
  2. Look at using HTML canvas as it will use much less memory since only 1 HTML element is created.

These are the ways that I would expand on this code to improve, not only performance, but my skill set.

Collapse
maixuanhan profile image
Han Mai

I doubt that.

  1. How will requestAnimationFrame() help in this case? Interval resolution is 1 second.
  2. Are there any measurements for this or you’ve just guessed?
Collapse
emekaorji profile image
EmekaOrji

This is amazing!!

👍👍

Collapse
code_mystery profile image
Foolish Developer Author

Thank you 😀😀😍

Collapse
emekaorji profile image
EmekaOrji • Edited

😍Amazingly, I found myself doing the same thing today. I built an Analog Clock! And I coded the whole thing on my android device.👌👌. Thanks man

Collapse
abhaycs profile image
Abhay Sharma

Crystal clear!

Collapse
hosseinjafari9574 profile image
Hossein_jafari

lovely :)

Collapse
neill45675728 profile image
Neill

Truly stunning. Thank you.

Collapse
code_mystery profile image
Foolish Developer Author

😍

Collapse
luzhenqian profile image
luzhenqian

Great! thank you for writing such a wonderful tutorial. Can I translate it and repost it to the developer community website in China?

Collapse
code_mystery profile image
Foolish Developer Author

Of course

Collapse
ashutoshmishra4 profile image
Ashutosh Mishra

Your UI is very amazing and beautiful

Collapse
code_mystery profile image
Foolish Developer Author

Thank you

Collapse
nitesh603 profile image
nitesh603

Thank you!

Collapse
code_mystery profile image
Foolish Developer Author

Welcome 😍

Collapse
aakashsingh1210 profile image
aakashsingh1210

Wow

Collapse
code_mystery profile image
Foolish Developer Author • Edited

😍

Collapse
curioushokie profile image
CuriousHokie

Very nice clock solution. Different from the clock solution on W3Schools: w3schools.com/graphics/canvas_cloc...

Collapse
forkbikash profile image
Bikash Mishra

Good one!

Collapse
code_mystery profile image
Foolish Developer Author

Thank you BIKASH MISHRA

Collapse
jreegene profile image
Jeremiah

Nice one. Thanks for sharing

Collapse
code_mystery profile image
Foolish Developer Author

Welcome 😍

Collapse
exoticallisticsm profile image
Salieu Sesay

Excellent coding flow.

I wished all code supports are written as elegant as this.

Collapse
artydev profile image
artydev

Great :-)

Collapse
madrafj profile image
Ahmad Rafsanjani

Beautiful..
Btw 'SecondHand' distracted me😁

Collapse
code_mystery profile image
Foolish Developer Author

😂😂😅

Collapse
cwilliams2024 profile image
Calvin Williams

Wow

Collapse
yogesh27 profile image
yogesh-kumar-27

learn a lot form this as a beginner

Collapse
code_mystery profile image
Foolish Developer Author

Your comments have encouraged me to write more articles of this kind. Thank you 😍

Collapse
eliseogarcia1024 profile image
EliseoGarcia1024

What time is it
Nice.

Collapse
code_mystery profile image
Foolish Developer Author

Thank you 😍

Collapse
ayabouchiha profile image
Aya Bouchiha

Amazing

Collapse
code_mystery profile image
Foolish Developer Author

Thank you

Collapse
goesttheinfor profile image
Goest The Infor

Dope 👌

Collapse
code_mystery profile image
Foolish Developer Author

😍

Collapse
sujoywebdev profile image
Sujoy Dutta

Thankyou, works like a charm. Smart idea and the neo look is awesome.

Collapse
code_mystery profile image
Foolish Developer Author

Welcome 😍

Collapse
jona42ui profile image
JonathanThembo

Thanks foolishdev., tho;
My clock is not starting, I have no clie why

Collapse
piyush181 profile image
Piyush Raj

I followed along, but it gives me this error: javascript.js:10 Uncaught TypeError: Cannot read property 'style' of null
at setDate (javascript.js:10)
at javascript.js:23

Some comments have been hidden by the post's author - find out more