CSS - Specificity
Specificity Hierarchy
In CSS, selectors have different levels of specificity, which determine which styles are applied to an element when there are conflicting rules. Understanding the specificity hierarchy is key to writing effective and maintainable CSS code. Here's a breakdown of the specificity hierarchy, from highest to lowest:
Inline styles
Inline styles, which are applied directly to an element using the style
attribute, have the highest specificity. They take precedence over any other styles defined in external stylesheets or <style>
tags.
Inline styles example
<p style="color: red;">This text will be red.</p>
IDs
ID selectors, which target a specific element with a unique ID, have the second-highest specificity. An ID selector is defined using the #
symbol followed by the ID name.
ID selector example
#unique-element {
background-color: yellow;
}
Classes, attributes, and pseudo-classes
Class selectors, attribute selectors, and pseudo-classes have the third-highest specificity. They are more specific than element selectors but less specific than IDs.
Classes, attributes, and pseudo-classes example
.class-name {
font-weight: bold;
}
[type="text"] {
border: 1px solid black;
}
a:hover {
text-decoration: underline;
}
Elements and pseudo-elements
Element selectors and pseudo-elements have the lowest specificity. They target elements based on their tag name or a pseudo-element.
Elements and pseudo-elements example
p {
font-size: 16px;
}
h1::before {
content: "* ";
}
When multiple selectors target the same element, the browser applies the styles according to the specificity hierarchy. Inline styles take precedence over IDs, which take precedence over classes, attributes, and pseudo-classes, which in turn take precedence over elements and pseudo-elements.
Calculating Specificity
To find which styles apply to an element when there are conflicting rules, browsers calculate the specificity of each selector. Specificity is calculated based on a set of weight values assigned to different types of selectors.
Specificity weight values
The specificity of a selector is calculated using four components, each with a different weight value:
Component | Weight Value |
---|---|
Inline styles | (1, 0, 0, 0) |
IDs | (0, 1, 0, 0) |
Classes, attributes, and pseudo-classes | (0, 0, 1, 0) |
Elements and pseudo-elements | (0, 0, 0, 1) |
The specificity value of a selector is the sum of its weight values for each component.
How to calculate the specificity of a selector
To calculate the specificity of a selector, follow these steps:
- Count the number of inline styles, IDs, classes/attributes/pseudo-classes, and elements/pseudo-elements in the selector.
- Multiply each count by its corresponding weight value.
- Sum up the weighted counts to get the final specificity value.
The selector with the highest specificity value takes precedence over others.
Examples of specificity calculations
Example 1
p {
color: black;
}
.text {
color: blue;
}
p
: (0, 0, 0, 1) = 1.text
: (0, 0, 1, 0) = 10
The .text
selector has a higher specificity, so the text will be blue.
Example 2
#unique-id {
color: green;
}
p.text {
color: red;
}
#unique-id
: (0, 1, 0, 0) = 100p.text
: (0, 0, 1, 1) = 11
The #unique-id
selector has a higher specificity, so the text will be green.
Example 3
<p class="text" style="color: orange;">Hello, world!</p>
#unique-id {
color: green;
}
p.text {
color: red;
}
- Inline style: (1, 0, 0, 0) = 1000
#unique-id
: (0, 1, 0, 0) = 100p.text
: (0, 0, 1, 1) = 11
The inline style has the highest specificity, so the text will be orange.
Specificity Rules
When working with CSS, you need to understand the rules that govern specificity. These rules help determine which styles are applied when there are conflicting selectors targeting the same element. Let's look at some key specificity rules:
Equal specificity: the latest rule counts
When two selectors have the same specificity, the one that appears later in the stylesheet takes precedence. This is because CSS cascades from top to bottom, and the last rule encountered overrides previous ones with equal specificity.
Equal specificity example
p {
color: black;
}
/* This rule will override the previous one */
p {
color: blue;
}
ID selectors have a higher specificity than attribute selectors
ID selectors are more specific than attribute selectors. This means that if an element is targeted by both an ID selector and an attribute selector, the styles defined by the ID selector will be applied.
Example: ID vs Attribute Selectors
#unique-element {
background-color: yellow;
}
[id="unique-element"] {
background-color: green;
}
The element with the ID "unique-element" will have a yellow background because the ID selector has higher specificity.
Contextual selectors are more specific than a single element selector
Contextual selectors, which target elements based on their relationship to other elements, have a higher specificity than a single element selector.
Example: Contextual Selectors
div {
font-size: 16px;
}
div p {
font-size: 14px;
}
Paragraphs inside a <div>
will have a font size of 14px, while other <div>
elements will have a font size of 16px.
The universal selector has low specificity
The universal selector (*
), which targets all elements, has a very low specificity. It has a specificity value of (0, 0, 0, 0), which means that any other selector will override its styles.
Example: Universal Selector
* {
margin: 0;
padding: 0;
}
p {
margin: 10px;
}
All paragraphs will have a margin of 10px, overriding the universal selector's margin of 0.
Inherited values have low specificity
Inherited values, which are passed down from parent elements to their children, have a specificity value of (0, 0, 0, 0). This means that any directly applied style will override an inherited value.
Example: Inherited Values
body {
color: black;
}
p {
color: blue;
}
Paragraphs will have a color of blue, overriding the inherited black color from the <body>
element.
The !important Exception
In CSS, the !important
declaration overrides the normal specificity rules. When !important
is used, it gives the declared style the highest priority, regardless of its selector's specificity.
How !important overrides other specificity values
When you add !important
to a style declaration, it overrides any other conflicting styles for that property, even if the conflicting selector has a higher specificity value.
Specificity override example
#unique-element {
background-color: yellow;
}
.class-name {
background-color: blue !important;
}
The element with the ID #unique-element
will have a blue background, despite the ID selector having a higher specificity than the class selector. This is because the !important
declaration overrides the specificity hierarchy.
When to use !important
While !important
can be useful in certain situations, it should be used sparingly, as it can make your CSS harder to maintain and debug. Here are a few cases where using !important
might be justified:
Case | Explanation |
---|---|
Overriding inline styles | If you need to override inline styles applied directly to an element, using !important can be a quick solution. |
Overriding styles from third-party libraries | When working with third-party CSS libraries, you might need to use !important to override their styles to match your design. |
Creating utility classes | If you are creating utility classes that should always take precedence, such as a class for hiding elements, using !important can make sure that the styles are applied consistently. |