DIGITALREP

CSS SpecificityApril 12, 2015

Sometimes you’ll inherit a project that has one or more CSS files that are thousands upon thousands of lines long. You’ll want to edit them, naturally, in order to update the styles of the website you’re working on. You’ll search through the CSS file for the properties you need to change and then change them, save the file, hit refresh…

And nothing happens. So you do another search and make sure that the property you just added or edited is the last instance of that property in the file. Then you make sure any preceding files aren’t overwriting your property. Then you want to make sure no one has used !important anywhere. But still…

You come up empty-handed. So what is going on?

It turns out that different things are weighted more importantly in CSS. For example, IDs always beat out CLASSES. So, if I have:

<div id="pinksquare" class="purplesquare"> Hi. I am a square. </div>

and

#pinksquare { height: 100px; width: 100px; background: pink; color: white; } .purplesquare { background: purple; }

The ID properties override the class ones – the square remains pink.

The principle seems to be that the more specific the rule is to the element it’s applied to, the higher its importance.

We can have many purplesquares but only one pinksquare, therefore the background property in pinksquare is the one that is acknowledged.

imasquare

But if you happened to have surrounded your little square in a containing div, like so:

<div id="container"> <div id="pinksquare" class="purplesquare"> Hi. I am a square. </div> </div>

And then edit your css as so:

#container { height: 100%; width: 100%; } #pinksquare { height: 100px; width: 100px; background: pink; color: white; } #container .purplesquare { background: purple; }

You are now referring to .purplesquare as a descendant of #container, and so purplesquare has borrowed the higher status of container, like it is someone attending an exclusive club as a guest of a current member, and as such the specifity of that rule is higher now, in fact, high enough to override the background rule of #pinksquare, and you will get a purple square:

imasquare2

If you knew in advance that you wanted the background colour of that square to change on some condition, you could just take the background property out of the ID and leave it to be declared only in classes.

#square { height: 100px; width: 100px; color: white; } .pinksquarebg { background: pink; } .purplesquarebg { background: purple; }

Then, with the help of jquery or javascript, you can just add/remove classes at will.

You can also use !important to force your point:

#pinksquare { height: 100px; width: 100px; background: pink; color: white; } .purplesquare { background: purple !important; }

imasquare2

… However, if you end up with a CSS file full of !important properties, then you might as well not bother with !important at all, as everything will be !important, and the ordinary rules will once more apply.

So how is specificity calcuated?

a b c d
The highest level of specificity you can get is inline css To get this score, count the number of ID attributes in the selector To get this score, count the number of classes and pseudo-classes To get this score, count the number of element names and pseudo-elements
<div style=””> #pinksquare .purplesquare
a:hover
a:nth-child(n)
div
p::first-line
div::before

So if we apply these scores to some random css rules, we get, in ascending order:

* 0000 not very specific as it includes everything
.large 0010 only applies to a certain class
.large::selection 0011 specifically, when a certain class is selected
.large:hover 0020 applies to a certain state of a certain class
#content::before 0101 applies to a specific pseudo-element of a specific ID
#content .large:hover 0120 applies to a certain class inside element of certain ID with a certain state
<div style=”color: white;”> 1000 very specific, only applies to the element it is attached to

Category: Best Practices
Tags:  

Leave a Reply

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