Apr 062010
 

specificitywars Today, I ran into a problem with some CSS code I was modifying.  I was making what I thought was a simple change, but the change refused to show up when I refreshed.  Changing the declaration type from a class to an ID, and stripping out some HTML selectors made the problem go away, but I knew that wasn’t the right thing to do.  That’s when I ran across this article at hungred.com.

Selector Order Priority

I knew CSS favored more specific over less specific.  However, I mixed up what that meant. I thought more specific was just to have MORE information pointing at the item in question. It’s not quite so simple. Compare the following two samples:

<style>
p .bordered {
border: 1px black solid;
}
.bordered {
border:	5px red dotted;
}
</style>
<div>
	<p class="bordered">Bordered?</p>
</div>
<style>
p.bordered {
border: 1px black solid;
}
.bordered {
border:	5px red dotted;
}
</style>
<div>
	<p class="bordered">Bordered?</p>
</div>

How do each of these examples work out? There’s not a big change to look for, it’s a single space between p and .bordered, and it’s the difference between the border showing up or not. In this case, the bottom example gets the black border, and the top one gets the red dotted border. (Try it out yourself here. Just replace their text with mine)

Clay at Hungred goes on to show an example formula, which looks strong at face value, but the conclusion turned out to not solve my problem. His example is:

Another interesting thing you might want to know. If you have 4 specification on a single element such as the one below,

#thislist{color: black;}

ul li ul li.thislist{color: green;}

li.thislist{color: red;}

li{color: blue;}

Assuming the HTML element is

<ul>

<li>

<ul>

<li id=”thislist” class=”thislist”>hello! </li>

</ul>

</li>

</ul>

which color will appear? The answer is black! Calculate the number of times the ID attributes in the selector. Calculate the number of times the CLASS attributes in the selector. Calculate the number of times the HTML tag names in the selector. Once you done that you will have 3 digits. Each digit is meant for each description above. Next, arrange them from left to right starting from the first description to the third one. And you will have something like this.

#thislist{color: black;} /*a: 1 b: 0 c: 0 = 100*/

ul li ul li.thislist{color: green;} /*a: 0 b: 1 c: 4 = 014*/

li.thislist{color: red;} /*a: 0 b: 1 c: 1 = 011*/

li{color: blue;} /*a: 0 b: 0 c: 1 = 001*/

Don’t get me wrong, I thought he was right too at first glance, but if his statements were true, then both of my examples would have a black border because the math would work out the same. Below, I show that the example that does not get the black border, has the higher score.

p .bordered{  [adds up to 011 with his math, but has bad syntax for my intention]
border: 1px black solid;
}
.bordered {  [adds up to 010 with his math]
border:	5px red dotted;
}

So, What is the right answer? How do you know what rules will take priority? Well, I learned an important lesson. Hungred.com was right. I wrote bad CSS. What does the above p .bordered{ example say? it says to apply .bordered to some unspecified object contained inside of a <p> element. I’m not applying it TO the <p>! That is why the CSS always chose the simpler .bordered element. <p> had the bordered class assigned to it in the HTML. While the code looked fine to me, it’s very important to link the HTML and class or ID selector together if the selector is going to be assigned to that element. The math I read about over at http://hungred.com works, but syntax is very important still. Whew.

If you made it all the way to the bottom of this article, I think you deserve a reward. An example displayed in terms we can all understand. I for one, will be printing this quick reference sheet out and hanging it on my computer. Props to Andy Clarke for a spectacular diagram.

CSS: Specificity Wars

http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html

Reddit<-- Share/Bookmark

  One Response to “CSS Math! (How to figure out CSS selector priority)”

  1. ul li ul li.thislist{color: green;} /*a: 0 b: 1 c: 4 = 014*/
    in my opinion it’s priority must be 011.3
    ul li ul = 0.3
    li.thislist = 011

Sorry, the comment form is closed at this time.