TTKTheTextKit

CSS Specificity Calculator

Type one or more CSS selectors, one per line, and see the specificity score of each as three numbers: ids, classes and types. A breakdown shows what each part of the selector adds, and when you enter several selectors the highest-scoring one is marked, so you can see which rule wins. Everything runs in your browser.

ul li.red
0,1,2
PartCounts asWhy
ulTypesA type selector
liTypesA type selector
.redClassesA class selector
#nav a:hover
Highest1,1,1
PartCounts asWhy
#navIDsAn id selector
aTypesA type selector
:hoverClassesA pseudo-class
.menu > .item:not(.off)
0,3,0
PartCounts asWhy
.menuClassesA class selector
.itemClassesA class selector
:not(.off)No change:not() takes the most specific selector inside it: 0,1,0

Specificity decides which rule wins when two rules set the same property on the same element. It is a score of three numbers, written (a, b, c) and compared from left to right: a counts id selectors, b counts class selectors, attribute selectors and pseudo-classes, and c counts type selectors and pseudo-elements. The universal selector and combinators add nothing. :where() always counts as zero, while :is(), :not() and :has() count as their most specific argument, and :nth-child() counts as one pseudo-class plus the most specific selector after "of". Inline styles, !important and cascade layers are decided before specificity and are not part of this score. Everything is worked out in your browser and nothing is uploaded.

Related Tools

[5 suggestions]

About the CSS Specificity Calculator

Specificity decides which rule applies when several rules set the same property on the same element and none is marked more important. It is a score of three numbers, written (a, b, c) and compared from left to right, so one id beats any number of classes. The first number counts id selectors. The second counts class selectors, attribute selectors and pseudo-classes such as :hover. The third counts type selectors such as li and pseudo-elements such as ::before. The universal selector and the combinators (space, >, + and ~) add nothing. The tool follows Selectors Level 4: :where() always counts as zero, :is(), :not() and :has() count as the most specific selector in their list, and :nth-child() and :nth-last-child() count as one pseudo-class plus the most specific selector after the word of. The older single-colon forms of :before, :after, :first-line and :first-letter are counted as pseudo-elements. Commas inside functions and quoted attribute values do not split the list, and comments are ignored. For example, ul li.red scores 0,1,2, #nav a:hover scores 1,1,1 and .menu > .item:not(.off) scores 0,3,0. Inline styles, the !important flag, cascade layers and rule order are settled before or after specificity and are not part of this score, and the nesting selector & takes the score of its parent rule, which the tool cannot see. Nothing is uploaded.

How is CSS specificity calculated?▾

Count the id selectors, then the class, attribute and pseudo-class selectors, then the type selectors and pseudo-elements. Write them as three numbers, such as 1,0,2, and compare from left to right. A selector with more ids always wins, whatever the other numbers are.

Does :where() or :is() change specificity?▾

Yes. :where() always counts as zero, which makes it useful for base styles that are easy to override. :is() and :not() count as the most specific selector inside them, so :is(.a, #b) scores like #b.

Which wins when two selectors have the same specificity?▾

The one that comes later in the stylesheet. Specificity is checked first, and source order only breaks a tie. Rules marked !important and rules in a later cascade layer are considered before specificity.

Do inline styles count?▾

An inline style beats any selector, because it sits above the ids in the cascade. It is not part of the (a, b, c) score of a selector, so this tool does not include it.

Does the tool read my stylesheet?▾

No. It scores only the selectors you type, in your browser, and nothing is uploaded.