Skip to main content or search

Front-End Architecture: CSS, Specificity, Cascade, and Precision

Wednesday August 30, 2006 / 14 Comments
Note:

Matthew Pennell brings up a good point in the comments about the cascade vs. specificity. I got a little ahead of myself mentioning the cascade in this post. My next post is going into managing these aspects through multiple files and gets into the cascade where it’s more appropriate.

With CSS, your options for how to accomplish any given goal are virtually limitless. As such, it’s easy to write CSS that is a bit intertwingled and possibly confusing. The cascade is a feature of CSS. Understanding it and manipulating it for our own diabolical madness can be incredibly fun.

Simple

Adjusting specificity of your selectors to be more or less specific is one of the more powerful techniques you can master. When initially learning CSS, it’s easiest to create fairly basic and simple selectors like p.introduction, #header ul li, or div.main p

Complex

However, as we grow and mature, we quickly realize that CSS can be written elegantly to handle some pretty hairy stuff. For example, while the MySpace markup is horrendous, Mike Davidson has managed to use CSS to pull off a nice design, all things considered. Unfortunately, the CSS ended up looking like this…

table table table table td, table table table table tbody td { background-color: transparent !important; padding: 15px !important; }

It’s not pretty, but it gets the job done. Complex selectors can be necessary and useful. Obviously, we don’t want to work with markup like that of MySpace, but this example makes it clear that anything’s possible.

Elegant

That gives us a good starting point. Now let’s think about how to wield CSS more like a scalpel and less like a broadsword. Ideally, we’d be working from stellar markup full of semantic value. There’s essentially two ends of the spectrum as we write selectors. You can write very specific selectors that affect very few elements, or you can write very general selectors that affect many elements.

Very General

We’ll start with general selectors. The catch here is to be careful because a more general selector can have far-reaching effects. This is where we encounter unintended consequences if we’re not careful, and that’s a bad thing when writing code.

The most general selectors are type selectors. For example, most of us have taken advantage of body, a, or p. These make powerful but dangerous selectors if we’re not careful.

For instance, if our goal is to style all of our paragraphs in our body text, we could simply use p as your selector. However, if we instead used #mainContent p as our selector, we’re limiting the scope of that selector to have a smaller impact. This is safety through precision.

General selectors can be good, but they should be used with extreme caution, and we want to be aware of how they will affect other elements. Once that’s under control, we’ve mastered half of the specificity battle.

Very Specific

At the opposite end of the spectrum, we can write very focused selectors that might only affect one little element. These selectors might look like #someId #anotherId p ul li a and we could be pretty sure that selector wouldn’t accidentally be styling something that we didn’t intend for it to.

Our problem with specific selectors is that since we’re only styling one element at a time, we could easily end up writing a significant amount of redundant CSS, and that’s no good.

As you get more specific with your CSS rules, it’s important to understand the different options you have when writing selectors. This means balancing type, class, and ID selectors for now. Hopefully at some point in the future, we’ll even be able to reliably use child, descendant, attribute, pseudo-class, and pseudo-element selectors as well. That will increase our options and make things really interesting.

Summary

As with most topics, balance is the key. We have to take time whenever writing code to determine which is the most appropriate for a given situation. This goes back to the architecture concept and investing time in thinking through your decision rather than writing the first selector that gets the job done. Taking time to think about the cascade and how you can take advantage of it can help make your code more elegant, or conversely, not thinking about it can turn your code into a house of cards.

If you’d like to get a bit more into the nitty-gritty, the W3C page on this part of the CSS2 spec is pretty informative.

Featured Stuff - Resources: Wireframes & Page Description Diagrames

Omnigraffle and Visio versions of the wireframe templates and stencils I use on all of my projects. There’s even a few examples included for good measure. More about Wireframe & Page Description Diagram Stencils and Templates


Browser’s can have different default styles, too. I’ve started using some styles at the top of my main css files like Yahoo’s Reset CSS code or Faruk’s initial css.

Regarding font sizes, different browsers, especially on different platforms do not render fonts quite the same size. Yahoo also has some good stuff about that, too.

I’m finding that the more even you make the playing field, the more likely you won’t have to differentiate between browsers. Particularly if you deal with nitpicky designers!

Wade Winningham

Very nice take on the cascade. Every once in a while you find an article that makes things a little clearer and this is one of them.

Garret, hope you had a great vacation! Good to see you back.

Chris Alexander

Our problem with specific selectors is that since we’re only styling one element at a time, we could easily end up writing a significant amount of redundant CSS, and that’s no good.

I often run into this problem, where I find I’m styling specific elements, which defeats some of the benefits of CSS. How do you know when it’s more appropriate to style generally or specifically?

