Jomatter

CSS Specificity Calculator

Calculate CSS selector specificity instantly. Analyze IDs, classes, attributes, pseudo-classes, and elements, compare selectors, and inspect detailed specificity scores.

CSS Selector Input

0 characters
0 selectors

Specificity Results

Enter one or more CSS selectors and calculate their specificity.

Compare Selectors

—
—

How specificity works

Specificity compares the selector-based weight of applicable CSS rules. The tuple is read left to right: IDs first, then classes, attributes and pseudo-classes, then types and pseudo-elements. Combinators and the universal selector * contribute zero, and :where() always contributes zero. :is(), :not() and :has() use the highest specificity among their argument selectors. !important is not an extra specificity component, and inline style attributes are not part of the three-component selector tuple. Cascade layers, cascade origin, scope and source order can affect the winning declaration independently of selector specificity, and equal specificity does not automatically mean one rule wins.

Loading the CSS selector engine…

All Developer Tools

Browse free online tools for JSON, HTML, CSS, XML, JavaScript, data conversion, and everyday development tasks.

50 tools

What Is CSS Specificity?

CSS specificity is the weight assigned to a CSS selector that helps the browser determine which declaration should apply when competing CSS rules target the same element and set the same property. Understanding specificity makes it easier to debug styling conflicts, maintain consistent designs, and understand why one rule overrides another.

For example, a paragraph might receive its text color from a general element selector, a class selector, and an ID selector. When the declarations compete under the same cascade conditions, the browser compares their specificity to determine which one takes precedence.

Jomatter's CSS Specificity Calculator helps you calculate selector weights, compare multiple CSS selectors, and understand how IDs, classes, attributes, pseudo-classes, elements, and pseudo-elements contribute to a selector's specificity.

Instead of manually counting each selector component, use the calculator to examine the specificity score and identify which selector has the higher weight. This is useful when working with complex stylesheets, reusable components, CSS frameworks, and legacy code.

Example of a Specificity Conflict

p { color: gray; } .card p { color: blue; } #main p { color: red; }

All three rules can target a paragraph inside an element with the ID main and the class card. Assuming they declare the same property and no other cascade rule changes the outcome, the #main p selector wins because its specificity is higher.

Key point: Specificity is one part of the CSS cascade. Origin, importance, cascade layers, and source order can also affect which declaration wins. A higher specificity score does not automatically win in every possible cascade situation.

How to Calculate CSS Specificity Online

Calculating CSS specificity is easier when you separate a selector into its individual components. Follow these steps to compare selectors and understand their relative weights.

1
Enter a CSS selector

Paste a selector into the calculator, such as .card p, #header .nav, or article h2::before.

2
Add other selectors for comparison

Enter additional selectors if you need to compare multiple rules. Depending on the tool, you can separate selectors using new lines or commas.

3
Review the specificity score

Check the calculated specificity tuple, commonly displayed as (A, B, C), where A represents IDs, B represents classes and similar selectors, and C represents elements and pseudo-elements.

4
Inspect each selector component

Identify how many ID selectors, classes, attribute selectors, pseudo-classes, elements, and pseudo-elements contribute to the score.

5
Compare selectors from left to right

Compare the A values first. If they are equal, compare B. If B is also equal, compare C. The first column that differs determines which selector has greater specificity.

6
Review the complete CSS cascade

When you are debugging a real styling conflict, also check importance, cascade layers, inline styles, selector matching, and source order before deciding why a declaration wins.

A specificity calculator helps explain selector weight, but the score alone does not show every factor that affects the final rendered style. Use it alongside your stylesheet and browser developer tools when troubleshooting a difficult cascade conflict.

How CSS Specificity Is Calculated

CSS selector specificity is commonly represented by three values: (A, B, C). Each value represents a different group of selector components. The browser compares the tuple from left to right rather than adding every component into a single ordinary number.

ID Selectors

The first value counts ID selectors, such as #header, #main, and #footer. Each ID selector adds one to the A column.

#main Specificity: (1, 0, 0) #main #header Specificity: (2, 0, 0)

Classes, Attributes, and Pseudo-Classes

The second value counts class selectors, attribute selectors, and ordinary pseudo-classes. Examples include .card, [type="email"], :hover, and :focus.

.card Specificity: (0, 1, 0) .card:hover Specificity: (0, 2, 0) input[type="email"]:focus Specificity: (0, 2, 1)

Elements and Pseudo-Elements

The third value counts type selectors and pseudo-elements. Examples include div, p, h1, ::before, and ::after.

