Vulpix CSS

New web developers are often confused about where to place the rules for their , especially if those rules contradict others in a stylesheet. Curiously, my students seem to have no problem remembering which card beats what in a game of Magic: The Gathering, or which level of Pikachu would do best against a Vulpix in a game of Pokémon… so perhaps it is best to characterize the conflict of CSS rules as a battle for control of your page content.

As a simple example, let’s say we set up the following opposing CSS rules and apply them to code. We’ll start with a linked style sheet:

h1 {
	color: red;
}

Applied to a page with this markup and inline style:

<h1 style="color: green;">Heading Text</h1>

The must determine the winner to produce the final appearance of the <h1> text. The rules of this battle are not always obvious, especially since there are several “levels” of stylesheet:

  1. The UA stylesheet: the CSS rules that are built into the browser. The UA stylesheet has absolute priority for the appearance of elements unless its rules are directly contradicted by declarations in the user or author stylesheets below. The rules in the UA stylesheet determine how the browser presents every website by default; subtle differences in the UA stylesheets of different vendors is the reason many web developers prefer to start the CSS for their sites with reset or normalize declarations.
  2. The user stylesheet: the user may set their own rules for how they wish to see HTML content. This may include setting the zoom level on pages, increasing the font size, or using high-contrast colors.
  3. The author styles, which are divided into four sub-levels:
    1. Inline styles for individual elements, which take precedence over…
    2. Scoped styles (new in HTML5, and the subject of another blog article)
    3. Embedded styles for a page
    4. Linked CSS rules from an external stylesheet.

Most of the effort of front-end developers and designers is concentrated on author styles, so that is the battle we’ll focus our attention on: there’s nothing you can do about UA or user stylesheets anyway, short of the aforementioned resets and the !important property (again, discussed later).

CSS Rule Prioritization With Distance

The basic rule you need to keep in mind to determine CSS precedence is this: all other things being equal, rules for appearance become more “powerful” the closer they get to the element they affect. In the case of a conflict, an inline style will beat an embedded style, which in turn has more power than a linked style over the affected element.

Of course, inline styles are also the most time-consuming to write and manage, which leads to an important point:

CSS Rule Prioritization With Order

As a general rule, you can think of CSS as being read from left to right, and top to bottom. CSS rules in an inline, embedded or linked style take precedence over conflicting rules earlier in that same location. That is, in the case of a conflict, the last rule takes priority. If we have a stylesheet with two conflicting rules:

h1 { color: black; }
h1 { color: red; }

The last rule will be followed; h1 elements will be red, assuming there are no other conflicting rules. This is also the reason we list W3C standard CSS3 properties last in a declaration, with vendor-prefixed versions first.

Specificity

The more specific a rule is, the higher its priority. Again, in a theoretical stylesheet:

p { margin: 2em; } 
aside p { margin: 3em; }

In this example paragraphs that are within an <aside> element will have a margin of 3em, whatever the order of the two declarations may be in the stylesheet. (As a best practice, create general rules first, exceptions later in your stylesheet: it makes it much easier to understand your CSS).

Specificity also counters inheritance:

article {
	line-height: 200%;
} 
article p {
	line-height: 120%;
}

In this case, paragraphs in articles will have a line-height (leading) of 120%

id’s trump classes, which in turn beat simple element selectors

Style conflicts between an id and a class are settled in favor of the id. For example these styles:

p#special {
	font-size: 2rem;
}
p.specialness {
	font-size: 1rem;
}

Applied to this markup:

<p id="special" class="specialness">This is a very special paragraph…

The font-size of the paragraph will be 2rem. In a similar sense, the class for an element will beat any contradictory rules applied using a simple element selector.

The rather strange exception to this rule are classes with the specific name c000 to c255, which will beat a contradictory id declaration, as Chris Coyier demonstrates in this example.

Remember That CSS Is Reconciled Via Inheritance

Many new web developers are convinced that they must re-state all the rules they wish to use in a CSS declaration. This isn’t the case: you only have to state the rules that are different.

For example, in the following:

body {
	color: #333;
	font-size: 62.5%;
	font-family: Avenir, Arial, sans-serif;
} 
h1 {
	color: #c00;
	font-size: 2rem;
}
p {
	font-size: 1rem;
}

We only need to specify the size of the paragraphs; everything else is inherited from the <body> selector.

Conclusion

Understanding the rank, structure and resolution of CSS declarations that you order about on your site is one of the core skills of a generalist front-end web developer; having these rules at hand will help you write crisp, clean and ordered CSS code.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.