ForHosting KIT · Web Scraping & Monitoring

CSS Selector Specificity Calculator

CSS specificity decides which competing declaration can win before source order and other cascade rules are considered.

● BetaFree · in your browser
Use it from WebAPIEmailTelegramApp soon

This calculator accepts one selector, validates its structure, and returns the familiar four-part count: inline styles, IDs, classes or attributes or pseudo-classes, and element types or pseudo-elements. It also applies the special rules for modern selectors such as :is(), :not(), :has(), :where(), and :nth-child(). Use it to explain an unexpected override, compare selectors during a refactor, or add a reliable specificity check to developer tooling.

Read the four-part specificity result

The result is reported as (inline, ID, class, type). The first position represents inline style declarations; because this tool receives a selector rather than an HTML style attribute, that value is always zero. The second position counts ID selectors such as <code>#checkout</code>. The third combines class selectors, attribute selectors, and pseudo-classes, so <code>.button</code>, <code>[disabled]</code>, and <code>:hover</code> each add one there. The fourth counts element type selectors and pseudo-elements, meaning <code>button</code> and <code>::before</code> each add one. Universal selectors and combinators add nothing. Compare the tuple from left to right, not by summing it into one decimal number: one ID outranks any number of classes, and one class outranks any number of types. The named fields make the output convenient for code, while the specificity array preserves the conventional visual form. Remember that specificity is only one part of the cascade. Origin, importance, cascade layers, scoping proximity, and source order can still determine the declaration that wins when you inspect a real page.

Understand functional pseudo-class rules

Modern functional pseudo-classes require more than simply counting every token. The pseudo-classes <code>:is()</code>, <code>:not()</code>, and <code>:has()</code> contribute the specificity of the most specific selector in their argument list; the wrapper itself adds no class count. In contrast, <code>:where()</code> always contributes zero, even when its argument contains an ID. This makes <code>:where()</code> useful for library defaults that should remain easy to override. The structural pseudo-classes <code>:nth-child()</code> and <code>:nth-last-child()</code> add one pseudo-class count, and an optional <code>of</code> selector list additionally contributes its most specific member. Other functional pseudo-classes add one class-level count, while pseudo-elements add one type-level count. The parser also recognizes relative selectors inside <code>:has()</code>, escaped identifier characters, attribute values containing punctuation, namespaces, and the legacy single-colon spellings of <code>:before</code>, <code>:after</code>, <code>:first-line</code>, and <code>:first-letter</code>. These distinctions match how authors reason about the selectors supported by current CSS rather than treating parentheses as opaque text.

Use validation to catch selector mistakes

A specificity number is useful only when the input is a plausible selector. The calculator therefore rejects missing fields, empty text, unfinished strings, unclosed brackets or parentheses, malformed combinators, missing identifiers after a dot or hash, and other structural errors instead of returning a confident but meaningless tuple. It accepts one selector at a time. A top-level comma creates a selector list whose members can have different specificity, so that input is rejected with a message asking for a single selector; calculate each member separately when comparing a rule list. The input length is bounded to keep execution predictable, and the algorithm uses no browser session, network request, random value, or clock. That makes identical inputs produce identical JSON in a local widget, an API call, a test suite, or a build check. Use the result as a focused diagnostic: compare the selectors involved, then inspect cascade layers, <code>!important</code>, inheritance, and source order if the specificity comparison alone does not explain the rendered style.

Debug a stubborn override

Compare competing selectors and see which specificity component causes one rule to outrank another.

Review stylesheet refactors

Check that a simplified selector reduces specificity without accidentally introducing an ID or extra pseudo-class weight.

Power developer tooling

Add deterministic selector validation and structured specificity counts to a linter, editor, or CI report.

What does the inline value mean?

It represents inline style declarations. It is always zero here because the input is a CSS selector, not an HTML style attribute.

Does :where() increase specificity?

No. :where() and its entire argument always contribute zero specificity, although the argument is still checked for valid selector structure.

How are :is(), :not(), and :has() counted?

They contribute the specificity of the most specific selector in their argument list; the functional pseudo-class wrapper adds nothing itself.

Can I submit a comma-separated selector list?

No. Submit each top-level selector separately because members of a selector list can have different specificity.

Does a higher specificity always win?

No. Cascade origin, importance, layers, scoping proximity, and source order may take precedence or break ties.

What does an API request cost?

Each API request costs $0.002. The browser version can run locally without sending the selector to a server.

Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.

POSThttps://api.kit.forhosting.com/web/css-specificity-calc

Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.

curl -X POST https://api.kit.forhosting.com/web/css-specificity-calc \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selector":"article#main.card[data-state='\''open'\'']:hover > h2::before"}'
{
  "selector": "article#main.card[data-state='open']:hover > h2::before"
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "web.css_specificity_calc",
  "status": "queued",
  "_links": {
    "result": "/tasks/tsk_…/result"
  }
}

The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

max_chars10000
HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

Read the full KIT documentation →