CSS Precedence

Jakob Jenkov
Last update: 2020-07-04

When multiple CSS rules target the same HTML elements, and those CSS rules set some of the same CSS properties, what styles end up being applied to the HTML element? In other words, which CSS rules take precedence?

CSS precedence is an issue that web designers and developers can spend long time fighting with. Understanding CSS precedence definitely makes the fight easier.

CSS Precedence Example

Before jumping into the CSS precedence rules, let us look at an example:

<head>
    <style>
        body {
            font-family: Arial;
            font-size: 14px;
        }
        p {
            font-size: 16px;
        }
        .logo {
            font-family: Helvetica;
            font-size  : 20px;
        }

        
    </style>
</head>
    
<body>

  <div id="header">
    <span class="logo">Super Co</span>    
  </div>

  <div id="body">
    <p>
        This is the body of my page    
    </p>
  </div>
</body>

This example contains three CSS rules. All three CSS rules set the CSS property font-size, and two of the CSS rules set the CSS property font-family. The CSS rule for the body element is inherited by both the div, span and p element. Additionally, the span element has a CSS rule targeting it by its CSS class (.logo), and the p element has a CSS rule that targets all p elements. Which styles end up being applied to span and p elements?

CSS Precedence Rules

When the browser needs to resolve what styles to apply to a given HTML element, it uses a set of CSS precedence rules. Given these rules, the browser can determine what styles to apply. The rules are:

  1. !important after CSS properties.
  2. Specificity of CSS rule selectors.
  3. Sequence of declaration.

I will explain what these rules mean in the following sections.

Note, that CSS precedence happens at CSS property level. Thus, if two CSS rules target the same HTML element, and the first CSS rule takes precedence over the second, then all CSS properties specified in the first CSS rule takes precedence over the CSS properties declared in the second rule. However, if the second CSS rule contains CSS properties that are not specified in the first CSS rule, then these are still applied. The CSS rules are combined - not overriding each other.

!Important

If you need a certain CSS property to take precedence over all other CSS rules setting the same CSS property for the same HTML elements, you can add the instruction !important after the CSS property when you declare it. The !important instruction has the highest precedence of all precedence factors. Here is an !important example:

<style>
  div {
      font-family: Arial;
      font-size: 16px !important;
  }
  .specialText {
      font-size: 18px;
  }
</style>


<div class="specialText">
  This is special text.
</div>

This example contains two CSS rules which both target the div element.

Normally, a CSS rule with CSS class selector has higher specificity than a CSS rule with an element selector, so normally the second CSS rule (.specialText {...} ) would take precedence over the first CSS rule (div {...} ). That means, that the .specialText rule would set the font-size of the div element to 18px.

However, since the div {...} CSS rule contains the instruction !important after the font-size CSS property, then that CSS property declaration takes precedence over all other declarations without the !important instruction targeting the same HTML element.

Specificity of CSS Rule Selectors

Sometimes the browser cannot determine the CSS rule or property precedence based on the !important instruction. Either because no CSS property declarations contain the !important instruction, or because multiple CSS property declaration contain the !important instruction for the same CSS property. In these cases the browser resorts to using the specificity of the CSS rule selectors to determine what CSS properties take precedence.

The specificity of a CSS rule depends on its selector. The more specific the CSS selector is, the higher is the precedence of the CSS property declarations inside the CSS rule owning the selector.

In general terms, the more specifically (uniquely) a CSS selector targets an HTML element, the higher is its specificity.

The different CSS selector types has different specificity. By specificity is meant how specifically the CSS selector targets the element is selects. Here is a list of CSS selector specificity:

CSS Selector Description
Inherited styles Lowest specificity of all selectors - since an inherited style targets the element's parent, and not the HTML element itself.
* Lowest specificity of all directly targeted selectors
element Higher specificity than universal selector and inherited styles.
attribute Higher specificity than element selector
class Higher specificity than attribute, element and universal selectors.
ID Higher specificity than class selector.
Combined selectors Gets the specificity of the selectors combined.
CSS properties set directly
on element, inside style attribute.
Stronger specificity than ID selector.

Understanding specificity from this list alone is hard, so let me follow up with some examples. First, look at this HTML + CSS example:

<body>

    <style>
        body     { font-size: 10px; }
        div      { font-size: 11px; }
        [myattr] { font-size: 12px; }
        .aText   { font-size: 13px; }
        #myId    { font-size: 14px; }
    </style>

    <div                                > Text 1 </div>
    <div myattr                         > Text 2 </div>
    <div myattr class="aText"           > Text 3 </div>
    <div myattr class="aText" id="myId" > Text 4 </div>

</body>

This example contains 5 different CSS rules which all target one or more of the div elements in the example.

The first CSS rule targets the body element. The styles set for the body element in this CSS rule are inherited by the div elements. The CSS properties set in this CSS rule will have the lowest precedence for the div elements, as they are not set directly on the div elements, but rather on their parent element, the body element.

The second CSS rule targets the div elements. This CSS rule is more specific to div elements that the styles inherited from the body element.

The third CSS rule targets all HTML elements with an attribute named myattr. This is more specific than all div elements. Thus, the div element with the myattr attribute has this CSS rule applied. If you had set an attribute value on the attribute selector, it would have been even more specific.

The fourth CSS rule targets all HTML elements with the CSS class named aText. The CSS class selector is more specific than a the div element selector and [myattr] attribute selector, so the div element with the CSS class aText will have this CSS rule applied.

The fifth CSS rule targets the HTML element with the ID myId. The ID selector is more specific than the element selector, attribute selector and class selector, so the div element with the ID myId has this CSS rule applied.

By now you should understand the specificity of the different selectors. But precedence can get more complicated still. When you combine CSS selector types their specificity is combined too. For instance, look at these CSS rules:

div { }
div[myattr]
div[myattr].aText { }    

The first CSS rule is just the standard element selector. Nothing new here. The second selector, however, is a combination of the element selector and the attribute selector. This selector will be more specific than an attribute selector by itself. The third CSS rule combines an element selector, attribute selector and a class selector. This CSS selector is even more specific than a class selector by itself.

Once you start combining CSS selector types in your CSS rules you will need to scrutinize the precedence of those selectors more carefully, or make sure that they have no overlap in targeted elements, in order to achieve the desired styling.

Jakob Jenkov

Featured Videos

Java ConcurrentMap + ConcurrentHashMap

Java Generics

Java ForkJoinPool

P2P Networks Introduction

















Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Previous
Next tutorial in this tutorial trail
Next