Stato del CSS 2022

Funzionalità di stile web di oggi e di domani, come mostrato al Google I/O 2022, più alcuni extra.

Il 2022 si preannuncia come uno degli anni migliori per i CSS, sia per le funzionalità che per le versioni delle funzionalità dei browser cooperativi, con l'obiettivo collaborativo di implementare 14 funzionalità.

Panoramica

Questo post è la versione scritta dell'intervento tenuto al Google I/O 2022. Non è pensata per essere una guida approfondita su ogni funzionalità, ma piuttosto un'introduzione e una breve panoramica per suscitare il tuo interesse, fornendo ampiezza anziché profondità. Se ti interessa, controlla la fine di una sezione per i link alle risorse per ulteriori informazioni.

Sommario

Utilizza l'elenco di seguito per passare agli argomenti di interesse:

Compatibilità del browser

Uno dei motivi principali per cui così tante funzionalità CSS sono impostate per il rilascio cooperativo è dovuto agli sforzi di Interop 2022. Prima di studiare gli sforzi di Interop, è importante esaminare quelli di Compat 2021.

Compat 2021

Gli obiettivi per il 2021, basati sul feedback degli sviluppatori tramite sondaggi, erano di stabilizzare le funzionalità attuali, migliorare la suite di test e aumentare i punteggi di superamento dei browser per cinque funzionalità:

  1. sticky posizionamento
  2. aspect-ratio dimensionamento
  3. Layout flex
  4. Layout grid
  5. Posizionamento e animazione di transform

I punteggi dei test sono aumentati in tutti i casi, a dimostrazione di una maggiore stabilità e affidabilità. Congratulazioni ai team presenti.

Interop 2022

Quest'anno, i browser si sono riuniti per discutere delle funzionalità e delle priorità su cui intendevano lavorare, unendo le loro forze. Avevano pianificato di fornire le seguenti funzionalità web per gli sviluppatori:

  1. @layer
  2. Spazi colore e funzioni
  3. Contenimento
  4. <dialog>
  5. Compatibilità con i moduli
  6. Scorrimento
  7. Subgrid
  8. Tipografia
  9. Unità di misura dell'area visibile
  10. Compatibilità web

Si tratta di un elenco entusiasmante e ambizioso che non vedo l'ora di vedere realizzarsi.

Novità del 2022

Non sorprende che lo stato di CSS 2022 sia influenzato in modo significativo dal lavoro di Interop 2022.

Livelli a cascata

Browser Support

  • Chrome: 99.
  • Edge: 99.
  • Firefox: 97.
  • Safari: 15.4.

Source

Prima di @layer, l'ordine di caricamento dei fogli di stile era molto importante, in quanto gli stili caricati per ultimi possono sovrascrivere quelli caricati in precedenza. Ciò ha portato a fogli di stile di ingresso gestiti meticolosamente, in cui gli sviluppatori dovevano caricare prima gli stili meno importanti e poi quelli più importanti. Esistono metodologie complete per aiutare gli sviluppatori a gestire questa importanza, come ITCSS.

Con @layer, il file di ingresso può predefinire i livelli e il loro ordine in anticipo. Poi, man mano che gli stili vengono caricati o definiti, possono essere inseriti in un livello, consentendo di preservare l'importanza dell'override dello stile, ma senza l'orchestrazione meticolosamente gestita del caricamento.

Il video mostra come i livelli a cascata definiti consentono un processo di creazione e caricamento più libero e in stile libero, mantenendo comunque la cascata come necessario.

Chrome DevTools è utile per visualizzare gli stili provenienti dai vari livelli:

Screenshot della barra laterale Stili di Strumenti per sviluppatori di Chrome, che mostra come appaiono gli stili all&#39;interno dei nuovi gruppi di livelli.

Risorse

Subgrid

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 71.
  • Safari: 16.

Source

Prima del giorno subgrid, una griglia all'interno di un'altra griglia non poteva allinearsi alle celle o alle linee della griglia principale. Ogni layout a griglia era unico. Molti designer posizionano una singola griglia sull'intero design e allineano costantemente gli elementi al suo interno, cosa che non era possibile fare in CSS.

Dopo subgrid, un elemento secondario di una griglia può adottare le colonne o le righe dei genitori come proprie e allineare se stesso o i suoi elementi secondari.

Nella seguente demo, l'elemento body crea una griglia classica di tre colonne: la colonna centrale è chiamata main, mentre le colonne sinistra e destra nominano le linee fullbleed. Poi, ogni elemento nel corpo, <nav> e <main>, adotta le linee denominate dal corpo impostando grid-template-columns: subgrid.

​​body {
  display: grid;
  grid-template-columns:
    [fullbleed-start]
    auto [main-start] min(90%, 60ch) [main-end] auto
    [fullbleed-end]
  ;
}

body > * {
  display: grid;
  grid-template-columns: subgrid;
}

Infine, i figli di <nav> o <main> possono allinearsi o dimensionarsi utilizzando le colonne e le righe fullbleed e main.

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

Gli strumenti di sviluppo possono aiutarti a visualizzare le linee e le griglie secondarie (al momento solo Firefox). Nell'immagine seguente, la griglia principale e le griglie secondarie sono state sovrapposte. Ora assomiglia al modo in cui i designer pensavano al layout.

Screenshot di una demo della griglia secondaria, che utilizza gli strumenti di overlay della griglia di Chrome DevTools per mostrare le linee definite da CSS.

Nel riquadro degli elementi di DevTools puoi vedere quali elementi sono griglie e sottogriglie, il che è molto utile per il debug o la convalida del layout.

Screenshot del riquadro Elementi di Chrome DevTools che indica quali elementi hanno layout a griglia o griglia secondaria.
Screenshot di Firefox Devtools

Risorse

Query sui container

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

Prima del giorno @container, gli elementi di una pagina web potevano rispondere solo alle dimensioni dell'intera area visibile. Questa soluzione è ideale per i layout macro, ma per i layout micro, in cui il contenitore esterno non è l'intera area visibile, è impossibile per il layout adattarsi di conseguenza.

Dopo @container, gli elementi possono rispondere alle dimensioni o allo stile di un contenitore principale. L'unico avvertimento è che i contenitori devono dichiararsi come possibili target di query, il che è un piccolo requisito per un grande vantaggio.

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

Questi stili consentono di eseguire query sulle colonne Lun, Mar, Mer, Gio e Ven nel video seguente in base agli elementi dell'evento.

Demo di Una Kravets

Ecco il CSS per eseguire query sul contenitore calendar-day per la sua dimensione, quindi regolare un layout e le dimensioni dei caratteri:

@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}

Ecco un altro esempio: un componente libro si adatta allo spazio disponibile nella colonna in cui viene trascinato:

Demo di Max Böck

Una ha ragione a definire la situazione come il nuovo responsive. Quando utilizzi @container, puoi prendere molte decisioni di design interessanti e significative.

Risorse

accent-color

Browser Support

  • Chrome: 93.
  • Edge: 93.
  • Firefox: 92.
  • Safari: 15.4.

Source

Prima di accent-color, quando volevi un modulo con colori corrispondenti al brand, potevi ritrovarti con librerie complesse o soluzioni CSS difficili da gestire nel tempo. Anche se ti hanno fornito tutte le opzioni e, si spera, incluso l'accessibilità, la scelta di utilizzare i componenti integrati o adottare i tuoi diventa noiosa da continuare a scegliere.

Dopo accent-color, una riga di CSS porta un colore del brand nei componenti integrati. Oltre a una tonalità, il browser sceglie in modo intelligente i colori di contrasto appropriati per le parti ausiliarie del componente e si adatta alle combinazioni di colori del sistema (chiaro o scuro).

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

Elementi HTML accentati chiari e scuri affiancati per il confronto.

Per saperne di più su accent-color, consulta il mio post su web.dev, in cui esploro molti altri aspetti di questa utile proprietà CSS.

Risorse

Livello di colore 4 e 5

Il web è stato dominato da sRGB negli ultimi decenni, ma in un mondo digitale in espansione di display ad alta definizione e dispositivi mobili preinstallati con schermi OLED o QLED, sRGB non è sufficiente. Inoltre, sono previste pagine dinamiche che si adattano alle preferenze degli utenti e la gestione del colore è diventata una preoccupazione sempre più importante per designer, sistemi di progettazione e responsabili della manutenzione del codice.

Non nel 2022, però: CSS ha una serie di nuove funzioni e spazi di colore: - Colori che sfruttano le funzionalità di colore HD dei display. - Spazi colore che corrispondono a un intento, ad esempio l'uniformità percettiva. - Spazi colore per sfumature che modificano drasticamente i risultati dell'interpolazione. - Funzioni di colore per aiutarti a mescolare e contrastare i colori e scegliere lo spazio in cui lavorare.

Prima di tutte queste funzionalità di colore, i sistemi di progettazione dovevano precalcolare i colori di contrasto appropriati e garantire tavolozze adeguatamente vivaci, mentre i preprocessor o JavaScript facevano il lavoro più pesante.

Dopo tutte queste funzionalità di colore, il browser e CSS possono fare tutto il lavoro, in modo dinamico e appena in tempo. Anziché inviare agli utenti molti KB di CSS e JavaScript per consentire la creazione di temi e la visualizzazione dei colori dei dati, CSS può eseguire l'orchestrazione e i calcoli. Inoltre, CSS è meglio attrezzato per verificare il supporto prima dell'utilizzo o gestire i fallback in modo appropriato.

@media (dynamic-range: high) {
  .neon-pink {
    --neon-glow: color(display-p3 1 0 1);
  }
}

@supports (color: lab(0% 0 0)) {
  .neon-pink {
    --neon-glow: lab(150% 160 0);
  }
}

hwb()

Browser Support

  • Chrome: 101.
  • Edge: 101.
  • Firefox: 96.
  • Safari: 15.

Source

HWB è l'acronimo di tonalità, bianco e nero. Si presenta come un modo semplice per esprimere il colore, in quanto si tratta solo di una tonalità e di una quantità di bianco o nero per schiarire o scurire. Gli artisti che mescolano i colori con il bianco o il nero potrebbero apprezzare questa aggiunta alla sintassi dei colori.

L'utilizzo di questa funzione di colore genera colori dello spazio colore sRGB, lo stesso di HSL e RGB. In termini di novità per il 2022, non offre nuovi colori, ma potrebbe semplificare alcune attività per gli appassionati della sintassi e del modello mentale.

Risorse

Spazi colore

Il modo in cui i colori vengono rappresentati avviene tramite uno spazio colore. Ogni spazio colore offre varie funzionalità e compromessi per lavorare con il colore. Alcuni potrebbero raggruppare tutti i colori vivaci, altri potrebbero allinearli in base alla loro luminosità.

Le specifiche CSS del 2022 prevedono 10 nuovi spazi colore, ognuno con caratteristiche uniche per aiutare designer e sviluppatori a visualizzare, scegliere e combinare i colori. In precedenza, sRGB era l'unica opzione per lavorare con il colore, ma ora CSS offre nuove potenzialità e un nuovo spazio colore predefinito, LCH.

color-mix()

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

Source

Prima di color-mix(), gli sviluppatori e i designer avevano bisogno di preprocessor come Sass per combinare i colori prima che il browser li visualizzasse. La maggior parte delle funzioni di miscelazione dei colori non offriva nemmeno la possibilità di specificare in quale spazio colore eseguire la miscelazione, il che a volte portava a risultati confusi.

Dopo color-mix(), sviluppatori e designer possono combinare i colori nel browser, insieme a tutti gli altri stili, senza eseguire processi di compilazione o includere JavaScript. Inoltre, possono specificare lo spazio colore in cui eseguire la combinazione o utilizzare lo spazio colore di combinazione predefinito LCH.

Spesso, un colore del brand viene utilizzato come base e vengono create varianti, ad esempio colori più chiari o più scuri per gli stili al passaggio del mouse. Ecco come si presenta con color-mix():

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}

e se volessi mescolare questi colori in uno spazio colore diverso, ad esempio sRGB, modificalo:

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

Di seguito è riportata una demo della personalizzazione dei temi che utilizza color-mix(). Prova a cambiare il colore del brand e guarda l'aggiornamento del tema:

Nel 2022 potrai divertirti a combinare i colori in vari spazi colore nei tuoi fogli di stile.

Risorse

color-contrast()

Prima di color-contrast(), gli autori dei fogli di stile dovevano conoscere in anticipo i colori accessibili. Spesso una tavolozza mostra testo nero o bianco su un campione di colore, per indicare a un utente del sistema di colori quale colore del testo sarebbe necessario per contrastare correttamente con quel campione.

Screenshot di tre tavolozze Material, che mostrano 14 colori e i relativi colori di contrasto bianco o nero appropriati per il testo.
Esempio tratto dalle tavolozze dei colori di Material Design del 2014

Dopo color-contrast(), gli autori dei fogli di stile possono delegare completamente l'attività al browser. Non solo puoi utilizzare il browser per scegliere automaticamente un colore nero o bianco, ma puoi anche fornirgli un elenco di colori appropriati per il sistema di progettazione e fargli scegliere il primo che supera il rapporto di contrasto desiderato.

Ecco uno screenshot di una demo di un set di tavolozze di colori HWB in cui i colori del testo vengono scelti automaticamente dal browser in base al colore del campione:

Screenshot della demo HWB in cui ogni tavolozza ha un diverso accoppiamento di testo chiaro o scuro, come determinato dal browser.
Prova la demo

Le basi della sintassi sono le seguenti, dove il grigio viene passato alla funzione e il browser determina se il nero o il bianco hanno il contrasto maggiore:

color: color-contrast(gray);

La funzione può anche essere personalizzata con un elenco di colori, da cui verrà scelto il colore con il contrasto più elevato della selezione:

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

Infine, nel caso in cui sia preferibile non scegliere il colore con il contrasto più elevato dall'elenco, è possibile fornire un rapporto di contrasto target e viene scelto il primo colore che lo supera:

color: color-contrast(
  var(--bg-blue-1)
  vs
  var(--text-lightest), var(--text-light), var(--text-subdued)
  to AA /* 4.5 could also be passed */
);

Questa funzione può essere utilizzata per molto più del semplice colore del testo, anche se ritengo che sarà il suo caso d'uso principale. Pensa a quanto sarà più facile fornire interfacce accessibili e leggibili una volta che la scelta dei colori di contrasto appropriati sarà integrata nel linguaggio CSS stesso.

Risorse

Sintassi del colore relativo

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 15.

Source

Prima della sintassi del colore relativo, per eseguire calcoli sul colore e apportare modifiche, i canali colore dovevano essere inseriti singolarmente nelle proprietà personalizzate. Questa limitazione ha reso HSL la funzione di colore principale per la manipolazione dei colori perché la tonalità, la saturazione o la luminosità potevano essere regolate in modo semplice con calc().

Dopo la sintassi del colore relativo, qualsiasi colore in qualsiasi spazio può essere decostruito, modificato e restituito come colore, tutto in una riga di CSS. Nessuna limitazione all'HSL: le manipolazioni possono essere eseguite in qualsiasi spazio colore desiderato e devono essere create molte meno proprietà personalizzate per facilitarlo.

Nel seguente esempio di sintassi, viene fornito un esadecimale di base e vengono creati due nuovi colori relativi a questo. Il primo colore --absolute-change crea un nuovo colore in LCH dal colore di base, quindi procede a sostituire la luminosità del colore di base con 75%, mantenendo la croma (c) e la tonalità (h). Il secondo colore --relative-change crea un nuovo colore in LCH dal colore di base, ma questa volta riduce la croma (c) del 20%.

.relative-color-syntax {
  --color: #0af;
  --absolute-change: lch(from var(--color) 75% c h);
  --relative-change: lch(from var(--color) l calc(c-20%) h);
}

È come mescolare i colori, ma è più simile alle alterazioni che alla mescolanza. Puoi eseguire il cast di un colore da un altro colore, ottenendo l'accesso ai tre valori dei canali in base alla funzione di colore utilizzata, con la possibilità di regolare questi canali. Nel complesso, si tratta di una sintassi molto interessante e potente per il colore.

Nella seguente demo ho utilizzato la sintassi dei colori relativi per creare varianti più chiare e più scure di un colore di base e ho utilizzato color-contrast() per garantire che le etichette abbiano un contrasto adeguato:

Screenshot con tre colonne, ognuna più scura o più chiara della colonna centrale.
Prova la demo

Questa funzione può essere utilizzata anche per la generazione di tavolozze di colori. Ecco una demo in cui vengono generate intere tavolozze a partire da un colore di base fornito. Questo unico insieme di CSS alimenta tutte le varie tavolozze, ognuna delle quali fornisce semplicemente una base diversa. Come bonus, dato che ho utilizzato LCH, guarda come le tavolozze sono uniformi dal punto di vista percettivo: non ci sono punti caldi o morti, grazie a questo spazio colore.

:root {
  --_color-base: #339af0;

  --color-0:  lch(from var(--_color-base) 98% 10 h);
  --color-1:  lch(from var(--_color-base) 93% 20 h);
  --color-2:  lch(from var(--_color-base) 85% 40 h);
  --color-3:  lch(from var(--_color-base) 75% 46 h);
  --color-4:  lch(from var(--_color-base) 66% 51 h);
  --color-5:  lch(from var(--_color-base) 61% 52 h);
  --color-6:  lch(from var(--_color-base) 55% 57 h);
  --color-7:  lch(from var(--_color-base) 49% 58 h);
  --color-8:  lch(from var(--_color-base) 43% 55 h);
  --color-9:  lch(from var(--_color-base) 39% 52 h);
  --color-10: lch(from var(--_color-base) 32% 48 h);
  --color-11: lch(from var(--_color-base) 25% 45 h);
  --color-12: lch(from var(--_color-base) 17% 40 h);
  --color-13: lch(from var(--_color-base) 10% 30 h);
  --color-14: lch(from var(--_color-base) 5% 20 h);
  --color-15: lch(from var(--_color-base) 1% 5 h);
}
Screenshot di 15 tavolozze generate dinamicamente dai CSS.
Prova la demo

A questo punto, dovresti aver capito come gli spazi colore e le diverse funzioni di colore possono essere utilizzati per scopi diversi, in base ai loro punti di forza e di debolezza.

Risorse

Spazi colore del gradiente

Prima degli spazi colore con gradiente, veniva utilizzato lo spazio colore sRGB predefinito. sRGB è generalmente affidabile, ma presenta alcuni punti deboli, come la zona grigia morta.

4 sfumature in una griglia, tutte dal ciano al rosa intenso. LCH e LAB hanno una vivacità più uniforme, mentre sRGB è un po&#39; desaturato al centro.

Dopo gli spazi colore del gradiente, indica al browser quale spazio colore utilizzare per l'interpolazione del colore. In questo modo, sviluppatori e designer possono scegliere il gradiente che preferiscono. Anche lo spazio colore predefinito cambia in LCH anziché sRGB.

L'aggiunta della sintassi segue la direzione del gradiente, utilizza la nuova sintassi in ed è facoltativa:

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

Ecco una sfumatura di base ed essenziale dal nero al bianco. Esamina l'intervallo di risultati in ogni spazio colore. Alcuni raggiungono il nero intenso prima di altri, alcuni sbiadiscono al bianco troppo tardi.

11 spazi colore mostrati confrontando il nero con il bianco.

Nel prossimo esempio, il nero viene trasformato in blu perché è un problema noto spazio per i gradienti. La maggior parte degli spazi colore tende al viola durante l'interpolazione del colore o, come mi piace pensare, mentre i colori si spostano all'interno dello spazio colore dal punto A al punto B. Poiché il gradiente segue una linea retta dal punto A al punto B, la forma dello spazio colore cambia drasticamente le tappe del percorso.

11 spazi colore mostrati confrontando il blu e il nero.

Per esplorazioni più approfondite, esempi e commenti, leggi questo thread di Twitter.

Risorse

inert

Browser Support

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 112.
  • Safari: 15.5.

Source

Prima di inert, era buona prassi indirizzare l'attenzione dell'utente verso le aree della pagina o dell'app che richiedevano attenzione immediata. Questa strategia di messa a fuoco guidata è diventata nota come intrappolamento dello stato attivo perché gli sviluppatori posizionavano lo stato attivo in uno spazio interattivo, ascoltavano gli eventi di cambio dello stato attivo e, se lo stato attivo usciva dallo spazio interattivo, veniva forzato a rientrare. Gli utenti che utilizzano tastiere o screen reader vengono riportati allo spazio interattivo per assicurarsi che l'attività sia completata prima di andare avanti.

Dopo inert, non è necessario alcun blocco perché puoi bloccare o proteggere intere sezioni della pagina o dell'app. I tentativi di clic e cambio di messa a fuoco non sono disponibili mentre queste parti di un documento sono inerti. Si potrebbe anche pensare a questo come a delle guardie invece di una trappola, in cui inert non è interessato a farti rimanere in un posto, ma a rendere indisponibili altri luoghi.

Un buon esempio è la funzione JavaScript alert():

Il sito web viene visualizzato come interattivo, quindi viene chiamato un alert() e la pagina non è più attiva.

Nel video precedente, nota come la pagina fosse accessibile con mouse e tastiera fino a quando non è stato chiamato un alert(). Una volta visualizzato il popup della finestra di dialogo di avviso, il resto della pagina è stato bloccato o inert. Lo stato attivo dell'utente si trova all'interno della finestra di dialogo di avviso e non può essere spostato altrove. Una volta che l'utente interagisce e completa la richiesta di funzione di avviso, la pagina torna a essere interattiva. inert consente agli sviluppatori di ottenere facilmente la stessa esperienza di messa a fuoco guidata.

Ecco un piccolo codice campione per mostrare come funziona:

<body>
  <div class="modal">
    <h2>Modal Title</h2>
    <p>...<p>
    <button>Save</button>
    <button>Discard</button>
  </div>
  <main inert>
    <!-- cannot be keyboard focused or clicked -->
  </main>
</body>

Una finestra di dialogo è un ottimo esempio, ma inert è utile anche per elementi come l'esperienza utente del menu laterale a scorrimento. Quando un utente estrae il menu laterale, non è consentito che il mouse o la tastiera interagiscano con la pagina sottostante, perché è un po' complicato per gli utenti. Quando viene visualizzato il menu laterale, la pagina diventa inerte e gli utenti devono chiudere o navigare all'interno del menu laterale, senza perdersi in altre parti della pagina con un menu aperto.

Risorse

Caratteri COLRv1

Prima dei caratteri COLRv1, il web aveva i caratteri OT-SVG, anch'essi in formato aperto per i caratteri con sfumature ed effetti e colori integrati. Questi potevano diventare molto grandi e, sebbene consentissero di modificare il testo, non c'era molto spazio per la personalizzazione.

Dopo i caratteri COLRv1, il web dispone di caratteri più piccoli, scalabili in formato vettoriale, riposizionabili, con sfumature e con modalità di fusione che accettano parametri per personalizzare il carattere in base al caso d'uso o per abbinarlo a un brand.

Visualizzazione del confronto e grafico a barre che mostrano come i caratteri COLRv1 siano più nitidi e più piccoli.
Immagine tratta da https://developer.chrome.com/blog/colrv1-fonts/

Ecco un esempio tratto dal post del blog per sviluppatori Chrome sugli emoji. Forse avrai notato che se aumenti le dimensioni del carattere di un'emoji, questa non rimane nitida. È un'immagine e non un'illustrazione vettoriale. Spesso, quando viene utilizzata un'emoji nelle applicazioni, viene sostituita con un asset di qualità superiore. Con i caratteri COLRv1, le emoji sono vettoriali e bellissime:

I caratteri icona potrebbero fare cose straordinarie con questo formato, offrendo tavolozze di colori personalizzate in due tonalità e altro ancora. Il caricamento di un carattere COLRv1 è identico a quello di qualsiasi altro file di caratteri:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

La personalizzazione del carattere COLRv1 viene eseguita con @font-palette-values, una regola CSS speciale per raggruppare e denominare un insieme di opzioni di personalizzazione in un bundle per riferimento futuro. Nota come specificare un nome personalizzato proprio come una proprietà personalizzata, a partire da --:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

Con --colorized come alias per le personalizzazioni, l'ultimo passaggio consiste nell'applicare la tavolozza a un elemento che utilizza la famiglia di caratteri a colori:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
Screenshot del carattere Bungee Spice con la parola DUNE.
Carattere Bungee Spice mostrato con colori personalizzati, origine da https://developer.chrome.com/blog/colrv1-fonts/

Con la crescente disponibilità di caratteri variabili e a colori, la tipografia web sta percorrendo un percorso molto promettente verso una ricca personalizzazione e un'espressione creativa.

Risorse

Unità di misura dell'area visibile

Immagine che mostra come lo schermo del dispositivo, la finestra del browser e un iframe abbiano tutti viewport diversi.

Prima delle nuove varianti dell'area visibile, il web offriva unità fisiche per facilitare l'adattamento delle aree visibili. Uno per l'altezza, la larghezza, la dimensione più piccola (vmin) e il lato più grande (vmax). Questi hanno funzionato bene per molte cose, ma i browser mobile hanno introdotto una complessità.

Sui dispositivi mobili, quando viene caricata una pagina, viene visualizzata la barra di stato con l'URL e questa barra occupa parte dello spazio dell'area visibile. Dopo alcuni secondi e un po' di interattività, la barra di stato potrebbe scomparire per consentire all'utente un'esperienza di visualizzazione più ampia. Quando la barra scorre verso l'esterno, l'altezza dell'area visibile è cambiata e tutte le unità vh si spostano e vengono ridimensionate man mano che le dimensioni di destinazione cambiano. Negli anni successivi, l'unità vh doveva decidere in modo specifico quale delle due dimensioni della finestra di visualizzazione utilizzare, perché causava problemi di layout visivo sui dispositivi mobili. È stato stabilito che vh rappresenterà sempre l'area visibile più grande.

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

Dopo le nuove varianti dell'area visibile, vengono rese disponibili unità di area visibile piccole, grandi e dinamiche, con l'aggiunta di equivalenti logici a quelli fisici. L'idea è di dare a sviluppatori e designer la possibilità di scegliere l'unità che vogliono utilizzare per il loro scenario specifico. Forse è accettabile un piccolo spostamento del layout quando la barra di stato scompare, in modo che dvh (altezza dinamica del viewport) possa essere utilizzata senza problemi.

Un&#39;immagine con tre smartphone per illustrare DVH, LVH e SVH. Il telefono di esempio DVH
   ha due linee verticali, una tra la parte inferiore della barra di ricerca
   e la parte inferiore del riquadro visibile e una tra la parte superiore della barra di ricerca (sotto la
   barra di stato del sistema) e la parte inferiore del riquadro visibile, mostrando come DVH può avere una
   di queste due lunghezze. LVH viene mostrato al centro con una linea tra la parte inferiore della barra di stato del dispositivo e il pulsante della finestra del telefono. L&#39;ultima è
   l&#39;unità SVH, che mostra una linea dalla parte inferiore della barra di ricerca del browser
   alla parte inferiore del riquadro visibile

Di seguito è riportato un elenco completo di tutte le nuove opzioni per le unità viewport rese disponibili con le nuove varianti del viewport:

Unità di altezza dell'area visibile
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
Unità di larghezza del viewport
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
Unità laterali più piccole dell'area visibile
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
Unità laterali più grandi dell'area visibile
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

Ci auguriamo che queste funzionalità offrano a sviluppatori e designer la flessibilità necessaria per ottenere i design reattivi della finestra.

Risorse

:has()

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

Prima di :has(), l'oggetto di un selettore si trovava sempre alla fine. Ad esempio, l'oggetto di questo selettore è un elemento dell'elenco: ul > li. Gli pseudo-selettori possono modificare il selettore, ma non cambiano il soggetto: ul > li:hover o ul > li:not(.selected).

Dopo :has(), un soggetto più in alto nell'albero degli elementi può rimanere il soggetto fornendo una query sui figli: ul:has(> li). È facile capire perché :has() ha ricevuto il nome comune di "selettore principale", in quanto il soggetto del selettore è ora il genitore in questo caso.

Ecco un esempio di sintassi di base in cui la classe .parent rimane il soggetto, ma viene selezionata solo se un elemento secondario ha la classe .child:

.parent:has(.child) {...}

Ecco un esempio in cui un elemento <section> è il soggetto, ma il selettore corrisponde solo se uno degli elementi secondari ha :focus-visible:

section:has(*:focus-visible) {...}

Il selettore :has() inizia a diventare un'utilità fantastica quando diventano evidenti casi d'uso più pratici. Ad esempio, al momento non è possibile selezionare i tag <a> quando includono immagini, il che rende difficile insegnare al tag di ancoraggio come modificare i suoi stili in questo caso d'uso. È possibile con :has() però:

a:has(> img) {...}

Questi sono tutti esempi in cui :has() sembra solo un selettore principale. Prendi in considerazione il caso d'uso delle immagini all'interno degli elementi <figure> e la regolazione degli stili delle immagini se la figura ha una <figcaption>. Nell'esempio seguente, vengono selezionate le figure con le didascalie e poi le immagini all'interno di questo contesto. :has() viene utilizzato e non modifica il soggetto, in quanto il soggetto a cui ci rivolgiamo sono le immagini, non le figure:

figure:has(figcaption) img {...}

Le combinazioni sono apparentemente infinite. Combina :has() con query sulla quantità e regola i layout a griglia CSS in base al numero di elementi secondari. Combina :has() con stati di pseudo-classe interattivi e crea applicazioni che rispondono in nuovi modi creativi.

La verifica del supporto è semplificata con @supports e la relativa funzione selector(), che verifica se il browser comprende la sintassi prima di utilizzarla:

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

Risorse

2022 e anni successivi

Ci sono ancora molte cose che saranno difficili da fare dopo l'implementazione di tutte queste fantastiche funzionalità nel 2022. La sezione successiva esamina alcuni dei problemi rimanenti e le soluzioni in fase di sviluppo attivo per risolverli. Queste soluzioni sono sperimentali, anche se potrebbero essere specificate o disponibili dietro i flag nei browser.

I risultati delle sezioni successive dovrebbero rassicurarti sul fatto che i problemi elencati sono oggetto di risoluzione da parte di molte persone di molte aziende, non che queste soluzioni verranno rilasciate nel 2023.

Proprietà personalizzate con tipizzazione debole

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

Le proprietà personalizzate CSS sono fantastiche. Consentono di memorizzare tutti i tipi di dati all'interno di una variabile denominata, che può essere estesa, calcolata, condivisa e altro ancora. Infatti, sono così flessibili che sarebbe bello averne alcuni meno flessibili.

Considera uno scenario in cui un box-shadow utilizza proprietà personalizzate per i suoi valori:

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

Tutto funziona bene finché una delle proprietà non viene modificata in un valore che CSS non accetta, ad esempio --x: red. L'intera ombra viene interrotta se una delle variabili nidificate è mancante o è impostata su un tipo di valore non valido.

È qui che entra in gioco @property: --x può diventare una proprietà personalizzata digitata, non più libera e flessibile, ma sicura con alcuni limiti definiti:

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

Ora, quando box-shadow utilizza var(--x) e successivamente viene tentato --x: red, red verrà ignorato perché non è un <length>. Ciò significa che l'ombreggiatura continua a funzionare, anche se a una delle sue proprietà personalizzate è stato assegnato un valore non valido. Anziché non riuscire, torna al valore initial-value di 0px.

Animazione

Oltre alla sicurezza dei tipi, apre anche molte porte all'animazione. La flessibilità della sintassi CSS rende impossibile animare alcune cose, come i gradienti. @property è utile in questo caso perché la proprietà CSS digitata può informare il browser dell'intento di uno sviluppatore all'interno di un'interpolazione altrimenti eccessivamente complessa. In sostanza, limita l'ambito delle possibilità in modo tale che un browser possa animare aspetti di uno stile che prima non poteva.

Considera questo esempio di demo, in cui viene utilizzato un gradiente radiale per creare una porzione di una sovrapposizione, creando un effetto di messa a fuoco. JavaScript imposta x e y del mouse quando viene premuto il tasto Alt/Opzione, quindi modifica la dimensione del fuoco a un valore più piccolo, ad esempio 25%, creando il cerchio di messa a fuoco del riflettore nella posizione del mouse:

Prova la demo
.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );
}

Tuttavia, i gradienti non possono essere animati. Sono troppo flessibili e complessi per il browser per "dedurre" semplicemente come vuoi che vengano animate. Con @property, invece, una proprietà può essere digitata e animata in isolamento, per cui il browser può comprendere facilmente l'intento.

I videogiochi che utilizzano questo effetto di messa a fuoco animano sempre il cerchio, da un cerchio grande a un cerchio puntiforme. Ecco come utilizzare @property con la nostra demo in modo che il browser animi la maschera sfumata:

@property --focal-size {
  syntax: '<length-percentage>';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );

  transition: --focal-size .3s ease;
}
Prova la demo

Ora il browser è in grado di animare le dimensioni del gradiente perché abbiamo ridotto la superficie della modifica a una sola proprietà e abbiamo digitato il valore in modo che il browser possa interpolare in modo intelligente le lunghezze.

@property può fare molto di più, ma questi piccoli miglioramenti possono fare una grande differenza.

Risorse

Si trovava in min-width o max-width

Prima degli intervalli delle media query, una media query CSS utilizza min-width e max-width per articolare le condizioni superiori e inferiori. Potrebbe avere un aspetto simile al seguente:

@media (min-width: 320px) {
  
}

Dopo gli intervalli delle query supporti, la stessa query supporti potrebbe essere simile alla seguente:

@media (width >= 320px) {
  
}

Una query supporti CSS che utilizza sia min-width che max-width potrebbe avere il seguente aspetto:

@media (min-width: 320px) and (max-width: 1280px) {
  
}

Dopo gli intervalli delle query supporti, la stessa query supporti potrebbe essere simile alla seguente:

@media (320px <= width <= 1280px) {
  
}

A seconda delle tue competenze di programmazione, uno dei due ti sembrerà molto più leggibile dell'altro. Grazie alle aggiunte alle specifiche, gli sviluppatori potranno scegliere quella che preferiscono o persino utilizzarle in modo intercambiabile.

Risorse

Nessuna variabile di query supporti

Prima di @custom-media, le media query dovevano ripetersi più volte o fare affidamento sui preprocessor per generare l'output corretto in base alle variabili statiche durante la compilazione.

A partire da @custom-media, CSS consente di creare alias per le query supporti e di farvi riferimento, proprio come per una proprietà personalizzata.

Assegnare un nome è molto importante: può allineare lo scopo alla sintassi, rendendo più facile condividere e utilizzare le cose nei team. Ecco alcune query personalizzate sui contenuti multimediali che seguo tra i progetti:

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

Ora che sono definiti, posso usarne uno in questo modo:

@media (--OSdark) {
  :root {
    
  }
}

Trova un elenco completo di query personalizzate per i media che utilizzo all'interno della mia libreria di proprietà personalizzate CSS Open Props.

Risorse

L'annidamento dei selettori è molto utile

Prima di @nest, c'era molta ripetizione nei fogli di stile. È diventato particolarmente ingombrante quando i selettori erano lunghi e ognuno aveva come target piccole differenze. La comodità dell'annidamento è uno dei motivi più comuni per adottare un preprocessor.

Dopo @nest, la ripetizione non è più disponibile. Quasi tutte le funzionalità dell'annidamento abilitato al preprocessor saranno disponibili integrate nel CSS.

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

Ciò che mi interessa di più dell'annidamento, oltre a non ripetere article nel selettore annidato, è che il contesto di stile rimanga all'interno di un blocco di stile. Anziché passare da un selettore e dai relativi stili a un altro selettore con stili (esempio 1), il lettore può rimanere nel contesto di un articolo e vedere i link di proprietà dell'articolo al suo interno. L'intento di relazione e stile sono raggruppati, quindi article sembra avere i propri stili.

La proprietà può anche essere considerata come centralizzazione. Invece di cercare in un foglio di stile gli stili pertinenti, possono essere trovati tutti nidificati insieme all'interno di un contesto. Questo funziona con le relazioni genitore-figlio, ma anche con le relazioni figlio-genitore.

Considera un componente secondario che vuole adattarsi quando si trova in un contesto principale diverso, anziché il componente principale che possiede lo stile e modifica un componente secondario:

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

@nest contribuisce a organizzare, centralizzare e gestire meglio gli stili. I componenti possono raggruppare e possedere i propri stili, anziché distribuirli tra altri blocchi di stili. Può sembrare una piccola cosa in questi esempi, ma può avere un impatto molto grande, sia per comodità che per leggibilità.

Risorse

Definire gli stili è molto difficile

Browser Support

  • Chrome: 118.
  • Edge: 118.
  • Firefox: behind a flag.
  • Safari: 17.4.

Source

Prima di @scope, esistevano molte strategie perché gli stili in CSS vengono applicati a cascata, ereditati e hanno ambito globale per impostazione predefinita. Queste funzionalità di CSS sono molto utili per molte cose, ma per siti e applicazioni complessi, con potenzialmente molti stili diversi di componenti, lo spazio globale e la natura della cascata possono far sembrare che gli stili perdano efficacia.

Dopo @scope, gli stili non solo possono essere limitati a un contesto, ad esempio una classe, ma possono anche indicare dove terminano e non continuano a essere applicati a cascata o ereditati.

Nell'esempio seguente, l'ambito della convenzione di denominazione BEM può essere invertito nell'intento effettivo. Il selettore BEM tenta di definire l'ambito del colore di un elemento header in un contenitore .card con convenzioni di denominazione. Per completare l'obiettivo, l'intestazione deve contenere questo nome classe. Con @scope, non sono necessarie convenzioni di denominazione per completare lo stesso obiettivo senza contrassegnare l'elemento di intestazione:

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

Ecco un altro esempio, meno specifico per i componenti e più incentrato sulla natura dell'ambito globale di CSS. I temi scuro e chiaro devono coesistere all'interno di un foglio di stile, in cui l'ordine è importante per determinare uno stile vincente. In genere, gli stili del tema scuro vengono dopo quelli del tema chiaro, che viene impostato come predefinito e il tema scuro come stile facoltativo. Evita la battaglia per l'ordine e l'ambito con @scope:

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

Per completare la storia qui, @scope consente anche di stabilire dove termina l'ambito dello stile. Questa operazione non può essere eseguita con alcuna convenzione di denominazione o preprocessor; è speciale e può essere eseguita solo con CSS integrati nel browser. Nell'esempio seguente, gli stili img e .content vengono applicati esclusivamente quando un elemento secondario di un .media-block è un elemento di pari livello o principale di .content:

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

Risorse

Nessun modo CSS per un layout a griglia

Prima di CSS masonry con griglia, JavaScript era il modo migliore per ottenere un layout a griglia, poiché qualsiasi metodo CSS con colonne o flexbox avrebbe rappresentato in modo impreciso l'ordine dei contenuti.

Dopo CSS masonry con griglia, non saranno necessarie librerie JavaScript e l'ordine dei contenuti sarà corretto.

Screenshot del layout a griglia che mostra i numeri che scorrono in alto e poi in basso.
Immagine e demo di Smashing Magazine
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

La demo precedente viene ottenuta con il seguente CSS:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

È confortante sapere che questa strategia di layout mancante è in fase di valutazione. Inoltre, puoi provarla oggi in Firefox.

Risorse

Il CSS non può aiutare gli utenti a ridurre i dati

Browser Support

  • Chrome: behind a flag.
  • Edge: behind a flag.
  • Firefox: not supported.
  • Safari: not supported.

Source

Prima della media query prefers-reduced-data, JavaScript e un server potevano modificare il proprio comportamento in base all'opzione "Risparmio dati" del sistema operativo o del browser di un utente, ma CSS non poteva.

Dopo la query multimediale prefers-reduced-data, CSS può contribuire al miglioramento dell'esperienza utente e svolgere il suo ruolo nel risparmio di dati.

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

Il CSS precedente viene utilizzato in questo componente di scorrimento dei contenuti multimediali e i risparmi possono essere enormi. A seconda delle dimensioni dell'area visibile visitata, maggiore è il risparmio sul caricamento della pagina. Il salvataggio continua mentre gli utenti interagiscono con gli scorrimento dei contenuti multimediali. Le immagini hanno tutte attributi loading="lazy" e, se combinati con il CSS che nasconde completamente l'elemento, non viene mai effettuata una richiesta di rete per l'immagine.

Screenshot dell&#39;interfaccia di un carosello di programmi TV con molte miniature e titoli.

Per i miei test, in un'area visibile di medie dimensioni sono state caricate inizialmente 40 richieste e 700 KB di risorse. Man mano che l'utente scorre la selezione dei contenuti multimediali, vengono caricati più richieste e risorse. Con CSS e la media query per la riduzione dei dati, vengono caricate 10 richieste e 172 KB di risorse. Si tratta di un risparmio di mezzo megabyte e l'utente non ha ancora scorri nessuno dei contenuti multimediali, a quel punto non vengono effettuate richieste aggiuntive.

Screenshot dell&#39;interfaccia di un carosello di programmi TV senza miniature e con molti titoli visualizzati.

Questa esperienza con dati ridotti offre più vantaggi del semplice risparmio di dati. Puoi vedere più titoli e non ci sono copertine che distraggono. Molti utenti navigano in modalità Risparmio dati perché pagano a megabyte di dati. È davvero bello vedere che CSS può essere d'aiuto in questo caso.

Risorse

Le funzionalità di scorrimento controllato sono troppo limitate

Prima di queste proposte di scorrimento agganciato, scrivere il proprio JavaScript per gestire un carosello, un cursore o una galleria poteva diventare rapidamente complesso, con tutti gli osservatori e la gestione dello stato. Inoltre, se non si presta attenzione, le velocità di scorrimento naturale potrebbero essere normalizzate dallo script, rendendo l'interazione dell'utente un po' innaturale e potenzialmente goffa.

Nuove API

snapChanging()

Questo evento viene attivato non appena il browser rilascia un elemento figlio dello snap. Ciò consente all'interfaccia utente di riflettere la mancanza di uno snap figlio e lo stato di snap indeterminato dello scroller, poiché ora viene utilizzato e si fermerà in una nuova posizione.

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()

Questo evento viene attivato non appena il browser si sposta su un nuovo elemento figlio e lo scorrimento si arresta. In questo modo, qualsiasi UI che dipende dal bambino agganciato viene aggiornata e riflette la connessione.

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

Lo scorrimento non inizia sempre dall'inizio. Prendi in considerazione i componenti scorrevoli in cui lo scorrimento verso sinistra o destra attiva eventi diversi oppure una barra di ricerca che al caricamento della pagina è inizialmente nascosta finché non scorri verso l'alto. Questa proprietà CSS consente agli sviluppatori di specificare che uno scorrimento deve iniziare da un punto specifico.

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
:snap-target

Questo selettore CSS corrisponderà agli elementi di un contenitore di scorrimento attualmente agganciati dal browser.

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

Dopo queste proposte di scorrimento rapido, creare un cursore, un carosello o una galleria è molto più semplice, poiché il browser ora offre comodità per l'attività, eliminando gli osservatori e il codice di orchestrazione dello scorrimento a favore dell'utilizzo di API integrate.

Siamo ancora agli albori di queste funzionalità CSS e JS, ma tieni d'occhio i polyfill che possono contribuire alla loro adozione e al loro test a breve.

Risorse

Ciclo tra gli stati noti

Prima del giorno toggle(), per lo stile e l'interazione potevano essere utilizzati solo gli stati integrati nel browser. L'input della casella di controllo, ad esempio, ha :checked, uno stato del browser gestito internamente per l'input che CSS può utilizzare per modificare visivamente l'elemento.

Dopo il giorno toggle(), è possibile creare stati personalizzati su qualsiasi elemento per consentire al CSS di modificarli e utilizzarli per lo stile. Consente di raggruppare, pedalare, attivare/disattivare in modo mirato e altro ancora.

Nell'esempio seguente, lo stesso effetto di una riga barrata in un elenco viene ottenuto senza alcun elemento di casella di controllo:

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

e gli stili CSS toggle() pertinenti:

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}

Se hai familiarità con le macchine a stati, potresti notare quanto si sovrappongono a toggle(). Questa funzionalità consentirà agli sviluppatori di integrare più stati nel CSS, con la speranza di ottenere modi più chiari e semantici di orchestrare l'interazione e lo stato.

Risorse

Personalizzare gli elementi di selezione

Prima di <selectmenu>, CSS non aveva la possibilità di personalizzare gli elementi <option> con HTML avanzato o modificare molti aspetti della visualizzazione di un elenco di opzioni. Ciò ha portato gli sviluppatori a caricare librerie esterne che ricreavano gran parte delle funzionalità di un <select>, il che si è rivelato un lavoro molto impegnativo.

Dopo il giorno <selectmenu>, gli sviluppatori possono fornire HTML avanzato per gli elementi delle opzioni e applicare lo stile che preferiscono, rispettando comunque i requisiti di accessibilità e fornendo HTML semantico.

Nell'esempio seguente, tratto dalla <selectmenu> pagina esplicativa, viene creato un nuovo menu di selezione con alcune opzioni di base:

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

CSS può scegliere come target e applicare uno stile alle parti dell'elemento:

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

Un menu dall&#39;aspetto elegante con colori di accento rossi.

Puoi provare l'elemento <selectmenu> su Chromium in Canary con il flag web experiments attivato. Nel 2023 e negli anni successivi, saranno disponibili elementi del menu di selezione personalizzabili.

Risorse

Ancorare un elemento a un altro

Prima di anchor(), le posizioni assoluta e relativa erano strategie di posizionamento fornite agli sviluppatori per spostare gli elementi secondari all'interno di un elemento principale.

Dopo anchor(), gli sviluppatori possono posizionare gli elementi rispetto ad altri elementi, indipendentemente dal fatto che siano secondari o meno. Consente inoltre agli sviluppatori di specificare il bordo rispetto al quale posizionare gli elementi e altre funzionalità per creare relazioni di posizione tra gli elementi.

La spiegazione include alcuni ottimi esempi e campioni di codice, se ti interessa saperne di più.

Risorse