Help! understanding CSS priority rules

I’m trying (not for the first time) to understand how CSS determines whether one style rule takes priority over another. Can anyone help?

I’m fairly tech savvy (I worked as a programmer for over 20 years in several languages and environments), but this topic makes my brain shut down. All the stuff about adding up points seems utterly arbitrary and impossible to understand, much less remember and apply.

Perhaps someone has written a brilliant explanation of it which will make everything come clear. If so, please tell me where it is!

Here’s a humorous infographic, but it covers what you’re looking for:

[font=calibri]It’s called “specificity”, and here goes!

If you have conflicting style rules applied to the same element, work down these rules from the top.

[list][]if one of the rules is marked as !important and the other is not, the important one wins.
[
]if one of the rules is applied inline (ie style=“…” in the HTML) and the other is not (ie, is in a <style>…</style> or <link rel=“stylesheet”>), the inline one wins.
[]if one of the rules has more ID names in its selector list than the other, it wins.
[
]if one of the rules has more class names in its selector list than the other, it wins.
[]if one of the rules has more elements in its selector list than the other, it wins.
[
]if all of those are tied, the one that comes last wins. @imported sheets are assumed to all exist at the @import command.[/list]

(If you have more than two rules targeting the same element and two (or more) of them “win”, the other ones are knocked out and those two (or more) carry on to the next round).

So
#red {color:red;} beats .blue {color:blue;} and also beats body.home div.container p.green {color:green;}, but loses to #yellow p {color:yellow;}
meaning that this paragraph:

<body class="home">
<div class="container" id="yellow">
[b]<p class="blue green" id="red">This paragraph here</p>[/b]
</div></body>

would actually be yellow, with the above rules written in any order. Can you follow why?

Note that if we also said body.home div#yellow {color:black;}, the paragraph would still be yellow. Can you see why? After all, it’s more specific than any of the rules we had before, isn’t it? No. It’s because that rule isn’t targeting the paragraph. If no colour was set on the paragraph, it would inherit its colour from its parent element, but as soon as you set a rule that applies to the paragraph, it stops inheriting anything for that property, no matter how specific the declaration.

Hope that helps as a rough and ready guide![/font]

If you want to experiment, try this link. It gives you all you want to know.:slight_smile:
http://specificity.keegan.st/

Stevie, that is clear! I don’t think I’m going to remember it all, but I can refer to it when I have to figure out one of these problems.

The other side of the puzzle is still dark, though. When I’m writing style rules, is there a systematic way to design them so that they will behave the way I want?

[font=calibri]Not sure I get what you mean here … some aspects of CSS are very straightforward, around text formatting and that … others are more complex, around page layout. I find a piece of paper and a pencil is usually a good way to start any design! It helps you to clarify how you want each block to behave, and therefore what properties you need to apply. Then it’s just a case of trying it and testing it in a few different browsers … and coming back on here when you get stuck!

Did you have a specific question in mind here?[/font]

As much as possible, I write most rules with a single class. E.g.

.wrapper header {}

If I need something more specific, I might add another class, but that’s usually all that’s needed. I often see people unnecessarily starting with IDs and then trying to override them.

>Not sure I get what you mean… Did you have a specific question in mind here?

Yes, and I think I needed to explain it before you could understand what I was asking.

I recently had to debug the CSS for a JavaScript function that finds all of the headings on a page and builds a table of contents for them. For flexibility and simplicity, the table of contents used its own set of style rules: p.h1 for a level-one entry, p.h2 for level-two, etc. The table of contents was being displayed with no formatting at all, and I couldn’t figure out why. I finally discovered that the way the pre-existing “generic” paragraph style was defined made it more specific than the “specific” paragraph styles that I had just defined for the table of contents. (This incident is what prompted me to post my original question.)

In this situation I don’t think the advice to start with a pencil and paper would apply. The problem was abstract rather than visual. Furthermore I was adding a distinct new type of functionality to an existing (and rather complex) set of rules; my problem was not to design a complete set of rules that worked together, but to make some new rules work with the old ones, which were designed cleanly but without any consideration for what I was now trying to do.

(Also, ralph.m, if I interpret your advice to use a single rule correctly, it wouldn’t apply here; overriding one rule with another was the only way I could implement the concept cleanly.)

Yes, I was talking about starting from scratch, of course. In your situation, you have no choice but to make the new rules more specific … unless you give in and just use !important … though I don’t advise that. It sounds like the styles for the original <p>s were overly specific.

You might find the section I wrote for the Sitepoint reference useful here as it goes step by step through the issues of specificity (and indeed inheritance and the cascade). Take some time to read through it as its not rocket science if I can even understand it enough to write about it :slight_smile:

Specificity is not that hard to understand once you know the basic details and its not really necessary to do any adding up in your head a ssuch. In a simplistic way an element with more selectors will carry more weight and thus win out to those with less selectors. Ids win out over any number of classes so you also have to factor that into your rules if they contain ids and classes and of course !important trounces them all.

What catches most people out is things like this:


p.test{background:red}
.test{background:blue}

The first rule wins out because it has more weight and any p elements will never be blue. So just by looking at the rule you can guess it will have more weight because there are more selectors and both have classes. Ids will win out over any number of classes which is why a points adding up system doesn’t work because you could have a million classes but one single ID still wins out.

It really is something that becomes second nature after a little while and if you keep your rules as simple as possible then its easier still.

[font=calibri]Ugh. Trying to tidy up and work with someone else’s messy CSS is generally a nightmare. What might have seemed logical to them certainly won’t seem logical to someone else.

The best tip is to start using the developer tools in your browser to look at what styles are being applied to each element (and which ones are being ignored) – then you can start to figure out any rules that are causing problems, where you need to make changes and how specific you have to be to override what’s already there. It’s not an ideal way of doing it, but when you’re starting with an existing site there rarely is an ideal way![/font]

There are programs that will examine a stylesheet and remove all the entries that are not used. Some of them will rearrange the CSS as well to make it easier to see what is more specific than what.

If you were to run that on a COPY of the site then if it works correctly then the site will still display properly and the CSS may be shorter and easier to follow.