CSS :scope Pseudo Classe
La pseudo-classe CSS :scope rappresenta gli elementi di scope. Scopri come funziona e pratica con esempi.
La pseudo-classe CSS :scope corrisponde all'elemento rispetto al quale un selettore viene risolto — il suo elemento di riferimento. Nelle normali query DOM, l'elemento di riferimento è quello su cui si chiama il metodo di query; all'interno di uno Shadow DOM è la shadow root.
Questa pagina spiega cosa significa "scope" per un selettore, perché :scope è principalmente uno strumento JavaScript piuttosto che uno strumento per i fogli di stile, i due contesti principali in cui cambia comportamento e le insidie da tenere presenti.
Cos'è l'elemento di riferimento
Ogni selettore viene abbinato in relazione a un elemento. Quando scrivi CSS in un foglio di stile, l'elemento di riferimento è la radice del documento, quindi :scope lì è equivalente a :root e raramente è utile da solo.
:scope diventa significativo quando l'elemento di riferimento non è la radice — soprattutto quando si interroga il DOM da JavaScript:
element.querySelector(selector)eelement.querySelectorAll(selector)risolvono il selettore rispetto aelement. Qui:scopefa riferimento aelementstesso.- I metodi di query di un
ShadowRootusano la shadow root come elemento di riferimento.
Senza :scope, un selettore passato a element.querySelector() viene comunque abbinato all'intero sottoalbero, non ancorato a element. Questo sorprende molti sviluppatori — vedi l'insidia descritta di seguito.
Perché usarlo
Il motivo principale per cui si ricorre a :scope è ancorare un selettore all'elemento che si sta interrogando, così da poter selezionare figli diretti o esprimere "relativo a questo punto":
// Match only sections that are direct children of container.
container.querySelectorAll(':scope > section');:scope è significativo nei metodi di query elencati sopra (querySelector, querySelectorAll e il controllo live Element.matches()). Non ha effetti speciali in closest() né nelle normali regole dei fogli di stile.
Nota: il vecchio attributo <style scoped>, che un tempo permetteva a un blocco <style> di applicarsi solo all'interno del proprio elemento padre, è stato rimosso dai browser. Lo scoping degli stili si realizza oggi con Shadow DOM (o strumenti di build), e :scope sopravvive come helper per le query DOM.
Versione
Sintassi
In un foglio di stile la sintassi è uguale a quella di qualsiasi altra pseudo-classe:
:scope {
/* declarations — equivalent to :root in a normal stylesheet */
}In JavaScript viene passato all'interno della stringa del selettore:
element.querySelectorAll(':scope > .child');Esempio: ancorare una query al suo elemento
Nell'esempio seguente, container.querySelector(':scope > section') seleziona solo il <section> che è un figlio diretto di .container. La sezione trovata viene ricolorata per confermare che la query l'ha individuata.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.container {
margin: 40px auto;
max-width: 700px;
background-color: #eeeeee;
padding: 20px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.25);
}
section {
padding: 30px;
}
</style>
</head>
<body>
<h2>:scope selector example</h2>
<div class="container">
<section>
<p>
Inside the scope.
</p>
</section>
</div>
<script>
const container = document.querySelector('.container');
const scopeElement = container.querySelector(':scope > section');
scopeElement.style.backgroundColor = '#1c87c9';
scopeElement.style.color = '#fff';
</script>
</body>
</html>Insidia comune: selezionare i figli diretti
Il motivo più comune per usare :scope è selezionare i figli immediati dell'elemento che si sta interrogando. Un combinatore come > .x non può stare da solo — element.querySelector('> .x') genera un SyntaxError. È necessario un lato sinistro, e :scope lo fornisce:
<ul id="list">
<li>A</li>
<li>
<ul>
<li>B (nested)</li>
</ul>
</li>
</ul>const list = document.getElementById('list');
// SyntaxError — "> li" is not a complete selector:
// list.querySelectorAll('> li');
// Correct: only the direct <li> children of #list (A and the one wrapping the nested list),
// NOT "B (nested)".
list.querySelectorAll(':scope > li');Senza :scope, list.querySelectorAll('li') restituirebbe anche l'elemento nidificato B, perché un semplice selettore discendente raggiunge l'intero sottoalbero. :scope > è il modo idiomatico per dire "figli diretti dell'elemento che sto interrogando."
Supporto browser
:scope è supportato in tutti i browser moderni per i metodi di query DOM. Non ha alcun effetto come regola di stile in un foglio di stile normale al di là di comportarsi come :root.
Capitoli correlati
- CSS Selectors — il riferimento completo ai selettori.
- CSS Selector — le basi della sintassi dei selettori.