Modifiche all'eredità per lo stile di selezione CSS

Stephen Chenney
Stephen Chenney

Data di pubblicazione: 8 ottobre 2024

Da Chrome 131, l'ereditarietà delle evidenziazioni CSS verrà modificata per ::selection e ::target-text pseudo-classi. Questo serve a creare un modello più intuitivo ereditarietà ed allinearsi con i ::highlight, ::spelling-error aggiunti di recente e ::grammar-error pseudo-classi. Questo post spiega la modifica, che non dovrebbe hanno un impatto visibile sulla maggior parte dei siti.

Stile di selezione

Lo stile dell'aspetto del testo selezionato può trasmettere un significato agli utenti, ad esempio lo scopo dei contenuti selezionati o l'impossibilità di selezionare il testo. GitHub, ad esempio, colora il codice selezionato in modo diverso dalla struttura della directory selezionata.

CSS supporta gli stili di selezione con lo pseudo-elemento ::selection, uno di un insieme di pseudo-elementi noti come pseudo-elementi di evidenziazione. Questi pseudo-elementi controllano il modo in cui il testo viene visualizzato sotto vari browser o azioni basate su script. Oltre alla selezione, puoi applicare stili agli errori ortografici (::spelling-error), agli errori grammaticali (::grammar-error), ai target di testo incorporati in URL (::target-text) e agli elementi evidenziati generati da script (::highlight).

Come per qualsiasi raccolta di proprietà CSS, il comportamento dell'ereditarietà è un da tenere presente durante la progettazione di un sito. In genere, gli sviluppatori si aspettano che le proprietà CSS vengano ereditate tramite l'albero degli elementi DOM (ad es. font) o che non vengano ereditate affatto (ad es. background).

Modifiche al comportamento di selezione in Chrome 131

Considera questo frammento di documento:

p {
  color: red;
}

.blue::selection {
  color: blue;
}
<p class="blue">Some <em>emphasized</em> text that one would expect to be blue</p>

Le dichiarazioni di stile del frammento modificano il colore del testo selezionato, con una regola che corrisponde a tutti gli elementi e una che corrisponde a quelli con la classe "blue". Se questa opzione è selezionata in Chrome 130 o versioni precedenti, si verifica quanto segue:

Il testo che ti aspetteresti di vedere in blu è rosso.

Se viene selezionato in Chrome 131, il risultato diventa il seguente:

Il testo viene evidenziato in blu.

Che cosa è cambiato? Il comportamento dell'ereditarietà delle proprietà di selezione storicamente implementate attraverso l'ereditarietà degli elementi originari, dove la selezione utilizza le proprietà di un ::selection che corrisponde all'elemento in fase di selezione. Le versioni 130 e precedenti di Chrome utilizzano questo modello, in cui il testo enfatizzato non ha ::selection corrispondente perché il .blue::selection corrisponde solo agli elementi con la classe "blue", mancante nell'elemento <em>.

Chrome 131 attiva un nuovo comportamento in base al quale gli elementi ereditano il comportamento di selezione dall'elemento principale. Nell'esempio precedente, l'elemento <em> non ha ::selection corrisponde a se stesso, quindi eredita i colori di selezione dell'elemento <p>. Questo è nota come ereditarietà degli elementi in evidenza CSS. Puoi provarla in precedenza Versioni di Chrome attivando le funzionalità sperimentali della piattaforma web in chrome://flags.

I siti che si basano su proprietà di selezione non ereditabili potrebbero subire modifiche nell'aspetto del testo selezionato, ma le prove dei report di bug suggeriscono che esistono pochi casi d'uso per questo comportamento.

Le proprietà personalizzate CSS per la selezione continuano a funzionare

Molti siti simulano l'eredità degli elementi evidenziati CSS tramite l'uso di proprietà personalizzate CSS. Le proprietà personalizzate vengono ereditate tramite la struttura ad albero degli elementi, generando l'esito "eredita dal padre" con uno snippet di codice come questo:

:root {
   --selection-color: lightgreen;
}

::selection {
  color: var(--selection-color);
}

.blue {
  --selection-color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text that is blue</p>

Questo è il risultato quando selezionato sia in Chrome 130 che in Chrome 131:

La prima riga è verde, la seconda blu.

Qui ogni elemento eredita un valore per la proprietà --selection-color tramite la struttura ad albero degli elementi e questo colore viene utilizzato quando il testo è selezionato. Gli elementi con la classe .blue e i relativi discendenti sono blu quando sono selezionati, mentre gli altri elementi sono di colore verde chiaro. Molti siti utilizzano questa tecnica ed è il metodo consigliato su Stack Overflow.

Per mantenere la compatibilità, il modello di ereditarietà degli elementi evidenziati CSS specifica che ::selection (e altri pseudo-elementi di evidenziazione CSS) ereditano i valori delle proprietà personalizzate dall'elemento di origine (l'elemento a cui vengono applicati). I siti che utilizzano questo metodo non dovrebbero essere interessati dalle modifiche in Chrome 131.

Le proprietà personalizzate definite nello pseudo-elemento ::selection vengono ignorate per evitare comportamenti di ereditarietà concorrenti. Devi definire le proprietà sulla e quindi farvi riferimento nello pseudoelemento.

Selettori universali per ::selection disattivare l'ereditarietà dell'evidenziazione

I siti che non utilizzano proprietà personalizzate CSS potrebbero aver utilizzato un selettore universale per impostare il colore del testo selezionato. Come nel seguente CSS, ad esempio:

::selection /* = *::selection (universal) */ {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

Questo è il risultato se selezionato sia in Chrome 130 (e versioni precedenti) sia in Chrome 131 (e successive):

La prima riga di testo è verde. Il secondo è blu, ma la parola evidenziata è verde.

L'ereditarietà delle evidenziazioni CSS non fa sì che il secondo testo enfatizzato erediti in blu rispetto a quello principale perché il selettore universale corrisponde all'elemento <em> e applica il colore di evidenziazione universale, il verde chiaro.

Per usufruire dei vantaggi dell'ereditarietà delle evidenziazioni CSS, modifica il selettore universale per trovare solo la radice, che verrà poi ereditata dai suoi discendenti:

:root::selection {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

Il risultato in Chrome 131 ha il seguente aspetto:

La prima riga di testo è verde. La seconda riga è blu.

Se il tuo sito modifica i colori di selezione, ma non utilizza proprietà personalizzate, è probabile che tu abbia un selettore universale per l'elemento pseudo ::selection. Il bene è che il vostro sito non subirà interruzioni in Chrome, ma perde i vantaggi ergonomici dell'ereditarietà dei momenti salienti.

Anche lo stile di ::target-text sta cambiando

Tutti i comportamenti e le modifiche descritti qui si applicano allo pseudo-elemento ::target-text come a ::selection. I casi d'uso per più di un gli stili del testo target su un singolo sito sono limitati e la funzionalità è abbastanza nuova, pertanto è molto improbabile che il comportamento di ::target-text cambi.

Perché questa modifica?

Quando gli altri pseudo-elementi in evidenza erano in fase di sviluppo, il CSS Il gruppo è stato risolto per implementare l'ereditarietà con il modello di ereditarietà Evidenzia. Questo era già il metodo nella specifica di ::selection pseudo-elemento, ma non è stato implementato dai browser. La non selezione Gli pseudo-elementi usano l'ereditarietà degli elementi in evidenza, dove lo pseudo-elemento viene ereditato come se si trattasse di una proprietà. In altre parole, gli elementi ereditano gli pseudo-elementi di evidenziazione dal documento principale.

Nell'interesse della coerenza tra tutti gli pseudo-elementi di evidenziazione, il gruppo di lavoro CSS ha ribadito il supporto dell'eredità dell'evidenziazione per ::selection e i browser stanno lavorando per lanciare il nuovo comportamento, cercando al contempo di non interrompere il funzionamento dei siti esistenti.

Prova

Il CodePen seguente illustra le modifiche. Provalo in Chrome 131.