CSS3 Analogue Clock without using images

By | January 30, 2012

Ok today I’m creating an analogue clock with CSS3, Javascript and no images at all. I’ve seen a few stuff about creating clocks with CSS3 but all the ones I’ve seen use a background image for the clock face. So I thought I would create one just from CSS. I have to give credit where it is due though, the whole idea for this came from my friend Dave Seipp. He has a free colouring pages site where you can download his original artwork for your children to colour in. He had a great idea of putting some clock faces on there for people to help their children to learn how to tell the time. I took it one step further and said why don’t we create an online version for them to do, so this is the first part of that.

View Demo

Anyway enough of all that lets get started. So first we’re going to draw a few circles. 3 to begin with so lets look at the first one.

.clock {
display: block;
width: 405px;
height: 405px;
border:3px solid #3F1B05;
background: -moz-linear-gradient(top,  #8c4f39 0%, #541f06 51%, #8c4f39 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#8c4f39), color-stop(51%,#541f06), color-stop(100%,#8c4f39)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top,  #8c4f39 0%,#541f06 51%,#8c4f39 100%); /* Chrome10+,Safari5.1+ */
-moz-border-radius: 223px;
-webkit-border-radius: 223px;
border-radius: 223px;
padding: 20px;
position:relative;
}

So here I’m creating a div with such a huge border radius that it renders as circle then with the help of Colorzilla Gradient Editor I’ve created a simple gradient going from light to dark to light brown. I played around with the width and height, padding and border-radius values until I got something that I was happy with. You could probably do it more scientifically than me but that’s not the way I roll.
So that gave me one circle with a gradient now I needed another slightly smaller, slightly darker gradient to fit inside the first one.

.clockhighlight1 {
display: block;
width: 363px;
height: 363px;
background: #541f06; /* Old browsers */
background: -moz-linear-gradient(top,  #541f06 0%, #6b2c08 50%, #541f06 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#541f06), color-stop(50%,#6b2c08), color-stop(100%,#541f06)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top,  #541f06 0%,#6b2c08 50%,#541f06 100%); /* Chrome10+,Safari5.1+ */
background: linear-gradient(top,  #541f06 0%,#6b2c08 50%,#541f06 100%); /* W3C */
-webkit-border-radius: 200px;
-moz-border-radius: 200px;
border-radius: 200px;
border:6px solid #8c4f39;
padding: 16px;
}

So as you can see here I created it slightly smaller and darker then set the position to absolute and placed this circle in the middle of the previous one and also added a border.

Next the clock face. Same idea just different colour obviously. You can play with the gradients and colours yourselves ( I messed around for ages until I was happy with the results).

.clockface {
display: block;
width: 340px;
height: 340px;
background: #ffffff; /* Old browsers */
background: -moz-linear-gradient(top, #ffffff 0%, #efefef 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#efefef)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #ffffff 0%,#efefef 100%); /* Chrome10+,Safari5.1+ */
background: linear-gradient(top, #ffffff 0%,#efefef 100%); /* W3C */
-webkit-border-radius: 180px;
-moz-border-radius: 180px;
border-radius: 180px;
border:10px solid #8e8e8e;
}

Now for the minute markers. So we have to place the first marker at 12 o clock then rotate a little and place at the next minute and so on all the way round the clock. Before we get into the maths of this lets look at the most crucial part of this…. How to rotate the elements around the centre of the clock. Luckily there is a simple CSS3 property called translate-origin the only thing with this property is that it needs the browser specific prefix to work. Another tricky part is the rotation point, which is relative the element you are rotating so I placed the elements then took the file to the browser and used measureit plugin to see how far it was from the top of the element to the centre of the clock. Now for a bit of Maths (not my strong point) to work out how far to rotate each minute marker. So there’s 360 degrees in a circle and 60 minutes in the hour, so 360 / 60 = 6. So every minute marker has to be rotated 6 degrees and every 5 minutes or hour marker is 30 degrees (5 x 6).

.minutes {
position: absolute;
width: 3px;
height: 15px;
top: 53px;
left: 220px;
background: #8e8e8e;
-webkit-transform-origin: 50% 170px;
-moz-transform-origin: 50% 170px;
}

.fiveminutes {
position: absolute;
width: 3px;
height: 25px;
top: 53px;
left: 220px;
background: #000;
-webkit-transform-origin: 50% 170px;
-moz-transform-origin: 50% 170px;
}

As you can see I’ve created a two classes .mins and .fiveMins and done all the basic styling for the elements then I created unique ID’s for every minute marker (yes 60) and put the correct rotation on the element. So for the first and second minute markers are as follows:

#one {
-webkit-transform: rotate(6deg);
-moz-transform: rotate(6deg);
}

#two {
-webkit-transform: rotate(12deg);
-moz-transform: rotate(12deg);
}

Telling the time.

So now we just need the hands on the clock and we’ve cracked it. So first the hour hand

#hourhand {
position: absolute;
width: 8px;
height: 130px;
top: 120px;
left: 218px;
-webkit-border-radius: 7px;
-moz-border-radius: 5px;
border-radius: 7px;
background: black;
-webkit-transform-origin: 50% 100px;
-moz-transform-origin: 50% 100px;
-webkit-transform-origin-x: 50%;
-webkit-transform-origin-y: 100px;
}

So as you can see I have set the position absolutely set it to have curved edges and the most important part I have set the transform origin to the centre of the clock again using the same method as before. I do the same for the minute hand and the second hand and then finally place a small circle in the centre of the clock above all the other divs.

#minhand {
position: absolute;
width: 8px;
height: 160px;
top: 90px;
left: 218px;
-webkit-border-radius: 7px;
-moz-border-radius: 5px;
border-radius: 7px;
background: black;
-webkit-transform-origin: 50% 131px;
-moz-transform-origin: 50% 131px;
-webkit-transform-origin-x: 50%;
-webkit-transform-origin-y: 131px;
}

#sechand {
position: absolute;
width: 4px;
height: 160px;
top: 90px;
left: 220px;
-webkit-border-radius: 7px;
-moz-border-radius: 5px;
border-radius: 7px;
background: red;
-webkit-transform-origin: 50% 131px;
-moz-transform-origin: 50% 131px;
-webkit-transform-origin-x: 50%;
-webkit-transform-origin-y: 131px;
}

