Please Support - Ride for the child

Everyone seems to be banging on about CSS and selectors performance recently.

I was recently ask asked why an ID is faster than a class. My answer was that it “only reads the DOM until it finds that ID and then it’s stops because it’s unique”. After thinking about this I realised that’s not correct as if I gave two elements the same ID with some styles they will both be styled accordingly regardless of which appears first in the markup.

So I decided to delve a little deeper, find out the difference between ID’s and classes in different aspects of code and hopefully learn something in the process.

Specificity Values

Here’s the order of selections with the most efficient/highest value first as discussed in this book.

1- ID – #footer
2- Class – .media
3- Type – <div>
4 -Adjacent sibling = h1 + p
5- Child – li > ul
6- Descendant – li a
7- Universal – *
8- Attribute – [type=”input”]
9- Pseudo-classes – p:hover

So the ID is king and anything below it has a lower specificity value. I must admit I have never really had an issue with specificity, my code is pretty neat and I’ve been taught in environments that encourage speed and performance. However I’m still eager to learn more about the values of these selectors etc.

I guess the easiest way is to look at what selectors beat what. I like smashing mag’s specificity measurements best.

“Start at 0, add 1000 for style attribute, add 100 for each ID, add 10 for each attribute, class or pseudo-class, add 1 for each element name or pseudo-element”

So…

body #content .data img:hover

the specificity value would be 122 (0,1,2,2 or 0122)

#content == 100
.data == 10
:hover == 10
body == 1
img == 1

Here are some more examples

/*the specificity value would be 10*/
.class

/*the specificity value would be 2*/
p a 

/*the specificity value would be 112*/
body #container .media p

I found lots of interesting facts from Harry’s post. He actually wrote this in 2011 whilst I was still at university so I feel quite embarrassed I’m only just learning it now, but better late than never eh?!

Specificity

It takes an amazing 256 classes to overwrite one ID.  I think that ID’s ‘may’ be fine for styling unique parts of a page, but it doesn’t sound very future proof to me. Lets look at some code.

/*HTML*/
<footer id="footer">
<ul><li><a>Something</a></li></ul>
</footer>

/*CSS*/
#footer a {colour: blue};

Ok so the colour of our footer links are blue. So now we have an advertising module that looks like the following. It features on 100 pages and the styles are in one global stylesheet.

/*HTML*/
<div class="ad">
<ul><li><a>Something</a></li></ul>
</div>

/*CSS*/
.ad a {color: red};

So now I need that advert in my footer.

/*HTML*/
<footer id="footer">
<ul><li><a>Something</a></li></ul>
<div class="ad">
<ul><li><a>Something</a></li></ul>
</div>
</footer>

/*CSS*/
#footer a {colour: blue};
.ad a {color: red};

All the links are going to be blue but they should be red. They’re being overruled by the ID as it has a higher specificity value. So how would we solve this?

/* 
Two ways I can immediately think of, both of which are shit.
1st is over specific
!important is a no no
*/
#footer .ad a {color: red};
.ad a {color: red !important};

You might argue that there is no need to have the ID on the footer element. You could do this.

<footer>
<ul id="footer-links"><li><a>Something</a></li></ul>
<div class="ad">
<ul><li><a>Something</a></li></ul>
</div>
</footer>

#footer-links a {colour: blue};
.ad a {color: red};

But again you can never reuse those styles on the same page as the ID has the be unique. If it’s definitely going to be unique then you might want to use the ID  because it’s faster (that’s something we will discuss later in the article). If it is indeed faster then why not add ID’s to everything and make it lightening fast?
The answer is because it would be impossible to maintain. It’s important to find a good balance between speed and maintainability. But solely based on these examples I can’t see any logic in using ID’s over classes for CSS.

This is a nice solution for me (but I discuss and improve on things further in the post).

<footer>
<ul class="footer-links"><li><a>Something</a></li></ul>
<div class="ad">
<ul><li><a>Something</a></li></ul>
</div>
</footer>

.footer-links a {colour: blue};
.ad a {color: red};

Moving on, I’m now talking about how fast a CSS rule is.
I also want to add that it’s not all about speed. It’s important to find the balance between speed, maintainability, re-usability, structure and efficiency (maybe more – or less – but they’re the ones off the top of my head).

For example, which is – or should be – faster?

#media a {color: red};
.media a {color: red};
a {color: red};

Interestingly browsers read CSS from right to left. Whilst this may seem a bit mental, for any person who understands the render tree will understand that by looking at the outer branches and working in they can access elements quicker than starting at the root and working outwards.

So the following is faster.

a {color: red};

It’s reading the <a> tags on the outer branches of the render tree and it doesn’t have to continue to look if that <a> is contained within anything else.

So with regards to performance here are some examples of selecting <a> tags in a media object (Using BEM).

/*HTML*/
<div class="media">
<a class="media__link">link</a>
</div>

/*CSS*/
/*
So here we're selecting the <a> inside an element with the class media
BUT the browser has to read every <a> tag then see if it's inside  a .media element
*/
.media a {colour: red};

/*THIS is faster and more efficient*/
.media .media__link {colour: red};

/*This is the fastest possible and not over-qualifying it.*/
.media__link {colour: red};

Browsers are incredibly complex things and the more I read into it the more it confuses me. I’m going to be sure to come back to it at some point and learn more about them. You can try make sense of some serious sense of them here (although it looks a little dated ;-)).

Selector speed

I’ve established that I’m not going to use ID’s for CSS.
Next topic….

Are ID’s actually faster to select?

I came across this popular article which proves they are. Unfortunately the article is dated 2010 and is tested on Firefox 3.6, I’m currently using version 31.

I’ve done some testing of my own and I’m struggling to make ID’s go faster than classes in CSS.  Have a little play with this link and see what you conclude (the results can vary dramatically between machines and browsers).

Moving onto JS I’ve made a couple of test pages that output 9999 <li> items and selects and changes the colour of the last item using JS.
I’ve made two pages…

I’ve tested this dozens of times and I’m finding that the differences are so insignificant I can barely detect any in milliseconds, so I’ve had to go to microseconds (milliseconds * 1000, and the differences are still tiny). If anything the class looks to be faster for me.

So I think I can conclude that the selector speed between ID’s and classes in both CSS & JS is incredibly small.

Unfortunately I still don’t really know why ID’s used to be faster than classes and how the browser engine actually works. I’ve realised there is a hell of a lot to know about what goes on under the bonnet and I’m going to leave that for another time.
However here are some links below to get you started.

Conclusion

So I’m left pretty confused to be honest. ID’s aren’t faster than classes in both JS and CSS. They also aren’t good for styling as they are far too specific and can’t be reused.

Using ID’s in JS means that you’re restricted in reusing the functions too.
Say I make a popup box with the button using an ID. I can only have one popup button on that page. Your project might only require one, but what if the client came back six months later and wanted two? You would have to rework your code again. Surely using a class is better?

I’m struggling to think of anything that ID’s are useful for anything other than anchor links. I know that some JS plugins will use ID’s so you would have to work with them there. But I’m struggling to think of any reason why I personally should use ID’s any more?

This has been one of my most enjoyable posts and I felt a bit out of my depth with my opinions and statements. I tried to gather evidence to back up my claims but maybe I’m missing a trick, if so shoot me a tweet.

I hope you enjoyed reading!

References and further reading