Stylist Logo

Introduction to Specificity

This entry is part 3 of 15 in the series Stylist

ABSTRACT

CSS Specificity is something that many, many Web designers ignore, or get completely wrong. Misunderstanding specificity can lead to strange, stubborn bugs in your CSS. However, a good understanding of specificity can give you iron-fisted control of your page layout.

Specificity is the third leg in the “tripod” that forms the foundation of CSS-based design. With an understanding of the need to separate structure from presentation, the difference between block and inline elements and a good grasp on specificity, we’ll be able to move forward towards attractive, usable and fast-loading Web sites.

This discussion is gonna take a long time, and will be covered in a number of postings, so you can get it in bite-sized bits. It will cover the basics of how style is applied to markup.

PREREQUISITE

You should be familiar with the basic syntax of style definitions. I use the term “rule” to apply to a style defintion. A rule is basically made up of two basic types of component:

The selector:

<style type="text/css">
	body{ color:red }
</style>

and the properties:

<style type="text/css">
	body { color:red }
</style>

WHAT IS “SPECIFICITY”?

Let’s begin by examining the basic behavior of CSS. The “C” in “CSS” stands for “Cascading.” This means that you can add to, or alter, a style by redefining that style in a consecutive (cascading) manner.

For example, you can specify that all paragraphs have a 1em indent, but remove that indent for special first paragraphs:

<style type="text/css">
    p { text-indent:1em }
    p.first { text-indent:0em }
</style>

NOTE: This site has a great deal of style applied to it, so it will interfere with examples displayed in a site page. Because the examples will start getting difficult to display in these pages, I will link directly to the example HTML files, so you can see them and download the example code.

Example 10

<html>
    <head>
        <title>Example 10</title>
        <style type="text/css">
            p { text-indent:1em }
            p.first { text-indent:0em }
        </style>
    </head>
    <body>
        <p class="first">This is a first paragraph. It is not indented.</p>
        <p>This is a normal paragraph, so it is indented</p>
    </body>
</html>

I made this example a bit more complex because I want to stop using inline styles, and start using “proper” styles. In order to keep things as simple as possible, I’ll declare the styles in the HTML page (for now). In actual implementation, you will probably want to use an external CSS file instead. When declaring “proper” styles in an HTML page, you need to declare them in the <head> section of the page.

Okay, now, what happened here, was we made a very general (non-specific) rule for all <p> (paragraph) elements:

p { text-indent:1em }

This says that all paragraphs should be indented by 1 em.

However, notice that the first paragraph is not indented. This is because we wrote another rule with a higher specificity, that says <p> elements that have been assigned a class of “first” will not be indented:

p.first { text-indent:0em }

The basic rule of specificity is that the more specific your CSS class is, the more mojo it has. Proper CSS design uses this to keep style predictable, simple and easy to understand.

In order to get a grasp on specificity, we need to review how styles are assigned and referenced.

Assigning Styles

There are four ways to assign style to a markup element: implicit (element name), class, element ID and inline. You have already seen inline in action in previous posts, and I showed you class assignment in example 10.

Implicit references use only the element name, such as <div> or <p>. This is very general, and has low specificity.

Element ID is actually a far more broad concept than just style, but CSS uses it to enhance the choices for applying style to markup.

In HTML DOM (Document Object Model), each element can have “attributes.” Attributes are those things in a markup element that have a 'name=”value”' structure, such as '<div style=”font-weight:bold”>' or '<div id=”little_red_wagon”>'. We use attributes in our markup to give the style something to reference.

So, you can define a markup element in any one of four ways (or combinations thereof):

  1. <div> (Implicit reference, only “blanket classes” can be applied).
  2. <div class="some_class_name"> (The element has a class).
  3. <div id="some_unique_id"> (The element has an ID).
  4. <div style="font-weight:bold"> (Direct inline style)

#1 is no special assignment, so the element can have style applied to it using only the “main” element type styles. This can be combined with the other definitions to give much more specificity. I’ll go over this in more detail later.

#2 is interesting. You can assign more than one class to an element:

<div class="some_class_name another_class_name">

I’ll go into more detail about how this works later.

The rule with #3 is that the ID must be unique within the page. No other element, of any type, can have the same ID. This means that you can use CSS or JavaScript to reference just that element. Applying the same ID to multiple elements on a page is an HTML error.

As I mentioned earlier, we should try to avoid #4. When we define inline style, we are violating the separation of presentation and structure, and we’re also cutting off the ability to affect the element through changes in style. An inline style has the highest specificity. It will overrule any prior style assignments. The one place that I will often use inline style, is when I am defining elements to be revealed and hidden, using JavaScript. The easiest way to do this is by affecting the style="display:none" property. You can also use JavaScript to affect the class, but that is usually a bit of overkill.

We’ll use the following example markup in most of our subsequent examples:

Example 11

<html>
	<head>
		<title>Example 11</title>
	</head>
	<body>
		<div class="container_class" id="main_container">
			<div>This &lt;div&gt; has no specific assignment. It is just a &lt;div&gt;.</div>
			<div class="special_class">This &lt;div&gt; has a class assignment. It is a "special_class" &lt;div&gt;.</div>
			<div class="special_class second_class">This &lt;div&gt; has two class assignments. It is a "special_class" and a "second_class" &lt;div&gt;.</div>
			<div id="special_id">This &lt;div&gt; has an ID. It is "special_id".</div>
			<div style="font-weight:bold">This &lt;div&gt; has inline style. It displays its node value as bold text.</div>
			<div class="special_class" id="second_id">This &lt;div&gt; has a class assignment and an ID. It is a "special_class" &lt;div&gt;, and its ID is "second_id".</div>
			<div class="special_class" id="third_id" style="font-weight:bold">This &lt;div&gt; has a class assignment, an ID and inline style. It is a "special_class" &lt;div&gt;, its ID is "third_id" and it will display its node value as bold.</div>
		</div>
	</body>
</html>

For the record, there’s an excellent article by Eric Meyer (one of the people who developed the CSS standard), that summarizes the concept of specificity fairly well.

Okay, that’s enough for this post. Next, we’ll go over how to use these assignments, and how specificity is applied.