An analogue clock using only CSS

Hav­ing read the blurb around Safari’s CSS trans­itions I opted to famil­i­ar­ize myself with a quick pro­ject — the aim of which was to cre­ate a func­tional, CSS only, ana­logue clock.

Res­ult

Exper­i­ment: CSS Ana­logue Clock
Exper­i­ment works in Safari 4 Beta and Google Chrome. A work­ing clock that option­ally resorts to JavaS­cript to grab the cur­rent time (can be achieved by other means).

How To

Before get­ting into the nitty gritty I cre­ated four images, a clock face and three trans­par­ent PNG hands (seconds, minutes and hours), ensur­ing that each of these were the same size so that when over­layed their centres would align. The HTML and CSS to get us going is as follows:

<div id="clock">
	<div id="hour"><img src="images/hourHand.png" /></div>
	<div id="minute"><img src="images/minuteHand.png" /></div>
	<div id="second"><img src="images/secondHand.png" /></div>
</div>
#clock {
position: relative;
width: 378px;
height: 378px;
background-image: url('../images/clockFace.png');
left: 50%;
margin: 5em 0 0 -189px;
}

#clock div {
position: absolute;
}

The magic that rotates the clock’s hands comes via two Web­Kit spe­cific CSS prop­er­ties, -webkit-transition (doc­u­ment­a­tion) and -webkit-transform (doc­u­ment­a­tion). The trans­form prop­erty can alter the appear­ance of an ele­ment via a two dimen­sional trans­form­a­tion, for instance: scal­ing, rotat­ing and skew­ing a DIV ele­ment. In this case it is used to rotate the clock hands to the cor­rect angles; the CSS below puts the hour hand at 3 o’clock:

#clock img[src*='hour'] {
-webkit-transform: rotate(90deg);
}

The trans­ition prop­erty cre­ates an anim­a­tion of a spe­cified prop­erty between two val­ues when triggered, for instance fad­ing the opa­city on a DIV ele­ment from 1 to 0 — triggered using the :hover pseudo class. Trans­ition dur­a­tion and the trans­ition tim­ing func­tion (e.g. lin­ear) should also be set, amongst other optional prop­er­ties. In this example the trans­ition is from one trans­form­a­tion angle to another with dur­a­tions that match the appro­pri­ate clock hand, so the second hand takes 60 seconds to com­plete a 360 degree rota­tion. The trans­ition is triggered using the :tar­get pseudo ele­ment — if the URI con­tains the ‘clock’ frag­ment then the time piece shall start ticking.

#clock img[src*='second'] {
/* -webkit-transition: property duration timing-function */
-webkit-transition: -webkit-transform 60s linear;
}

#clock:target img[src*='second'] {
-webkit-transform: rotate(360deg);
}

The above trans­ition lasts only one rota­tion but by alter­ing the dur­a­tion length and degree of rota­tion in accord­ance the second hand can keep on going (e.g. 600 seconds and 3600 degrees rota­tion gives a bat­tery life of 10 minutes), a fairly safe assump­tion that users will not stay on the page for too long.

#clock img[src*='second'] {
-webkit-transition: -webkit-transform 600000s linear;
}

#clock:target img[src*='second'] {
-webkit-transform: rotate(3600000deg);
}

#clock img[src*='minute'] {
-webkit-transition: -webkit-transform 360000s linear;
}

#clock:target img[src*='minute'] {
-webkit-transform: rotate(36000deg);
}

Grab the cur­rent time

Although the anim­a­tion works beau­ti­fully, CSS alone is not cap­able of obtain­ing the cur­rent time. To start the clock at the cor­rect time a dynamic trans­form­a­tion needs to be applied to the clock hand con­tain­ers, this is easi­est done with inline styles and can be set in any num­ber of ways by the backend when the page loads, thereby erad­ic­at­ing any need for JavaScript.

Altern­at­ively, if you’ve no objec­tions to using JavaS­cript, I’ve cre­ated a small startClock() func­tion to do the job (albeit using Pro­to­type 1.6.0.3 for my own con­veni­ence):

function startClock() {
	var angle = 360/60;
	var date = new Date();
	var hour = date.getHours();
	if(hour > 12) {
		hour = hour - 12;
	}
	var minute = date.getMinutes();
	var second = date.getSeconds();
	var hourAngle = (360/12)*hour + (360/(12*60))*minute;
	$('minute').setStyle('-webkit-transform: rotate('+angle*minute+'deg)');
	$('second').setStyle('-webkit-transform: rotate('+angle*second+'deg)');
	$('hour').setStyle('-webkit-transform: rotate('+hourAngle+'deg)');
}

