Ordinare i selettori CSS per specificità
La specificità CSS stabilisce quale dichiarazione in conflitto può prevalere prima di considerare l’ordine nel sorgente e l’importanza, ma confrontare a vista un lungo elenco di selettori è lento e soggetto a errori.
Esegui gratis nel browser
Questo strumento riceve singoli selettori CSS, ne convalida la sintassi, calcola per ciascuno il valore di specificità in tre parti e restituisce l’intero elenco in ordine crescente. Riconosce le moderne pseudo-classi funzionali come :is(), :not(), :has(), :where() e :nth-child() e, quando due selettori hanno lo stesso peso, ne conserva l’ordine originale.
Come leggere il punteggio di specificità in tre parti
Ogni risultato segue la consueta struttura ID, classi e tipi. Il primo numero conta i selettori ID come <code>#checkout</code>. Il secondo conta classi, selettori di attributo e pseudo-classi come <code>.active</code>, <code>[disabled]</code> e <code>:hover</code>. Il terzo conta selettori di tipo e pseudo-elementi come <code>button</code> e <code>::before</code>. I selettori universali e i combinatori non aggiungono punti. Il confronto è lessicografico: un solo ID supera qualsiasi quantità di voci nelle altre colonne, mentre una classe supera qualsiasi quantità di selettori di tipo quando il numero di ID coincide. L’array <code>specificity</code> è comodo per il software, mentre <code>specificity_text</code> mostra lo stesso valore in forma compatta e leggibile. I risultati sono ordinati in modo crescente: le regole più riutilizzabili appaiono per prime e i selettori più difficili da sovrascrivere per ultimi. Se due punteggi coincidono esattamente, lo strumento mantiene l’ordine di inserimento invece di introdurre un criterio alfabetico secondario. Questo comportamento stabile rende prevedibili le esecuzioni ripetute e conserva il contesto utile del foglio di stile o della lista di revisione.
Gestire correttamente le pseudo-classi moderne
Le pseudo-classi funzionali sono il punto in cui i calcoli manuali sbagliano più spesso. <code>:where()</code> contribuisce sempre con specificità zero, compresi i selettori al suo interno: Lei può quindi precisare la struttura senza rendere più difficile sovrascrivere una regola. Al contrario, <code>:is()</code>, <code>:not()</code> e <code>:has()</code> assumono la specificità dell’argomento più specifico, senza aggiungere un proprio punto di pseudo-classe. Le forme <code>:nth-child()</code> e <code>:nth-last-child()</code> aggiungono un punto di pseudo-classe più la specificità più alta di un eventuale elenco introdotto da <code>of</code>. Sono considerate anche forme dello shadow tree come <code>:host()</code> e <code>::slotted()</code>. Il parser attraversa parentesi annidate, parentesi quadre, stringhe tra virgolette ed escape, perciò non confonde le virgole interne a una funzione con quelle che separano selettori al livello principale. Fornisca ciascun elemento come singolo selettore. Una virgola al livello principale rappresenterebbe più selettori con punteggi potenzialmente diversi e viene quindi rifiutata, anziché ridotta a un unico valore fuorviante. Questa regola mantiene una corrispondenza esatta tra ogni input e un solo punteggio di output.
Semplificare la cascata con l’elenco ordinato
Un rapporto sulla specificità è più utile come guida al refactoring che come invito a creare selettori più forti. Incolli selettori rappresentativi di un componente, di un design system o di un foglio di stile legacy ed esamini la parte alta dei risultati. I grandi salti rivelano spesso ID, stati eccessivamente qualificati o un argomento potente nascosto in <code>:is()</code> o <code>:not()</code>. Questi selettori possono costringere il codice successivo a ripetere dettagli strutturali solo per sovrascrivere una dichiarazione. Valuti di sostituirli con una classe a scopo unico, alleggerire il contesto facoltativo con <code>:where()</code> oppure organizzare i layer affinché la precedenza non dipenda da punteggi crescenti. Anche la parte bassa è utile: regole sugli elementi e utility leggere sono più facili da riutilizzare quando il loro ruolo è chiaro. I processi automatici possono chiamare l’API a $0.002 per segnalare nuovi selettori oltre la soglia scelta dal team, registrare la specificità insieme al CSS generato o presentare diagnostica ordinata durante la revisione. Un input non valido fa fallire l’intera richiesta, così un rapporto parziale non nasconde mai un selettore malformato. Il calcolo è deterministico e non richiede la rete: a input uguali corrispondono sempre gli stessi valori e lo stesso ordine.
Casi d'uso
Verificare un foglio di stile legacy
Ordini i selettori per peso per individuare ID e regole molto qualificate che rendono difficili le normali sovrascritture.
Esaminare il CSS di un componente
Confronti i nuovi selettori con le convenzioni esistenti prima di integrare una modifica in un design system condiviso.
Applicare un limite di specificità
Calcoli i punteggi in un controllo automatico e segnali i selettori che superano il massimo scelto dal team.
Domande frequenti
Che cosa indica ogni numero della specificità?
I tre valori contano rispettivamente selettori ID, selettori assimilabili alle classi e selettori assimilabili ai tipi; vengono confrontati da sinistra a destra.
Come viene conteggiato :where()?
:where() e tutto ciò che si trova nel suo argomento contribuiscono con specificità zero, anche se la sintassi del selettore viene comunque convalidata.
Come vengono conteggiati :is(), :not() e :has()?
Ciascuno assume la specificità del selettore più specifico nell’elenco degli argomenti, senza aggiungere un punto di pseudo-classe.
Un elemento di input può contenere virgole?
Non al livello principale. Invii ogni selettore separatamente, perché i membri di un elenco possono avere specificità diverse. Sono ammesse le virgole annidate nelle pseudo-classi funzionali supportate.
Che cosa accade se due selettori hanno la stessa specificità?
Viene mantenuto il loro ordine di input originale, per un ordinamento stabile e deterministico.
Quanto costa una richiesta API?
Ogni richiesta costa $0.002. La versione per browser viene eseguita localmente e gratuitamente.
Per sviluppatori — accesso via API
Tutto quello che vedi in questa pagina è disponibile anche via API. Questa sezione è per i team che vogliono integrarlo nei propri sistemi; chi non ne ha bisogno può semplicemente usare lo strumento qui sopra.
Endpoint
Autenticazione con Bearer token: un POST mette in coda l'attività e il risultato arriva via webhook o link firmato.
Chiamala dal tuo stack
curl -X POST https://api.kit.forhosting.com/web/css-specificity-sort \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"selectors":["button",".toolbar button:hover","#app .toolbar button"]}'const res = await fetch("https://api.kit.forhosting.com/web/css-specificity-sort", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"selectors": [
"button",
".toolbar button:hover",
"#app .toolbar button"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/css-specificity-sort",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"selectors": [
"button",
".toolbar button:hover",
"#app .toolbar button"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/css-specificity-sort", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"selectors":["button",".toolbar button:hover","#app .toolbar button"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"selectors":["button",".toolbar button:hover","#app .toolbar button"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/css-specificity-sort", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Esempio di richiesta
{
"selectors": [
"button",
".toolbar button:hover",
"#app .toolbar button"
]
}Esempio di risposta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.css_specificity_sort",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}L'API è asincrona: ricevi subito un task_id e puoi fare polling fino a 1 richiesta al secondo.
Prezzi
Prezzo pubblicato, senza token né crediti. Se l'attività fallisce, non paghi.
Limiti
max_items | 1000 |
max_selector_length | 4096 |
Errori
| HTTP | Codice | Significato |
|---|---|---|
401 | unauthorized | Chiave API mancante o non valida: controlla l'header Authorization. |
402 | insufficient_balance | Credito esaurito: ricarica per continuare a eseguire attività. |
404 | unknown_type | Tipo di attività sconosciuto: controlla il campo type della richiesta. |
429 | rate_limited | Troppe richieste in poco tempo: rallenta e riprova tra qualche secondo. |