How CSS Resolves Specificity Conflicts with Source Order

When multiple CSS rules target the same element and carry identical specificity scores, the browser resolves the conflict using the principle of source order. In the CSS cascade algorithm, source order acts as the final tiebreaker: the rule defined last in the document sequence takes precedence and overwrites any preceding conflicting properties. This article explains how the browser evaluates source order within single stylesheets, across multiple external files, and alongside modern features like cascade layers.

The Mechanism of Source Order

The CSS cascade calculates priority using a specific hierarchy: importance, specificity, and source order. When two selectors have the exact same specificity calculation—for example, both are single class selectors (.button) or identical combined selectors (nav ul li a)—the specificity check results in a tie.

To break this tie, the rendering engine processes rules sequentially from top to bottom. The declaration parsed last overrides earlier declarations.

/* Specificity: 0-1-0 */
.alert-box {
  background-color: blue;
}

/* Specificity: 0-1-0 */
.alert-box {
  background-color: red;
}

In this example, both rules match the same element with identical specificity (0-1-0). Because the rule setting background-color: red appears later in the stylesheet, the element renders with a red background.

Source Order Across Multiple Stylesheets

Source order is not restricted to a single file; it applies to the entire HTML document object model in the order stylesheets are loaded:

  1. HTML <link> and <style> Tags: Rules in <link> or <style> tags placed lower in the HTML <head> will override identical-specificity rules in tags placed higher up.
  2. @import Rules: Imported styles are treated as though they appear at the exact location of the @import statement. Styles declared after an @import statement within the same file will override the imported rules if specificity is matched.

Class Attribute Order vs. Stylesheet Order

A common misconception is that the order of class names within an HTML class attribute determines priority.

<p class="text-blue text-red">Hello World</p>

The order inside class="text-blue text-red" has no impact on styling. If .text-blue and .text-red have identical specificity, the winning style is determined strictly by which class is written later in the CSS stylesheet, not in the HTML attribute.

Source Order with !important

When competing declarations both use the !important flag, normal specificity and source order rules still apply within that importance tier. If two identical-specificity rules both declare !important, the tie is once again broken by source order, and the last declared !important rule prevails:

.highlight {
  color: green !important;
}

.highlight {
  color: orange !important; /* Wins due to source order */
}

Modern Exceptions: Cascade Layers (@layer)

With the introduction of CSS Cascade Layers (@layer), source order is evaluated within the context of defined layer orders. Layer precedence takes priority over selector specificity and standard source order:

  • Declarations inside a layer defined later in the layer order override declarations in earlier layers.
  • Regular, unlayered styles always override layered styles, regardless of where they appear in the source order.
  • Inside the same layer, identical specificity conflicts revert to standard source order resolution.