CSS Specificity
- Summary
-
Discussion
- What are the rules to determine CSS specificity?
- Could you explain CSS specificity with an example?
- How is specificity affected by cascading order?
- What are some examples of CSS specificity calculation?
- What are some tips for managing CSS specificity?
- I find CSS specificity confusing. Is there a simpler way?
- Is CSS specificity still relevant in modern JavaScript frameworks?
- Milestones
- References
- Further Reading
- Article Stats
- Cite As
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 rulesp { 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-0
Since 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? ul#nav li.active a
:#nav
is the ID,.active
is the class, and three elementsul
,li
anda
are used. Specificity 0-1-1-3.body.ie7 .col_3 h2 ~ h2
: Two classesie7
and.col_3
, and three elementsbody
,h2
andh2
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 toa[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
1996
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.
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.
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.
References
- Aderinokun, Ire. 2016. "The Effect of Importance and Origin on CSS Specificity." bitsofcode, January 19. Accessed 2020-10-14.
- BEM. 2020. "CSS with BEM." BEM. Accessed 2020-10-15.
- Barral, David. 2018. "Using BEM conventions in CSS modules leveraging custom webpack loaders." Trabe, September 24. Accessed 2020-10-15.
- Bos, Bert. 2016. "20 Years of CSS." W3C, December 17. Accessed 2020-10-15.
- Bos, Bert, Tantek Çelik, Ian Hickson, and Håkon Wium Lie, (eds). 2011. "Chapter 6: Assigning property values, Cascading, and Inheritance." In: Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification, W3C Recommendation, June 7. Updated 2016-04-12. Accessed 2020-10-15.
- Bostian, Emma. 2019. "CSS Specificity." Dev.to, January 21. Accessed 2020-10-14.
- Carlson, Laura L. 2002. "Calculating Specificity." University of Minnesota. Accessed 2020-10-14.
- Chijioke, Kingsley Silas. 2019. "What is CSS Specificity and How Does it Work?" Tutorial, Envato Tuts+, October 31. Accessed 2020-10-14.
- Churcher, Ali. 2018. "Overriding styles with CSS Modules: Where's my specificity?" LieferFactory GmbH, June 27. Accessed 2020-10-14.
- Clarke, Andy. 2005. "CSS Specificity Wars." Stuff & Nonsense, October 7. Updated 2018. Accessed 2020-10-15.
- Coyier, Chris. 2018. "Specifics on CSS Specificity." CSS-Tricks, February 26. Accessed 2020-10-14.
- Etemad, Elika J., and Tab Atkins, (eds). 2018. "CSS Cascading and Inheritance Level 3." W3C Candidate Recommendation, August 28. Accessed 2020-10-15.
- Friedman, Vitaly. 2007. "CSS Specificity: Things You Should Know." Smashing Magazine, July 27. Accessed 2020-10-14.
- Hiljá. 2014. "OOCSS, ACSS, BEM, SMACSS: what are they? What should I use?" Clubmate, January 23. Accessed 2020-10-15.
- Lie, Håkon Wium, and Bert Bos. 1996. "Cascading Style Sheets, level 1." W3C Recommendation, December 17. Accessed 2020-10-14.
- Lie, Håkon Wium, Elika J. Etemad, and Tab Atkins, (eds). 2013. "CSS Cascading and Inheritance Level 3." W3C Working Draft, January 3. Accessed 2020-10-15.
- Manchanda, Harry. 2017a. "The State of CSS Specificity, Part 2." CodingGame. Accessed 2020-10-14.
- Manchanda, Harry. 2017b. "The State of CSS Specificity, Part 3." Tech.io. Accessed 2020-10-14.
- Sandro. 2019. "Is BEM still a thing in a component-based world?" Dev.to, July 26. Accessed 2020-10-15.
- Singh, Kalpesh. 2016. "5 Things You Should Know About CSS Specificity." Onextrapixel, April 7. Accessed 2020-10-15.
- Street, Keegan. 2018. "keeganstreet/specificity." GitHub, August 28. Accessed 2020-10-14.
- The Electric Toolbox. 2008. "Using !important with CSS." The Electric Toolbox Blog, April 7. Updated 2020-01-02. Accessed 2020-10-15.
- Weyl, Estelle. 2012. "CSS Specificity." Standardista, January 8. Updated 2017-06-02. Accessed 2020-10-14.
- Çelik, Tantek, Elika J. Etemad, Daniel Glazman, Ian Hickson, Peter Linss, and John Williams. 2018. "Selectors Level 3." W3C Recommendation, November 6. Accessed 2020-10-14.
Further Reading
- Friedman, Vitaly. 2007. "CSS Specificity: Things You Should Know." Smashing Magazine, July 27. Accessed 2020-10-14.
- Coyier, Chris. 2018. "Specifics on CSS Specificity." CSS-Tricks, February 26. Accessed 2020-10-14.
- Çelik, Tantek, Elika J. Etemad, Daniel Glazman, Ian Hickson, Peter Linss, and John Williams. 2018. "Selectors Level 3." W3C Recommendation, November 6. Accessed 2020-10-14.
- MDN Web Docs. 2020. "Specificity." MDN Web Docs, April 20. Accessed 2020-10-14.
- Carrer, Vladimir. 2009. "CSS Specificity - Cheat Sheet." Blog, September 29. Accessed 2020-10-14.
Article Stats
Cite As
See Also
- Cascading Style Sheets
- CSS Selectors
- BEM Methodology
- CSS Design Patterns
- CSS Architecture
- Web Components