Thoughts on Cascading Style Sheets (CSS)
By Mark DuBois
Director of Education, WebProfessionals.org
As a professor teaching web technologies, I am often presented with clear examples demonstrating that someone does not fully grasp a concept. In this case, the number in question was 3,547. That was the number of classes in one CSS linked stylesheet to style one website. Yep. Over three thousand separate classes. I know, I counted them. Yes, it was painful.
Clearly, there was a lack of understanding of inheritance and the cascade part of Cascading Style Sheets. For those who would like more information on this topic, please visit http://www.w3.org/wiki/Inheritance_and_cascade [this blog post was inspired by content on that page].
Let’s first review inheritance. If you have ever had a class in genetics, you have likely heard the tired joke – “chances are that if your parents never had children, you won’t either!” Yes. Wait… What?… Ok, bad joke, but we inherit a lot of things from our parents – eye color, hair color, lack of hair, a number of diseases, and so forth. With respect to HTML elements, child elements inherit many of the features of their parent. For example, a within a
element will inherit the font properties and so forth. If this were not the case, we would need to specify all properties for all elements (and we would go beyond 3,500 separate definitions for a page – not something anyone desires. Of course, not all properties are inherited (margins, for example) as it would not make sense.
Now for the more confusing part – deciding which style wins when multiple styles apply to the same part of the web page. These conflicts are resolved by importance, then specificity, then source order. If something is important, it wins. If the importance is the same, then specificity applies. If specificity is the same, then source order wins.
Regarding importance, the lowest choice in the list below wins.
•Browser style sheet (yes, if you have ever wondered why a certain font appears for text in a web page with no styling, this is because each browser has a built in style sheet).
•User defined style sheets with normal declarations. In some browsers (Internet Explorer, for example), someone can define their own style sheet and apply it to web pages they view. For example, they may want to have a higher contrast or larger letters or a specific background color. Although most do not do this, people can.
•Author defined style sheets (those would be the CSS documents we create when building our web pages). We want our pages to have a certain look (font, color and so forth) and do this with CSS.
•Important declarations in author defined style sheets. These would be declarations including !important. Frankly, that one has always confused me. In every programming language the ! symbol implies not. Yet it means exactly the opposite in CSS. Go figure.
•Important declarations in user defined style sheets. This one will always win. If you think about it, this makes sense. If I really need a high contrast to view a web page and go to the trouble of writing my own CSS, I should be able to insist that the browser follows my preferences on my computer.
Ok, I understand importance. I know it is important. But what if there is only a set of author defined style sheets. What if there are multiple rules for the same area of the web page. Now what?
This is where specificity comes in to play. The match highest on the following list will win.
•Inline style (within a document we specify something like
•Id (after all we can only assign one spot on a web page a unique id).
•Class and pseudo-class. There can be multiple uses of a class on a page so this should have less priority/ specificity.
•Elements and pseudo-elements. This has the lowest specificity.
Consider this example:
body nav#top *.home a:link would yield a specificity of 0, 1, 2, 3. Since there is no inline style, 0 is the first value. There is a unique id (#top) which results in a value of 1. There is one attribute (.home) and one pseudo-class(link) yielding a value of 2. Lastly, there are 3 elements (body, nav, and a).
Lastly, there is source order. If there are conflicts within a given CSS document, the last definition wins. Remember that CSS is processed from top to bottom so the last one will override a prior declaration.
If there are multiple linked CSS documents and there is a conflict, the one which appears last in the documents will win). Again, the browser interprets CSS from top to bottom.
Lastly, inline style wins over embedded (within the document) which wins over linked.
If you still have a bit of trouble with these concepts, create a web page and apply different conflicting styles to see what wins. Personally, I typically use background-color within my CSS to make it obvious to students. Having a solid understanding of these concepts is very important. If you are participating in a web design contest or building a site for a client (and two of you are working on the look of the site), this should help you better understand why a given style wins.
By the way, once the particular student had a clearer understanding of inheritance and cascade, they managed to reduce the number of classes to under 50. Yes, from 3,500 to less than 50. This is why it is important to know these concepts.