p Specificity: (0, 0, 1) article p Specificity: (0, 0, 2) article p::before Specificity: (0, 0, 3)

How comparison works: The tuple (1, 0, 0) is greater than (0, 20, 20) because its ID column is higher. Specificity columns are compared lexicographically, not by treating the tuple as a normal decimal number.

CSS Selector Types and Their Specificity

Different selector types contribute to different parts of a specificity score. Recognizing these categories helps you calculate selector weights accurately.

Selector Type Example Contribution
ID selector #header One point in A
Class selector .card One point in B
Attribute selector [type="text"] One point in B
Pseudo-class :hover One point in B
Element selector div One point in C
Pseudo-element ::before One point in C
Universal selector * No contribution
Combinator >, +, ~ No contribution
Descendant combinator Whitespace No contribution
:where() :where(.card) Zero, including its arguments

For example, the selector #main .card p:hover contains one ID, one class, one element, and one pseudo-class. Its specificity is (1, 2, 1).

Combinators describe relationships between elements rather than contributing selector weight. Therefore, adding a descendant space or child combinator does not increase specificity by itself.

CSS Specificity Examples

Review the following examples to see how different selector combinations produce different specificity scores. Each score counts the relevant selector components in the A, B, and C columns.

CSS Selector Specificity Breakdown
* (0, 0, 0) Universal selector adds no specificity.
p (0, 0, 1) One element selector.
.card (0, 1, 0) One class selector.
#header (1, 0, 0) One ID selector.
.card:hover (0, 2, 0) One class and one pseudo-class.
nav a (0, 0, 2) Two element selectors.
#header .nav a (1, 1, 1) One ID, one class, and one element.
input[type="email"] (0, 1, 1) One attribute selector and one element.
ul li.active (0, 1, 2) One class and two elements.
#app .card:hover > h2::before (1, 2, 2) One ID, one class, one pseudo-class, one element, and one pseudo-element.
:where(.card) (0, 0, 0) :where() and its arguments add no specificity.
:is(#header, .card) (1, 0, 0) Uses the most specific argument, #header.

Example: Combining Selector Types

#main .card h2:hover::before

The selector contains one ID, one class, one pseudo-class, one element selector, and one pseudo-element. Its specificity is:

(1, 2, 2)

  • A = 1: #main
  • B = 2: .card and :hover
  • C = 2: h2 and ::before

Counting the selector components individually makes even long selectors easier to understand. It also helps you find opportunities to simplify selectors that have more specificity than necessary.

How to Compare CSS Selectors

When two or more CSS selectors target the same element and set the same property, specificity helps determine which declaration takes precedence, provided the declarations are otherwise comparable in the cascade.

Example 1: Element vs. Class Selector

p { color: gray; } .card { color: blue; }
Selector Specificity
p (0, 0, 1)
.card (0, 1, 0)

When both declarations apply to the same paragraph and are otherwise equal in the cascade, the class selector has higher specificity than the element selector. The text appears blue.

Example 2: Multiple Classes vs. an ID

.a.b.c.d { color: blue; } #main { color: red; }
Selector Specificity
.a.b.c.d (0, 4, 0)
#main (1, 0, 0)

The ID selector has greater specificity because the A column is compared first. One ID selector outweighs any number of class selectors in the specificity comparison.

Example 3: Equal Specificity

.card { color: blue; } .panel { color: green; }

Both selectors have specificity (0, 1, 0). If both declarations participate in the same cascade conditions and no other factor gives one priority, the later declaration wins. In this example, an element matching both selectors receives green text.

Debugging tip: When two declarations appear to conflict, compare their cascade origin and importance first, then consider cascade layers and specificity. If those factors are equal, source order can determine the winner.

Understanding :is(), :not(), :has(), and :where()

Modern CSS includes functional pseudo-classes with special specificity rules. These selectors can affect how a rule competes with other declarations, so treating every pseudo-class as a simple point in the B column can produce incorrect calculations.

The :is() Pseudo-Class

The :is() pseudo-class takes the specificity of the most specific selector in its argument list. The specificity of :is() itself is not added separately.

:is(#header, .card, p)

Specificity: (1, 0, 0)

The ID selector #header contributes the highest specificity among the arguments.

The :not() Pseudo-Class

The :not() pseudo-class takes the specificity of the most specific selector in its argument list. The pseudo-class itself does not add another point.

.card:not(#featured)

Specificity: (1, 1, 0)

The selector contains one class and an argument with one ID. The ID contribution comes from #featured.

The :has() Pseudo-Class

The :has() pseudo-class takes the specificity of the most specific selector in its argument list. It can match an element based on the presence of related elements or relationships that satisfy the supplied relative selector.

article:has(#featured)

Specificity: (1, 0, 1)

The ID inside :has() contributes to the A column, and the article element contributes to the C column.

The :where() Pseudo-Class

The :where() pseudo-class always has zero specificity, including when its argument contains IDs, classes, or other selectors with otherwise high specificity.

:where(#header, .card, article)

Specificity: (0, 0, 0)

This behavior makes :where() useful for applying baseline styles without increasing the specificity that other selectors must overcome.

Compare :is() and :where()

Selector Specificity Reason
:is(#app, .card) (1, 0, 0) Uses the most specific argument.
:where(#app, .card) (0, 0, 0) Always contributes zero specificity.
section:not(.active) (0, 1, 1) One element and the class argument.
main:has(> img) (0, 0, 2) The main element and the img argument contribute.

These rules apply to the relevant functional pseudo-classes themselves. A selector can still contain additional IDs, classes, attributes, pseudo-classes, elements, or pseudo-elements outside the function, and those components contribute normally.

Inline Styles, !important, and the CSS Cascade

Specificity is important, but it is not the only factor that determines which CSS declaration wins. The cascade also considers origin, importance, cascade layers, and other precedence rules before specificity and source order settle comparable declarations.

Inline Styles

An inline style is written directly on an HTML element using the style attribute.

<p style="color: red;"> This is a paragraph. </p>

Inline styles generally take precedence over normal author stylesheet declarations for the same property. However, other cascade rules, such as important declarations, can change the outcome. Inline styling is not simply another class or ID in the ordinary three-column specificity calculation.

The !important Declaration

The !important annotation gives a declaration important status within the CSS cascade.

.card { color: blue !important; } #main .card { color: red; }

In this example, the blue declaration is important while the red declaration is normal. The important declaration wins despite the other selector having higher specificity, assuming no higher-priority important declaration changes the result.

!important does not add to the selector's specificity score. It changes declaration priority in the cascade.

Cascade Layers

CSS cascade layers, declared with @layer, provide a way to organize style rules into groups and control precedence between them. For normal declarations, later layers have priority over earlier layers, and normal unlayered author styles take precedence over normal layered author styles.

@layer base, components; @layer base { #main { color: blue; } } @layer components { p { color: green; } }

For normal declarations in this example, the rule in the later components layer takes precedence over the rule in the earlier base layer, even though the ID selector is more specific. The rules are in different layers, so layer precedence is resolved before specificity.

The ordering of important declarations across cascade layers works in the reverse layer order. Important declarations in earlier layers have priority over important declarations in later layers. Unlayered important declarations also follow the cascade's special layer ordering.

Best practice: Avoid using !important as the default solution for every styling conflict. Check which declarations match the element, review the cascade and layer order, and simplify unnecessarily specific selectors where practical.

Common CSS Specificity Mistakes

Misunderstanding selector weights can make stylesheets harder to maintain. Recognizing common mistakes helps you write simpler CSS and troubleshoot conflicting declarations more efficiently.

1. Assuming More Classes Beat an ID

Many class selectors do not automatically outweigh an ID selector. The browser compares the specificity columns from left to right.

.a.b.c.d.e { color: blue; } #main { color: red; }

Result: The ID selector has higher specificity when the declarations are otherwise comparable in the cascade.

2. Counting Combinators as Specificity

Combinators express relationships between elements but do not add specificity.

.card > p .card p

Both selectors have specificity (0, 1, 1). The child combinator and descendant space do not contribute to the score.

3. Treating :where() Like :is()

The functional pseudo-classes have different specificity behavior. :is() takes the maximum argument specificity, while :where() always contributes zero.

:is(#main, .card) /* (1, 0, 0) */ :where(#main, .card) /* (0, 0, 0) */

4. Assuming !important Adds Specificity

!important changes a declaration's importance in the cascade. It does not add another point to the A, B, or C specificity columns.

5. Ignoring Source Order

When declarations have the same relevant cascade priority and specificity, source order can decide the winner. The later matching declaration takes precedence.

.button { color: blue; } .button { color: green; }

With otherwise equal cascade conditions, the later declaration sets the color to green.

6. Nesting Selectors Too Deeply

Long selectors can accumulate unnecessary specificity and become difficult to override.

#main .sidebar .widget .title a:hover

Use a simpler selector when possible, especially when styling reusable components.

7. Assuming Specificity Explains Every Conflict

A declaration can lose even when its selector has higher specificity because the competing rule has different importance, origin, or cascade-layer priority. Check those factors before comparing selector weight alone.

8. Confusing Pseudo-Classes and Pseudo-Elements

Ordinary pseudo-classes such as :hover contribute to B, while pseudo-elements such as ::before contribute to C. Functional pseudo-classes such as :is() and :has() have their own special rules.

A CSS specificity calculator helps expose these mistakes by breaking selectors into their contributing parts. Combined with a good understanding of the cascade, it makes CSS conflicts easier to diagnose and fix.

How to Reduce CSS Specificity

When stylesheet rules become difficult to override, lowering unnecessary specificity can make a codebase easier to maintain. The goal is not to make every selector as weak as possible, but to use the least complicated selector that expresses the intended styling relationship.

Prefer Classes for Reusable Components

Classes are useful for styling reusable components without creating the strong coupling associated with IDs.

/* More tightly coupled */ #main .sidebar .widget-title { color: #171E2B; } /* Simpler component class */ .widget-title { color: #171E2B; }

The class-based selector is easier to reuse and has lower specificity. Choose the appropriate selector based on your component structure rather than relying on IDs unnecessarily.

Use :where() for Low-Specificity Defaults

The :where() pseudo-class can apply baseline styles while keeping specificity at zero for the function and its arguments.

:where(.article, .sidebar) h2 { margin-bottom: 1rem; }

The selector's specificity is (0, 0, 1) because :where(.article, .sidebar) adds zero and the trailing h2 contributes one element point.

Avoid Unnecessary Selector Chains

Excessive nesting can make components harder to override, especially in large applications or shared design systems.

/* More complex */ .page .content .card .title { color: #171E2B; } /* Simpler */ .card-title { color: #171E2B; }

A dedicated component class can express the intended styling more directly and reduce the risk of conflicts with other stylesheet rules.

Refactoring tip: Before simplifying a selector, confirm which elements it matches and whether the selector is intentionally scoped. Lower specificity should improve maintainability without changing the intended appearance of the page.

CSS Specificity Calculator Best Practices

Use a consistent process when calculating selector specificity or debugging stylesheet conflicts. The following practices help prevent incorrect conclusions and reduce unnecessary complexity.

  • Count each selector component: Identify IDs, classes, attributes, pseudo-classes, elements, and pseudo-elements.
  • Compare tuples from left to right: Start with A, then compare B if A is equal, and C if both preceding values are equal.
  • Remember zero-specificity selectors: The universal selector and combinators contribute nothing, and :where() always adds zero.
  • Apply functional pseudo-class rules correctly: :is(), :not(), and :has() use the most specific selector in their argument list.
  • Check the complete cascade: Review origin, importance, cascade layers, specificity, and source order.
  • Use browser developer tools: Inspect the element's matched CSS declarations to see which rules apply and which declarations are overridden.
  • Keep selectors maintainable: Prefer understandable component classes over unnecessarily long selector chains.
  • Use !important sparingly: Resolve conflicts through clearer selector structure and layer organization where possible.
  • Test after refactoring: Confirm that simplifying selectors does not accidentally change the intended styling of other elements.
  • Consider cascade layers: Organize large stylesheets with intentional layer ordering instead of relying exclusively on increasingly high specificity.

Specificity is easier to manage when stylesheet rules are predictable, reusable, and organized. Use the calculator to understand selector weight, then verify the final result in the context of the complete CSS cascade.

Frequently Asked Questions

What is a CSS specificity calculator?

A CSS specificity calculator is an online tool that calculates the specificity of CSS selectors and helps you compare their relative weights. It can show how IDs, classes, attributes, pseudo-classes, elements, and pseudo-elements contribute to a selector's score.

How is CSS specificity calculated?

Specificity is commonly displayed as a three-part tuple, (A, B, C). A counts ID selectors, B counts classes, attribute selectors, and ordinary pseudo-classes, and C counts element selectors and pseudo-elements. The values are compared from left to right.

What does a specificity score of (1, 2, 1) mean?

The score (1, 2, 1) means the selector contains one ID selector, two class-like contributions, and one element-like contribution. For example, #main .card:hover p has this specificity.

Does an ID selector beat multiple class selectors?

Yes. One ID selector has greater specificity than any number of class selectors. The browser compares the ID column before comparing the class column, so #main outranks a selector such as .a.b.c.d.e when cascade priority is otherwise equal.

Do combinators add specificity?

No. Combinators such as the descendant space, child combinator (>), adjacent sibling combinator (+), and general sibling combinator (~) do not contribute to specificity. The selector components on either side still contribute normally.

Does the universal selector add specificity?

No. The universal selector (*) contributes zero specificity. Adding it to a selector does not increase the selector's A, B, or C values.

Does :hover increase CSS specificity?

Yes. The :hover pseudo-class contributes one point to the B column. Other ordinary pseudo-classes, such as :focus and :first-child, also contribute to B.

Does ::before increase specificity?

Yes. The ::before pseudo-element contributes one point to the C column, as do other pseudo-elements such as ::after.

What is the specificity of :is()?

The :is() pseudo-class takes the specificity of the most specific selector in its argument list. For example, :is(#header, .card) has specificity (1, 0, 0) because the ID selector is the most specific argument.

What is the specificity of :not()?

The :not() pseudo-class takes the specificity of its most specific argument. The pseudo-class itself does not add another point. Other selector components outside the function still contribute normally.

What is the specificity of :has()?

The :has() pseudo-class takes the specificity of the most specific selector in its argument list. Any elements or other selectors outside the function contribute according to the usual rules.

What is the specificity of :where()?

The :where() pseudo-class always has zero specificity, including when its arguments contain IDs, classes, or elements. Selectors outside the function still contribute normally.

Does !important increase specificity?

No. The !important annotation changes a declaration's importance in the cascade rather than increasing its selector specificity. An important declaration can override a normal declaration even when the normal declaration has a more specific selector, subject to the cascade's priority rules.

Do inline styles have higher specificity than ID selectors?

Inline styles are handled specially in the cascade and generally take precedence over normal author stylesheet rules for the same property. They are often represented separately from the ordinary three-column specificity tuple. Important declarations and other cascade rules can change which declaration wins.

What happens when two selectors have equal specificity?

If the declarations have the same relevant cascade priority and specificity, the one that comes later in source order wins. However, rules involving different origins, importance levels, or cascade layers must be resolved according to the cascade before source order is considered.

Can a less specific selector override a more specific selector?

Yes, when another cascade factor gives it priority. For example, cascade-layer precedence can allow a less specific normal declaration in a later layer to override a more specific normal declaration in an earlier layer. Importance and origin can also change the outcome.

What are CSS cascade layers?

Cascade layers are groups of CSS rules created with @layer. For normal declarations, later layers take precedence over earlier layers, and normal unlayered author rules take precedence over layered author rules. Important declarations use a reversed layer ordering.

Why is my CSS rule not applying even though it has higher specificity?

Specificity is not the only factor in the cascade. Check whether the selector matches the element, whether another declaration has higher importance or origin priority, whether cascade layers differ, and whether the competing rule applies to the same property.

How can I reduce CSS specificity?

Use simpler selectors, avoid unnecessary ID selectors, reduce deep nesting, and consider reusable component classes. The :where() pseudo-class can help apply baseline styles with zero specificity. Test your changes to ensure the intended elements remain styled correctly.

Can I compare multiple CSS selectors at once?

A calculator with multiple-selector support can compare several selectors and show their individual specificity scores. This is useful when debugging competing rules or reviewing a stylesheet for unnecessarily complex selectors.

Is CSS specificity the same as selector length?

No. Selector length does not determine specificity by itself. A short ID selector can outweigh a much longer selector containing many classes and elements because the specificity columns are compared from left to right.

Calculate CSS Specificity and Fix Styling Conflicts

CSS specificity plays an important role in keeping styles predictable when multiple rules target the same element. Understanding how IDs, classes, attributes, pseudo-classes, elements, and pseudo-elements contribute to selector weight makes it easier to debug overrides and maintain clean stylesheets.

Use Jomatter's CSS Specificity Calculator to examine individual selectors, compare competing rules, and identify which selector has the higher specificity score. When a styling conflict persists, also review importance, cascade layers, inline styles, and source order to determine the actual reason a declaration wins.

For maintainable CSS, prefer clear and reusable selectors over unnecessarily complex combinations. Calculate specificity when debugging a conflict, simplify selectors when appropriate, and test your changes to ensure the intended design remains consistent across your website.

Ready to check your selectors? Enter one or more CSS selectors into the calculator, review their specificity scores, and compare the results to understand how selector weight affects your styles.