Time for some CSS debate

That’s the best pun I could think of, pretty lame to be hon­est. My first foray into shared exper­i­mental CSS (pro­pri­et­ary Web­Kit prop­er­ties used to cre­ate a clock anim­a­tion) has fired up an inter­est­ing debate; where should the realm of cas­caded style sheets end?

This clock exper­i­ment does not advoc­ate such use of style sheets, it is instead used to demon­strate the cap­ab­il­it­ies and pos­sib­il­it­ies of WebKit’s trans­form and trans­ition prop­er­ties. It has inad­vert­ently high­lighted the con­tro­ver­sial and unex­pec­ted nature by which web developers may use them. Should this cross-pollination of beha­viour defin­i­tion become stand­ard? Is it risky? What might the side effects be?

Com­ments on the Ajaxian post began the dis­cus­sion, Malic opened the debate (this com­ment is par­tic­u­larly in ref­er­ence to ‘trans­ition’ rather than the more widely accep­ted ‘transform’):

While this [is] inter­est­ing and maybe a little bit cool, I think it is inap­pro­pri­ate for Web­kit to take CSS (even if only for itself) in this dir­ec­tion. CSS was cre­ated to define style. This seems more like a beha­vior to me and that belongs to the Javas­cript prob­lem space. Going down the the road that Web­kit is going, the ques­tion is — where do you stop? Just how much do you extend CSS to be? I think you run the risk of cre­at­ing solu­tions for prob­lems that have already been solved.

This yiel­ded some oppos­i­tion but the major­ity sup­por­ted the notion, Travis Almand cham­pi­ons the new trans­form prop­erty but strongly ques­tions its counter-part:

CSS should be a style guide, not a pro­gram­ming language.

Before high­light­ing that the road to beha­viour in CSS has already begun with the much used :hover, accom­pan­ied by :act­ive, and :focus — user action pseudo-classes, agents some­times change the ren­der­ing in response to user actions; response being the keyword.

Will Peavy com­ments that these beha­viours wreak reek of IE’s aban­doned CSS expres­sions, and edthered asks:

What hap­pens when your CSS lib­rary and your javas­cript lib­rary start try­ing to do the same thing to the same ele­ment, or dif­fer­ent things to the same element?

John Dowdell of Adobe has also weighed in with an hon­est rant that I heart­ily recom­mend read­ing, even if I’m slightly jeal­ous that I can­not artic­u­late my prose as well.

The clock example shows that people will use tech­no­lo­gies in unex­pec­ted ways. The cre­at­ors of Usenet did not intend mass advert­ising. […] Stuff­ing the genie back inside the bottle is harder than look­ing care­fully at the bottle before open­ing it.
[…]
We may not be able to per­suas­ively artic­u­late why this will even­tu­ally be con­sidered a bad archi­tec­tural decision. It’s like when vendors of email cli­ents star­ted talk­ing about how won­der­ful it would be to add hid­den graph­ics and script­ing to the emails strangers send to you. Vague warn­ings of an unsound future are at a dis­ad­vant­age to self-interested “But I wanna do it!!” evangelists.

It’s hard to per­suas­ively doc­u­ment future risks. But encum­ber­ing HTML and CSS like this is not the way to bless your own mul­ti­me­dia engine.

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.

Track outbound links using Google Analytics

“Track everything”, lest vital vis­itor trends fall through the cracks — that’s my newly endorsed web ana­lyt­ics doc­trine. As a pre­cursor to the quant­it­at­ive ‘what’ and the qual­it­at­ive ‘why’ we need that cold hard data before ana­lysis can begin; Google Ana­lyt­ics is the pop­u­lar har­vester of choice and out of the box it grabs a lot. Vis­its, Pageviews, Screen res­ol­u­tion, et al — GA seem­ingly has all your con­ven­tional data needs covered. But one sig­ni­fic­ant trend is lack­ing — how vis­it­ors leave your site, spe­cific­ally through out­bound links on a page, data that inev­it­ably leads to a what and an avenue for invest­ig­at­ing the why. For instance, “Which part­ner sites are attract­ing the highest click throughs?” or more gen­er­ally “Why do vis­it­ors leave my site?”.

