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
- Use a CSS naming convention.
- Use nesting only for pseudo-classes and pseudo-elements.
Don’t
- Don’t use element qualification. Example:
ol.breadcrumbs {}
- Don’t use IDs for styling. This raises specificity by 100.
- Don’t use inline
<style>
elements. This raises specificity by 1000. - Don’t use inline
<div style="">
attributes. This raises specificity by 1000. - 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;
}