#centerPoint {
width: 24px;
height: 24px;
-moz-border-radius: 12px;
-webkit-border-radius: 12px;
border-radius: 12px;
background-color: black;
position: absolute;
left: 210px;
top: 208px;
}

I’m not going to go into how the javascript works to update the time on the clock. That would be another tutorial but all the code is there and there are other tutorials on the web to help if you get stuck. In pseudo code though it is this.

Every second
Get the clients date object.
Find the hour
Find the minutes
Find the seconds
Work out whether the hour is after 12 noon
If so minus 12 off the hours
Find out the degrees to rotate the hands by.
Update the CSS3 transform property for each hand.

So finally the thing that ended up causing me the most problems.
The shadow under the clock.
I wanted to create a simple ellipse gradient underneath the clock. Easy I hear you cry. You would think so but in Chrome on the mac the ellipse gradient doesn’t work. So apologies to everyone using chrome on the mac the clock doesn’t look as good as I would have liked.

If anyone knows how to get round this please put in the comments below.
View Demo

7 thoughts on “CSS3 Analogue Clock without using images

  1. Pingback: Creating an Analog Clock with only HTML and CSS3 | Techplusone

  2. Pingback: Responsive Analog Clock with CSS3 and JavaScript | front-end fu

  3. Johnc525

    In fact when someone doesnt understand then its up to other visitors that they will help, so here it takes place. ekdgebddkdec

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *