This post will focus on why it is important to use classes instead of id's as much as possible in your CSS declarations. It isn't always possible but if you can stick to this rule, you will avoid future headaches when you are trying to change the style of a class only to find that the styling on the id is trumping your new style declaration. Let's dig into this to see what we mean.

So you probably know that cascading style sheets operate on the principle that the order of precedence goes like this.

inline styling > embedded styling > external style sheets

Thus, if you declare a style in-line, i.e. within the html, it will take precedence over a style for the same element that may have been declared in the <style> section of the <head> portion of the html or in the external style sheet(s). For a single web-page, you might see embedded styling and in-line styling while for full websites, the preference is to move as much styling as you can to external style sheets to separate style from the html form. For a refresher on these three ways of inserting CSS declarations, read up on W3Schools.org.

The further down in the style sheet you put your declaration, the higher precedence it has. Thus, if you have the following two declarations in your CSS, the bottom one will win:

.class1 { color: red; }
.class1 { color: green; }

This seems trivial and obvious but keep in mind that a style sheet could have hundreds or even thousands of line of code and the two declarations above could be very far apart. And this principle is useful when you are changing a style on a website, perhaps one that you didn't create. Many Wordpress themes make use of this principle to give the user the ability to update styling without necessarily having to access the CSS files living on the server. Often times in the Wordpress admin area you will find a "Custom CSS" section where you can input your CSS changes and magically (seemingly), the new style over-writes the old one. Really what is happening is that the Wordpress theme is injecting the style into the embedded CSS (that is, into the <style> section of the <head> of the html document. And since embedded CSS takes precedence over external style sheets, it will "win". You could think of the embedded styles being put at the bottom of the external style sheet which would give them preference because they would be at the very bottom of the external style sheet.

But we haven't even mentioned ID's yet and you're thinking, "the title mentions ID so when do we get to that". Well, let's go there now.

It turns out that CSS has something called Specificity which determines the rules for what style will actually be applied to a web page. Take a look at the image below.

CSS Specificity Rules

Notice how I didn't say not to use IDs in your HTML markup? These can be good to use in your JavasCript as hooks and that's fine. The trouble comes when you use them to style elements in your CSS because there specificity is so high, the only way to overcome them is to put another declaration further down on your style sheet or use !important to trump it. Before explaining what that is, let's dig deeper into specificity.

As you can see from the diagram above, elements (like a <div>, <p>, h1, etc.) have the lowest specificity, then classes and pseudo-classes, then IDs, and lastly inline styling. So, an inline style will overcome a style on an ID, an ID will overcome a style on a class, a class will overcome an element.

What is this !important thing? If you've never heard of it, it's basically like the silent ninja that can come in and take precedence over any other declartion. Here's how you might see it in a style sheet.

.class1 { color: red !important; }

As you can see, you place the !important after the attribute value, in this case red.

But, I am in no way advocating using !important because it injects a very difficult scenario. It sets the specificity so high for that particular CSS attribute declaration that it is nearly impossible to overcome. In fact, the only way to over come it would be to place an over-riding one further down in the style sheet.

To illustrate the preceding points, take a look at the fiddle below. You can click around the tabs to see the HTML, CSS, JavaScript and the Result. To play around and edit yourself, click "Edit in JSFiddle". I recommend trying these steps:

  1. Comment out the class1 and class2 declarations (by surrounding with /*  */). Notice how the h1 declaration now has priority and "My Heading" turns black.
  2. Uncomment class1 and class2 and notice how the class2 declaration is chained .class2.class2. This doubles the specificity for the declaration color: green; and allows it to beat the class1 declaration below it.
  3. Uncomment id1 and "My Heading" will turn blue. Recall id takes precedence over class.
  4. In the HTML section, for h1 in the style where the empty "" are, type color: orange; and you should see "My Heading" turn orange. Recall that inline styling takes precedence over embedded or external styling.
  5. Lastly, in the JavaScript section, uncomment the statement document.getElementById('id1').style.color = "pink";. "My Heading" should turn pink. This is because we are using id1 as a hook to get ahold of the element and style it. This will work unless !important is used somewhere else in the styling. Go ahead and try it. Put !important after green but before the semi-colon on the line that says .class2.class2. Can you see why !important could end up being quite troublesome? Changes we try to make with JavaScript could fall flat.

This post merely gives you an overview of CSS Specificity. Actually, the browser uses a point system of sorts to determine which style declaration will win out. You got a taste of this when you saw .class2.class2 because it appeared like it got double points due to the chaining and thereby was able to overcome a class that was declared below it. This is actually true.

To go deeper into the topic of specificity and to calculate what the specificity will be of a certain style declaration, check out the Further Reading.

Further Reading (and Viewing)