A Brief Guide to CSS Specificity

Specificity, also known as ”selectors weight”, is the very emanation of the ”cascadingness” of CSS. A better understanding of this concept will help avoid frustration and solve problems related to inability to override property values without using the magic of the !important flag.

In brief, the specificity of CSS selectors is a simple calculation of values on the basis of the type of elements that a rule consists of – HTML elements, class names, IDs, attribute selectors ([attr="value"]), pseudo classes (:hover, :link), pseudo elements (:first-letter in CSS2, ::first-letter in CSS3, the difference between the two is the double colon, and was introducedd by W3C in order to clearly distinguish between pseudo-classes and pseudo-elements), inline styles etc. The maths will be explained later in this article.

Below is a simple example of CSS specificity:

div
{
	color: black;
}

div.red
{
	color: red;
}

div.red selector will override the more common setting of div, because it is more ”specific”. According to W3C, specificity is calculated by counting various components of the CSS and expressing them in a four letter form (A, B, C, D):

Element, Pseudo Element: D = 1 – (0, 0, 0, 1)

Class, Pseudo Class, Attribute: C = 1 – (0, 0, 1, 0)

ID: C = 1 – (0, 1, 0, 0)

Inline CSS: A = 1 – (1, 0, 0, 0)

The example above clearly explains the concept of selectors weight, and div.red is more specific than div, because:

div
{
 /* specificity = 1 (0, 0, 0, 1),
 because the selector consists of 1 element */
 color: black;
}

div.red
{
 /* specificity = 11 (0, 0, 1, 1),
 because the selector consists of 1 element + class name */
 color: red;
}

A more complex and not so obvious example may be:

div p.info
{
 /* specificity = 12  - (0, 0, 1, 2),
 because the selector consists of two html elements + class name */
 font-size: 14px;
}

#content p
{
 /* specificity = 101 (0, 1, 0, 1),
 because the selector consists of 1 ID + 1 element */
 font-size: 12px;
}

According to the specifications, an ID selector has a specificity of 100, and in the example above the second selector will take precedence despite its position in the stylesheet, because 101 > 12.

Finally, a word about inline CSS and the magical !important flag:

<div style="color: lime">lorem ipsum...</div>

Adding CSS inline by using the style attribute directly in the HTML tag will override everything that has been set so far (unless there are no property values forced with !important) because the specificity of the inline CSS is 1000. !important should be used sparingly and only as a last resort, because its excessive usage will imminently end up to a point where we are unable to set any style, even with JavaScript because:

element.style.color = "pink !important";

… is not part of the DOM specification, and if we try to override:

#div-1
{
 color: red !important;
}

by

document.getElementById("div-1").style.color = "green !important";

… this will throw an exception in Internet Explorer (“Invalid property value.”). Opera and WebKit will actually turn the color to green, while FireFox will not produce any errors but will not apply the new color value either. If we try to override the value without the !important flag, this will not have any effect because red has been already hardcoded in the CSS.

Possible solutions if you are stuck in the above:

document.getElementById('div-1').setAttribute('style','color:green !important');
document.getElementById('div-1').setAttribute('class','sec');
.sec {color:green !important}

The jQuery addClass method.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s