# CSS Specificity

## Summary


Assume an element on a web document is targeted by two different CSS selectors. Each selector applies different styling to that element. The selector with the higher *specificity* will take effect. CSS defines clear rules to determine the specificity of CSS selectors. 

A good understanding of the rules of CSS specificity can enable developers write better selectors and troubleshoot problems in their stylesheets. Otherwise, developers may end up misusing `!important` in their CSS declarations, thus making code more difficult to maintain in the long run.

## Discussion

### What are the rules to determine CSS specificity?

A CSS selector will typically use ID, class, element/tag name or a combination of these. In addition, some selectors will use element attributes, pseudo-classes and pseudo-elements. Specificity is computed by counting each of these and ranking them. IDs have more importance than classes, pseudo-classes and attributes; the latter have more importance than elements and pseudo-elements. Inline style, specified as attribute `style="…"`, has highest importance. The counts are concatenated to arrive at the final specificity. A selector with a higher number to the left implies higher specificity. 

If two selectors have the same specificity, one that appears later in the stylesheet is applied. Universal selector `*` and combinators (`~`, `>`, `+`) are ignored. Pseudo-class `:not()` is not counted but selectors inside it are counted. 

Although specificity is calculated for selectors, styles are applied based on individual property-value declarations. Regardless of specificity, declarations with `!important` have highest importance. If conflicting declarations contain `!important`, higher specificity wins. 

If a selector has no declaration for a specific property, inherited value (if available) or initial value is applied. 


### Could you explain CSS specificity with an example?

Given an ID, three classes and two elements, specificity is 0-1-3-0. This has higher specificity than a selector with just five classes, where specificity is 0-0-5-0.

Consider HTML content `<p class="foo" id="bar">Lorem ipsum.</p>`. Consider CSS rules `p { color: red; }`, `.foo { color: green; }` and `#bar { color: blue; }`. All three selectors target the paragraph but the last selector has highest specificity. Hence, we'll see blue-coloured text. This can be understood by calculating the specificity: 

    + `p`: one element: 0-0-0-1
    + `.foo`: one class: 0-0-1-0
    + `#bar`: one ID: 0-1-0-0Since 0-1-0-0 > 0-0-1-0 > 0-0-0-0, `#bar` selector has the highest specificity. 

If we have `p { color: red !important; }`, we'll have red-coloured text. Specificity is ignored. 

Suppose we introduce inline styling, `<p class="foo" id="bar" style="color: purple">…</p>`. This will take precedence, unless there's an earlier declaration with `!important`. 

Suppose we have two classes `<p class="foo hoo">…</p>` styled with `.hoo { color: yellow; }`. Specificity is the same for both `.foo` and `.hoo`. If `.hoo` appears later in the stylesheet, we'll have yellow-coloured text. When specificity is same, order matters. 


### How is specificity affected by cascading order?

Consider HTML content `<p class="foo" id="bar">Lorem ipsum.</p>`. Suppose the author defines `.foo { color: green; }` and the user defines `#bar { color: blue; }`. User-defined styles are typical for accessibility reasons. The latter has higher specificity but the former declaration is used; that is, text is rendered in green. To understand this, we need to understand the concept of **origin**. 

CSS styles can come from different origins: user (reader of the document), user agent (browser), or author (web developer). The standard defines precedence of the origin. This is applied first before specificity is considered. The order also considers declarations that include `!important`. 

Precedence in descending order is Transition declarations, Important user agent declarations, Important user declarations, Important author declarations, Animation declarations, Normal author declarations, Normal user declarations, and Normal user agent declarations. 


### What are some examples of CSS specificity calculation?

Here we share a few examples: 

    + `ul#nav li.active a`: `#nav` is the ID, `.active` is the class, and three elements `ul`, `li` and `a` are used. Specificity 0-1-1-3.
    + `body.ie7 .col_3 h2 ~ h2`: Two classes `ie7` and `.col_3`, and three elements `body`, `h2` and `h2` are used. `~` is not counted. Specificity 0-0-2-3.
    + `<li style="color: red;">`: Has inline style attribute. Specificity 1-0-0-0.
    + `ul > li ul li ol li:first-letter`: Apart from six elements, `:first-letter` is a pseudo-element. `>` is not counted. Specificity 0-0-0-7.
    + `li:nth-child(2):hover`: Both `:nth-child(2)` and `:hover` are pseudo-classes. Specificity 0-0-2-1.
    + `.bar1.bar2.bar3.bar4`: This is a combined selector with four classes. Specificity 0-0-4-0.