Dan Mall

Dan – It depends. :) That would probably be a whole article in and of itself. Factors such as whether the element is used in multiple places on the site and whether it’s used in different contexts matter.

For instance, if I’m styling an hCard, and I have two places wher it’s used. One is a paging listing contacts, and the other is the display of a specific contact. They might share some similarities, but I can take advantage of specificity to style the latter differently without using different class names or ID’s. (It’s a tough thing to explain in a short paragraph, but I think that does it.)

Garrett

Liked the article, but lack of a link to the aforementioned Mike Davidson (MySpace & regular) had me scratching my head.

Keep up the good work.

Andreas

Most general selectors can be included into your framework, and that will save you some time to spend working on the specific ones, and the more you use your framework the more you convert some of the specific ones to general ones, and that’s where you have to be really carefull, because trying to save time this way can really make it hard for you.

marshy

Our problem with specific selectors is that since we’re only styling one element at a time, we could easily end up writing a significant amount of redundant CSS, and that’s no good.

I also often run into this problem, where I find I’m styling specific elements, which defeats some of the benefits of CSS. How do you know when it’s more appropriate to style generally or specifically

I also continuously find this to be an issue when developing large applications or sites. When my css files start to get very large – 20k + – I find its very beneficial to go back through my css and optimize the code.

I often find that i can trace similarities of classes and ids back to root elements. As a broad example: all p tags use x font.

However, that’s often not the case and i think that this is currently a major limitation of css. The ability to use a scripting language in combination with css to define global style elements in contexts not possible through css would be a great benefit, but wait a second, i already do that with php to increase adaptability of my css files.

While this will help the developers, it does nothing for css performance. css will have to adapt if it’s to become effective for large enterprise applications.

Aidan McQuay

Very nice take on the cascade.

Just to clarify, this article is about specificity, not the cascade.

Having greater or fewer selectors in your style rule = using Specificity

Having rules in author stylesheets, linked, imported or inline = using The Cascade

Common point of confusion.

Matthew Pennell

Specificity with CSS is like having ketchup with your hotdog. It goes hand in hand. Various page by page styling can be achieved simply by adding an id selector into the body element. body#foo specificity is very high and will overwrite other more generalized selectors such as #foo (body#foo #foo is more powerful).

For example: pica.org wanted multiple page types and those page types have multiple color schemes. We were able to control the structure by utilizing elements by a simple ID selector in the body tag (id=”inside”). At the same time add more strength by adding class selectors such as class=”level1 blue” also to the body tag. Which looks like this body#inside.level1.blue in the style sheet. Thus, achieving multiple page types and multiple color schemes with out changing any of the underline structure. However, the dependencies are to plan out your structure carefully to manipulate elements to create multiple page types by specificity alone.

Now I’m rambling…I hope I didn’t waste anyone’s time, but this is how I utilize specificity and the cascade with in style sheets.

Ryan (Parrfolio) Parr

Mattew – Good point. I guess I kind of got ahead of myself referencing the cascade. My next post is about managing these aspects in separate files, and the cascade does come into play there.

Garrett

Just to clarify, this article is about specificity, not the cascade.

Damn! I almost wrote, “Nice take on specificity.” instead!

Matthew, thanks for the clarification. I’m still learning a lot about CSS.

Looking forward to the next article to help me out…

Chris Alexander

Andy Clarke’s CSS Specifity Wars still has the best explanation on the subjec, as he’s actually explaining the weight of each type of selector (I’m missing this in your article) and provides a very handy cheat sheet

May The Force be with you, always.

B!

Bramus!

Actually, the number of selectors is not as important as their strength. For example, take body .inside p a ...it’s not as specific as a#archives The number of selectors is important when you’re dealing with the same types so, body p a is more specific than p a Also, cascade deals not only with the style sheet files, but rules. For example, properties defined in a general rule such as p {...} will cascade to more specific rules such as #content p, #footer p {...}.
Would it be more appropriate to call this selector inheritance? This is a little different than parent child inheritance.

bart

Nice write-up G, I’ve been writing about this very topic for the book, and the more people understand specificity, the more powerful CSS becomes…

Adding onto Bart’s comment, it is indeed important that length and complexity of a selector is not confused with its specificity. Using one of your example selectors:

#someId #anotherId p ul li a

Adding a class to the link would allow for a more specific selector with fewer elements:

#someId #anotherId a.someclass

And an extra ID would allow the same:

#wrapper #someId #anotherId a

So even though your example selector only targets links within list items within undordered lists within paragraphs contained within elements with those specific IDs, my less-complex variations would win.

Of course, you know this, but I’ve found it pays to really get, um, specific about this topic :)

Dan Rubin

Comments are closed for this entry.