CSS Specificity Made Simple: Know Which Style Wins!

CSS Specificity Made Simple: Know Which Style Wins!

CSS specificity determines which styles apply to an element when multiple CSS rules match. Understanding this concept is crucial for writing clean, maintainable, and conflict-free stylesheets. Let’s break it down step by step.

What is CSS Specificity?

CSS specificity is like a score that tells the browser which style rule is more important when there are conflicting rules targeting the same element. Higher specificity wins.

CSS - Specificity

Priority Order in CSS Specificity

The browser follows a specific priority order to determine which styles apply:

  1. Inline Styles (style="..."):

    • Inline styles have the highest specificity. They are applied directly to an element within the HTML and will override any other styles defined in external or internal stylesheets.
  2. ID Selectors (#id):

    • ID selectors have a high specificity, second only to inline styles. They are unique within a page, meaning each ID should be used only once, making them more specific than classes or element selectors.
  3. Classes, Attributes, and Pseudo-classes (.class, [attr=value], :hover):

    • These selectors have a moderate level of specificity. Classes can be reused across multiple elements, attributes target elements with specific attributes, and pseudo-classes apply styles based on the state of an element (e.g., :hover for when a user hovers over an element).
  4. Element Selectors and Pseudo-elements (div, p, ::before):

    • Element selectors and pseudo-elements have the lowest specificity among the standard selectors. They apply styles to all instances of a particular element type or to specific parts of an element (e.g., ::before to insert content before an element's content)Rules with higher specificity in this order will override lower ones.

In cases where multiple rules apply to the same element, the rule with the highest specificity will take precedence. If two rules have the same specificity, the one that appears later in the CSS will be applied.


How Specificity Works

Specificity is like a score that determines which CSS rule wins when there are conflicts. The browser calculates it based on the types of selectors used. Each type contributes a different weight to the score:

  1. Inline styles: Always have the highest weight.

  2. ID selectors: Count more than classes or elements.

  3. Class selectors, attributes, and pseudo-classes: Moderate weight.

  4. Element selectors and pseudo-elements: Lowest weight.

  5. Universal selectors (*): No weight.

The specificity score is written as a four-part value: (a, b, c, d) where:

  • a: Inline styles.

  • b: Number of ID selectors.

  • c: Number of class selectors, attributes, and pseudo-classes.

  • d: Number of element selectors and pseudo-elements.

For example:

  • #id = (0, 1, 0, 0)

  • .class = (0, 0, 1, 0)

  • div = (0, 0, 0, 1)

CSS Specificity. According to MDN, Specificity is the… | by Tanish Rajput |  Medium

Above Image is an example of four pat value (a, b,c ,d)


Specificity Calculation Examples

SelectorSpecificityExplanation
*(0, 0, 0, 0)Universal selector has no specificity.
li(0, 0, 0, 1)One element selector.
ul li(0, 0, 0, 2)Two element selectors.
.class(0, 0, 1, 0)One class selector.
#id(0, 1, 0, 0)One ID selector.
style="color: red;"(1, 0, 0, 0)Inline styles always take priority.
#id.class(0, 1, 1, 0)One ID and one class selector.
#id ul li.class(0, 1, 1, 2)One ID, one class, and two element selectors.

Key Specificity Rules

  1. Inline styles always win:

     <div style="color: red;">I am red!</div>
    
    • Specificity: (1, 0, 0, 0)
  2. ID selectors outweigh classes and elements:

     #important { color: blue; }  /* (0, 1, 0, 0) */
     .highlight { color: green; } /* (0, 0, 1, 0) */
     div { color: red; }          /* (0, 0, 0, 1) */
    
    • Result: #important styles will apply.
  3. Classes beat element selectors:

     .btn { background: yellow; } /* (0, 0, 1, 0) */
     button { background: gray; } /* (0, 0, 0, 1) */
    
    • Result: .btn styles will apply.
  4. Universal selectors (*) have no specificity:

     * { color: black; } /* (0, 0, 0, 0) */
     p { color: red; }   /* (0, 0, 0, 1) */
    
    • Result: p styles will apply.
  5. !important overrides specificity:

     p { color: blue !important; } /* Overrides all specificity */
    

Special Cases

Combining Selectors

Using multiple selectors increases specificity. For example:

  • #id.class = (0, 1, 1, 0)

  • #id .class = (0, 1, 1, 0)

Cascade Rule

If specificity is equal, the browser uses the rule defined later in the CSS file.

p { color: red; }  /* Defined first */
p { color: blue; } /* Defined later */
  • Result: p will be blue.

Best Practices for Managing Specificity

  1. Avoid overly specific selectors:Use simple selectors to make styles easier to override and maintain.

     #header .nav ul li a { color: white; }
    
    • This makes styles harder to override.
  2. Prefer Classes Over IDs: Use classes for styling instead of IDs to keep specificity lower and more manageable.

     .btn-primary { background: blue; }
    
  3. Organize CSS from general to specific: Write your CSS starting with general styles and move towards more specific ones.

     /* General styles */
     body { font-family: Arial; }
    
     /* Specific styles */
     .card { border: 1px solid #ccc; }
    
  4. Use !important sparingly: Reserve it for truly critical overrides. Reserve !important for critical overrides only, as it can make debugging difficult.


Conclusion

Understanding CSS specificity helps you write conflict-free styles and maintain cleaner code. Stick to best practices, keep selectors simple, and remember that specificity is just one part of the cascade! With these principles, you’ll master CSS in no time.