Each individual CSS Selector has its own specificity value. Every selector in a sequence increases the sequence’s overall specificity. Selectors fall into one of three different specificity groups: A, B and c. When multiple selector sequences select a given element, the browser uses the styles applied by the sequence with the highest overall specificity.
Group | Comprised of | Examples |
—— | –––––––––––––––––––– | ––––– |A | id selectors | #foo
|B | class selectors attribute selectors pseudo-classes | .bar
[title]
, [colspan="2"]
:hover
, :nth-child(2)
|c | type selectors pseudo-elements | div
, li
::before
, ::first-letter
|
Group A is the most specific, followed by Group B, then finally Group c.
The universal selector (\\*
) and combinators (like \\>
and ~
) have no specificity.
#foo #baz {} /* a=2, b=0, c=0 */
#foo.bar {} /* a=1, b=1, c=0 */
#foo {} /* a=1, b=0, c=0 */
.bar:hover {} /* a=0, b=2, c=0 */
div.bar {} /* a=0, b=1, c=1 */
:hover {} /* a=0, b=1, c=0 */
[title] {} /* a=0, b=1, c=0 */
.bar {} /* a=0, b=1, c=0 */
div ul + li {} /* a=0, b=0, c=3 */
p::after {} /* a=0, b=0, c=2 */
*::before {} /* a=0, b=0, c=1 */
::before {} /* a=0, b=0, c=1 */
div {} /* a=0, b=0, c=1 */
* {} /* a=0, b=0, c=0 */
Imagine the following CSS implementation:
#foo {
color: blue;
}
.bar {
color: red;
background: black;
}
Here we have an ID selector which declares color
as blue, and a class selector which declares color
as red and background
as black.
An element with an ID of #foo
and a class of .bar
will be selected by both declarations. ID selectors have a Group A specificity and class selectors have a Group B specificity. An ID selector outweighs any number of class selectors. Because of this, color:blue;
from the #foo
selector and the background:black;
from the .bar
selector will be applied to the element. The higher specificity of the ID selector will cause the browser to ignore the .bar
selector’s color
declaration.
Now imagine a different CSS implementation:
.bar {
color: red;
background: black;
}
.baz {
background: white;
}
Here we have two class selectors; one of which declares color
as red and background
as black, and the other declares background
as white.
An element with both the .bar
and .baz
classes will be affected by both of these declarations, however the problem we have now is that both .bar
and .baz
have an identical Group B specificity. The cascading nature of CSS resolves this for us: as .baz
is defined after .bar
, our element ends up with the red color
from .bar
but the white background
from .baz
.
The last snippet from Example 2 above can be manipulated to ensure our .bar
class selector’s color
declaration is used instead of that of the .baz
class selector.
.bar {} /* a=0, b=1, c=0 */
.baz {} /* a=0, b=1, c=0 */
The most common way to achieve this would be to find out what other selectors can be applied to the .bar
selector sequence. For example, if the .bar
class was only ever applied to span
elements, we could modify the .bar
selector to span.bar
. This would give it a new Group C specificity, which would override the .baz
selector’s lack thereof:
span.bar {} /* a=0, b=1, c=1 */
.baz {} /* a=0, b=1, c=0 */