GA gives the abil­ity to cre­ate your own events with a cat­egory, action, label and numer­ical value using the syntax:

_trackEvent(category, action, optional_label, optional_value)

Hence, on an out­bound link click, by call­ing this JavaS­cript method you can trig­ger a tracked event in GA. An obtrus­ive onclick attrib­ute on every out­bound link is both cum­ber­some to imple­ment and dif­fi­cult to man­age, it also goes against the best prac­tices of pro­gress­ive enhance­ment and unobtrusiveness.

The solu­tion is to attach a click event listener to each of the out­bound links on the page, and the ques­tion becomes how to do that. CSS3 comes with a couple of handy new select­ors that we can use in com­bin­a­tion with Pro­to­type or jQuery to root out the cor­rect links. The appro­pri­ate selectors:

E[foo^=“bar”] an E ele­ment whose “foo” attrib­ute value begins exactly with the string “bar“
E[foo*=“bar”] an E ele­ment whose “foo” attrib­ute value con­tains the sub­string “bar“
E:not(s) an E ele­ment that does not match simple selector s

The magic out­bound link selector then becomes one of the fol­low­ing, depend­ing on your needs:

/* Any link that does not contain yourdomain.com */
a:not(a[href*="yourdomain.com"])

/* Any link that does not start with yourdomain.com */
a:not(a[href^="yourdomain.com"])

/* Any link that does not start with yourdomain.com or www.yourdomain.com */
a:not(a[href^="yourdomain.com"]):not(a[href^="www.yourdomain.com"])

/* Any link that starts with http - e.g. any non relative links */
a[href^="http"]

/* Catch all - any link that starts with http but doesn't link to your domain */
a[href^="http"]:not(a[href*="yourdomain.com"])

With an array of all the out­bound links at hand, adding a click listener is simple. But we do need to set up the cat­egory, action and label. I have opted to cre­ate an arbit­rary “Out­bound Link” cat­egory that uses the link’s text (with HTML tags stripped out) as the action and the url as the label:

Event.observe(outboundLink, 'click', function() {
        // category, action, label
        pageTracker._trackEvent('Outbound Link', outboundLink.innerHTML.replace(/(<([^>]+)>)/ig,""), outboundLink.href);
}

The com­plete code

Using Pro­to­type ver­sion 1.6 the final code might look like this:

Update: As poin­ted out in the com­ments, hard cod­ing a domain into your code isn’t the best idea, window.location.hostname is a good altern­at­ive. This may not always work if you do not want to exclude subdomains.

var domainName = "domainname.com";
// Select all outbound links
$$('a[href^="http"]:not(a[href*="'+domainName+'"])').each(function(outboundLink) {
        // Add listener to each of the links
        Event.observe(outboundLink, 'click', function() {
        // category, action, label
        pageTracker._trackEvent('Outbound Link', outboundLink.innerHTML.replace(/(<([^>]+)>)/ig,""), outboundLink.href);
        }
});

Creating the first design

For the default FofR Online theme, the first of many, I have chosen a simple appear­ance that focuses on the beauty of fonts and typo­graphy. The header uses a sans-serif font, on OS X this will be Hel­vetica Neue, on Win­dows the CSS font stack allows the design to fall back to the more com­mon Arial, plain old Hel­vetica isn’t used because some Win­dows machines have a ter­rible low qual­ity ver­sion installed. The con­tent area is dis­tin­guished with a serif font, for the time being (no pun inten­ded — where would I be if I star­ted mak­ing typeface puns?), this is Times New Roman. I may exper­i­ment fur­ther with less com­mon serif fonts that are installed on a good major­ity of machines (e.g. with MS Office or Adobe CS4), fall­ing back to Times New Roman if necessary.

Update: I have slightly altered the content’s stack to begin with Apple’s Times font rather than Times New Roman, mainly for the super­ior glyphs that it offers, take for instance ‘fi’ in this post’s title. I’m attempt­ing to research the dif­fer­ences between Times and Times New Roman bey­ond a simple com­par­ison though inter­net sleuth­ing has not proved fruitful.

I’ve spent a short amount of time research­ing lead­ing, kern­ing, the meas­ure, et al to improve the legib­il­ity of the con­tent region (e.g. The Design Cubicle). I’ve increased the CSS line-spacing and slightly upped the word-spacing to make the con­tent area more read­able. The design’s hori­zontal dimen­sions are all defined in ems, so the page scales cor­rectly with changes in font size — always main­tain­ing an appro­pri­ate meas­ure in the region of 78 char­ac­ters, ‘a couple of alpha­bets’ — a good rule of thumb for legib­il­ity. The ver­tical align­ment in the header uses pixels to keep the desired appear­ance. The header image uses the text-indent text replace­ment tech­nique and a trans­par­ent PNG that uses Hel­vetica Neue to achieve a con­sist­ent brand­ing style across platforms.

Mark Boulton states that the lead­ing should increase pro­por­tion­ately with the meas­ure. I am temp­ted to cre­ate a small JavaS­cript pro­ject for a fluid web lay­out that dynam­ic­ally alters the CSS line-spacing of the con­tent based on the width of the win­dow and hence the meas­ure; just to see how things change. I think the first prob­lem may be decid­ing the scal­ing factor to apply to the line-spacing.

One of the biggest caveats of cre­at­ing a design that strongly relies on the beauty of fonts is the dif­fer­ence in Win­dows and Apple font ren­der­ing. Take for instance the screen cap­ture below which com­pares Win­dows XP (Left, IE7) with OSX (Right, Fire­fox 3). My pref­er­ence is towards Apple’s styl­ish approach that attempts to match print, versus Microsoft’s pixel jam­ming but easier to read prag­matic ren­der­ing. By using fonts as the pre­dom­in­ant styl­ing force on the page it is clear that in this case the Apple approach is super­ior. Joel on Soft­ware has a very nice art­icle that makes a good com­par­ison between the two.

Windows and OS X font rendering comparison

Areas still left to develop include the right hand columns, a proper grid lay­out and the footer, I have put these aside until next week.

Let’s get the ball rolling

Good even­ing, day, or morn­ing, depend­ing on the time you read this. Wel­come to my online port­fo­lio, my sand­box for design, my play­ground for web devel­op­ment, my plat­form for industry opin­ions and my busi­ness, “FofR Online”. What does FofR stand for? It’s Czech for “move it”, it’s a com­mon typo of for and it sits in that ball­park of quirky online brand­ing — remin­is­cent of Flickr or Twit­ter, espe­cially if pro­nounced ‘foffer’.

This blog has been devised as a spring board for my ideas whilst serving as a pro­fes­sional out­let for my skills, thoughts and col­lab­or­a­tions. If I were to include some buzz words in this open­ing blurb to describe the con­tent I’ll endeav­our to put here I might include; CSS3, HTML5, Inform­a­tion Archi­tec­ture, User Exper­i­ence, Unob­trus­ive JavaS­cript, Pro­to­type & jQuery lib­rar­ies, SEO, web ana­lyt­ics, OOCSS, pro­gress­ive enhance­ment, access­ib­il­ity, rapid design pro­to­typ­ing and inter­net marketing.

As an excit­ing start­ing point, rather than build my own Word­press theme from scratch I have opted to use the excel­lent Sand­box theme — ‘beau­ti­ful on the inside’. With its hugely power­ful class-generating func­tions Sand­box cre­ates clean and access­ible markup with a huge array of con­text sens­it­ive CSS select­ors, cre­at­ing an ‘excep­tion­ally extens­ible found­a­tion’.

For more inform­a­tion on the Sand­box Word­press theme I recom­mend check­ing out the offi­cial Sand­box web­site hos­ted at plaintxt or the pro­ject home on Google Code.