Specificity

[todo]

  • Selectors
  • Cascade
  • Inheritance
  • Specificity

Example

Here’s some nicely written HTML with BEM-style class names.

<header class="site-header">
    <a class="logo" href="#">Hobbiton</a>

    <form class="search-form">
        <label class="search-form_label" for="search">Search</label>
        <input type="text" class="search-form_input" id="search" name="q">
        <button type="submit" class="search-form_button">Search</button>
    </form>
</header>

And two ways to target the button:

// Good (10 specificity)
.search-form_button {}

// Bad (32 specificity)
.site-header .search-form input[type='search'] + button {}

Chaining selectors creates a specifity mess. This matters because

Reducing specificity

1. Use a CSS naming convention

2. Use nesting only for pseudo-classes and pseudo-elements.

3. Don’t use IDs for styling.

IDs raise specificity by 100.

4. Don’t use inline styling.

Inline styling raise specificity by 1000.

  • <style> tag
  • <div style=""> attribute

5. Don’t use !important.

!important raises specificity to infinity. Only the last defined rule applies.

Reducing specificity

Do

  1. Use a CSS naming convention.
  2. Use nesting only for pseudo-classes and pseudo-elements.

Don’t

  1. Don’t use element qualification. Example: ol.breadcrumbs {}
  2. Don’t use IDs for styling. This raises specificity by 100.
  3. Don’t use inline <style> elements. This raises specificity by 1000.
  4. Don’t use inline <div style=""> attributes. This raises specificity by 1000.
  5. Don’t use !important. This raises specificity to infinity. Only the last rule defined applies.

Element qualification

Append an element suffix to the class name to clarify the markup pattern (not by qualifying the element type). This keeps specificity low, and improves selector performance.

// Good
.breadcrumbs-list {}

// Bad
ol.breadcrumbs {}

Selector specificity

<!-- Good -->
<header class="account-header">
    <nav class="account-header-nav">
        <a href="#" class="account-header-link">Account</a>
        <a href="#" class="account-header-link">Sign Out</a>
    </nav>
</header>

<!-- Bad -->
<header>
    <nav>
        <a href="#">Account</a>
        <a href="#">Sign Out</a>
    </nav>
</header>
// Good
.account-header {}
.account-header-nav {}
.account-header-link {}

// Bad
header {}
header nav {}
header nav a {}

Selectors

Class

ID

IDs and classes

Always avoid using an ID if possible.

!important

If you think it is, rewrite the rules being inherited with high specificity that are causing problems.

Never use !important to raise the specificity of a rule. In well architected CSS this should never be required.

// Bad
.something {
    color: #000 !important;
}

Resources