### What are some tips for managing CSS specificity?

Use IDs to increase specificity. For example, `a#foo` has higher specificity compared to `a[id="foo"]`: 0-1-0-1 > 0-0-1-1.

When two selectors have same specificity, the selector defined second takes precedence. The use of `!important` overrides specificity. If two declarations have `!important`, the second one wins. In any case, avoid the use of `!important`. 

For link styling, define CSS rules in the order of Link, Visited, Hover, Active (LVHA). 

In terms of online resources, developers can consult handy cheat sheets on CSS specificity at Stuff & Nonsense or at Standardista. There's also an online calculator.


### I find CSS specificity confusing. Is there a simpler way?

One approach is to adopt a naming convention such as **Block-Element-Modifier (BEM)**. By defining CSS classes for design components (called blocks), scope of a class is "limited" to that block. 

In BEM, selectors use only classes. IDs and elements are avoided in selectors. Combined selectors (of the form `.foo.bar`) are avoided. Nested selectors (of the form `.foo .bar`) are allowed but discouraged in BEM. Since selectors are just classes, it's easier to determine specificity. Selectors can be reused more easily. 

**CSS Modules** offers a modern way to restrict the scope of CSS declarations. Via tooling, this automatically renames the selectors. This can be configured to adopt BEM naming approach. For example, a menu component is styled with `.Menu_item--3FNtb`. If it appears within a header, the style changes to `.Header_item--1NKCj`. Although both have same specificity, the latter occurs later in the stylesheet. 

One alternative to BEM is Enduring CSS (ECSS). Partly inspired by BEM, ECSS promotes the use of single class selectors. IDs and tag names are not used in selectors. Nested selectors are allowed. 

Other alternatives include Atomic CSS (ACSS), Object-Oriented CSS (OOCSS), Scalable and Modular Architecture for CSS (SMACSS). 


### Is CSS specificity still relevant in modern JavaScript frameworks?

Among the well-known JavaScript frameworks are Angular, React and Vue. All of these offer ways to style documents in a modular fashion. This is in contrast to the default global scope of CSS selectors and declarations. In Angular and React, a **styled component** would have declarations that are applicable only to that component. In Vue, **scoped CSS** achieves the same effect.  

This idea of combining JS and CSS has been formalized under the term **CSS-in-JS**. However, one disadvantage is that we're combining HTML structure and styling into a component file. Although this isolates one component from another, it also makes styles harder to reuse across components. 

Although CSS declarations are restricted to their components, specificity can't be ignored. Specificity still applies within the component but a lot easier to manage.

## Milestones

Dec  
1996

W3C publishes **CSS1** as a W3C Recommendation. This clarifies the precedence when conflicting rules target the same element. It also explains how to calculate the specificity of selectors. 

2000

There's no exact date when developers recognize the importance of CSS specificity. Probably around 2000 (plus or minus a few years), as websites and stylesheets start to grow in complexity, developers have a hard time debugging and maintaining their code. It's at this point that they begin to learn and understand CSS specificity.

Aug  
2002

W3C publishes the first draft of **CSS2.1**, which is a revision of CSS2 from 1997. This clarifies the **cascading order**. In descending order, it's user important, author important, author normal, user normal and user agent declarations. In CSS1, precedence in descending order was author, reader and user agent declarations. 

Jan  
2006

Developer Keegan Street open sources a JavaScript module that, given a selector, calculates and return its specificity. This is a command-line tool. For convenience, an online version of this calculator is available.

Jan  
2013

In W3C Working Draft titled *CSS Cascading and Inheritance Level 3*, cascading order is updated. This document becomes a W3C Candidate Recommendation in April 2015.