Enter two selectors to quickly compare their priority
Click a preset below to quickly see the specificity of common selectors
CSS specificity is the scoring system browsers use to decide which CSS rule wins when multiple rules target the same element. It is represented as a triplet (a, b, c):
#nav) adds 1 to a.active), attribute ([type="text"]), or pseudo-class (:hover) adds 1 to bdiv) or pseudo-element (::before) adds 1 to cWhen comparing, a higher a wins. If a is tied, the higher b wins. If b is also tied, the higher c wins. If all are equal, the later declaration wins (cascade).
Special rules:Universal selector * has zero weight. Combinators (>, +, ~) do not affect weight. :not() itself has zero weight, but selectors inside its parentheses do count.
This CSS specificity calculator is a practical debugging tool for frontend developers. Here is a detailed guide:
Calculate a single selector:Type any valid CSS selector (e.g., #nav .menu li a:hover) into the input field and click Calculate. The tool immediately parses the selector and displays its (a,b,c) triplet and total score. The breakdown shows the exact count of ID selectors, class selectors, and tag selectors so you can understand where the priority comes from.
Compare two selectors:When you are unsure which of two selectors has higher priority, enter them in the Selector Comparison section (for example, A: #header .nav, B: header .nav) and click Compare. The tool highlights the winner so you can instantly see the decisive impact of an ID selector on overall weight.
Use preset examples:If you are new to CSS, click any button under Common Selector Examples to quickly experience how different types of selectors affect specificity. These presets cover attribute selectors, pseudo-classes, pseudo-elements, and complex combinators.
Debugging style override issues:The most common reason styles do not apply is insufficient selector specificity. Use this tool to quickly calculate the specificity of conflicting selectors and identify the root cause. For example, when an element is matched by both .card .title (0,2,0) and .card-title (0,1,0), the former wins because its score is higher.
Code review and refactoring:During team code reviews, selector specificity is an important checkpoint. Over-reliance on ID selectors or deep nesting reduces reusability and maintainability. By quantifying each selector's weight, teams can enforce consistent CSS coding standards, such as banning ID selectors or limiting nesting depth to three levels.
Learning CSS priority:For beginners, specificity is an abstract concept. This tool breaks selectors down into ID, class, and tag dimensions and displays weights numerically, making the concept much easier to grasp. Combined with the preset examples, students can visually see how different selector types affect priority.
Cascade vs. Inheritance:Many developers confuse cascade and inheritance. Cascade is the process by which the browser decides which rule applies when multiple rules match the same element, based on origin (author, user, browser default), specificity, and declaration order. Inheritance is when certain properties (like color and font-family) are automatically passed from parent to child elements. They are different dimensions of CSS behavior.
BEM naming convention:BEM (Block Element Modifier) is a CSS naming methodology that scopes styles within a single class selector using names like .block__element--modifier. This naturally avoids specificity arms races because under BEM almost every selector has a weight of (0,1,0).
Modern CSS pseudo-classes :where() and :is():Modern CSS introduces :where() and :is(). :is() counts the specificity of its arguments, while :where() always has zero specificity. This means you can write complex selector combinations with :where() without increasing weight, making it a powerful tool for solving specificity issues.
CSS specificity is the mechanism browsers use to determine which CSS rule applies when multiple rules target the same element. It is represented as a triplet (a,b,c): a counts ID selectors, b counts class/attribute/pseudo-class selectors, and c counts tag/pseudo-element selectors.
!important is the highest-priority declaration modifier in CSS. It overrides any selector specificity. However, !important declarations also have their own cascade: a later !important declaration overrides an earlier one. Overusing !important leads to maintenance issues and should be avoided.
Inline styles (the style attribute) have higher priority than any selector combination. In the (a,b,c) model, inline styles are invisible but outrank all selectors, second only to !important declarations.
Best practices to reduce specificity: 1. Prefer class selectors over ID selectors; 2. Avoid deep nesting (e.g., .nav .list .item a); 3. Use naming conventions like BEM; 4. Avoid !important; 5. Use CSS custom properties for shared styles.
No. Pseudo-classes (like :hover, :nth-child) have the same weight as class selectors (counted in b). Pseudo-elements (like ::before, ::after) have the same weight as tag selectors (counted in c). Note that CSS3 pseudo-elements use double colons ::.
The universal selector * has a weight of zero and does not affect specificity calculations. However, it still matches all elements on the page, which is why it is widely used in reset stylesheets.
The :not() pseudo-class itself has zero weight, but the selectors inside its parentheses are counted normally. For example, :not(.active) has a weight of (0,1,0) because only .active is counted.
In CSS, selector specificity takes precedence over declaration order. Even if a style is written later, if an earlier selector has higher specificity, the earlier style will still apply. The later rule only wins when specificity is equal.