A word of warn­ing — apply­ing the inline style dir­ectly to the image will over­ride the trans­ition effects defined in the CSS file.

14 Comments

  1. Posted March 26, 2009 at 4:42 am | Permalink

    In Google Chro­mium (for linux) works fine!

  2. John Giotta
    Posted March 26, 2009 at 4:42 am | Permalink

    You can add Google Chrome to your com­pat­ible browsers

  3. Posted March 26, 2009 at 5:13 am | Permalink

    Works in Safari 3.2.1 on a Mac, cool !

  4. david
    Posted March 26, 2009 at 5:40 am | Permalink

    FF 3.1 also has css trans­forms https://developer.mozilla.org/web-tech/2008/09/12/css-transforms/

  5. Posted March 26, 2009 at 5:50 am | Permalink

    This work also on Safari 3.1.2 (525.21)

  6. Scavenger
    Posted March 26, 2009 at 5:58 am | Permalink

    Cool!

    Page zoom­ing doesn’t work on Mac (Safari 3.2.1), though.

  7. Posted March 26, 2009 at 6:29 am | Permalink

    Sweet! Works in Safari 4 BETA. I’m going to try this out myself!

  8. Posted March 26, 2009 at 7:52 am | Permalink

    Wow, nice clock. I made a sim­ilar one last year — using the afore­men­tioned CSS trans­forms with a touch of JavaScript — see:

    http://www.cuppadev.co.uk/oldbrew/an-analogue-clock-using-safari-transforms/

    :)

  9. Posted March 26, 2009 at 9:26 pm | Permalink

    Very cool! Gotta be care­ful with this stuff, tho — when I ran it in Chrome on WinXP on a Dell Inspiron 6000, it chewed up 55% of CPU.

  10. Posted March 31, 2009 at 12:25 am | Permalink

    You could try to integ­rate rotat­ing for older browsers by using: http://wilq32.googlepages.com/wilq32.rollimage222

  11. Posted March 31, 2009 at 1:36 pm | Permalink

    I used a sim­ilar tech­nique here:

    http://ryancannon.com/mtg/hi/

    to keep time, but mine is inten­ded for longer peri­ods. One thing to note: you must always incre­ment the trans­form up. If, for example, you set the hands at noon to 0deg when they were at 359deg a minute before hand, your arms will rotate backwards.

    A bit of a pain, and I haven’t found a work around, other than incre­ment­ing to infinity.

  12. Posted April 1, 2009 at 6:56 am | Permalink

    You get an inter­est­ing effect when you try and select the image in chrome, crazy shapes!

  13. Posted February 5, 2010 at 3:34 am | Permalink

    This is amaz­ing! Had no idea you could do any­thing like this in CSS, will have to give it a go!

  14. Posted February 6, 2010 at 2:11 pm | Permalink

    looks really great.

10 Trackbacks

  1. By Ajaxian » Creating a clock in CSS on March 26, 2009 at 4:11 am

    […] appro­pri­ate that Paul Hayes of Lon­don has cre­ated an inter­est­ing exper­i­ment that shows how you can cre­ate an ana­logue clock using just CSS and JavaS­cript is only used to get the current […]

  2. By Guide to creat an analogue clock using CSS on March 27, 2009 at 2:55 am

    […] Full Article […]

  3. By Time for some CSS debate - FofR Online on March 27, 2009 at 6:08 pm

    […] FofR Online A pro­fes­sional slice of newly baked webi­ness from Paul Hayes Skip to con­tent « An ana­logue clock using only CSS […]

  4. By Linkdump #12 | CTAPbIu_MABP's BLOG on March 28, 2009 at 11:05 am

    […] An ana­logue clock using only CSS Создание аналоговых часов на CSS […]

  5. […] Hayes baut eine ana­loge Uhr aus­schließ­lich mit […]

  6. By 網站製作學習誌 » [Web] 連結分享 on April 7, 2009 at 6:56 pm

    […] An ana­logue clock using only CSS […]

  7. […] Аналоговые часы с помощью transition […]

  8. […] have an iPhone, Black­berry or another cap­able device.]Visual Effects and Lay­out Tech­niques With CSS3CSS3 Ana­logue ClockAna­logue clock cre­ated using web­kit trans­ition and trans­form CSS. JavaS­cript is only used to pull in […]

  9. […] CSS3 Ana­logue ClockAna­logue clock cre­ated using web­kit trans­ition and trans­form CSS. JavaS­cript is only used to pull in the cur­rent time. […]

  10. […] CSS3 Ana­logue ClockAna­logue clock cre­ated using web­kit trans­ition and trans­form CSS. JavaS­cript is only used to pull in the cur­rent time. […]

Post a Comment

Your email is never shared. Required fields are marked *

*
*