Houdini: Forse lo sviluppo più eccitante nei CSS di cui non hai mai sentito parlare

Pubblicato: 2022-03-10
Riassunto veloce ↬ Hai mai desiderato utilizzare una particolare funzione CSS ma non l'hai fatto perché non era completamente supportata in tutti i browser ? O, peggio, era supportato in tutti i browser, ma il supporto era buggato, incoerente o addirittura del tutto incompatibile? Se ti è successo - e scommetto che è successo - allora dovresti preoccuparti di Houdini. Houdini è una nuova task force del W3C il cui obiettivo finale è far sparire per sempre questo problema. Ha in programma di farlo introducendo un nuovo set di API che, per la prima volta, darà agli sviluppatori il potere di estendere lo stesso CSS e gli strumenti per agganciarsi al processo di stile e layout del motore di rendering di un browser.

Hai mai desiderato utilizzare una particolare funzione CSS ma non l'hai fatto perché non era completamente supportata in tutti i browser ? O, peggio, era supportato in tutti i browser, ma il supporto era buggato, incoerente o addirittura del tutto incompatibile? Se ti è successo - e scommetto che è successo - allora dovresti preoccuparti di Houdini.

Houdini è una nuova task force del W3C il cui obiettivo finale è far sparire per sempre questo problema. Ha in programma di farlo introducendo un nuovo set di API che, per la prima volta, darà agli sviluppatori il potere di estendere lo stesso CSS e gli strumenti per agganciarsi al processo di stile e layout del motore di rendering di un browser .

Ulteriori letture su SmashingMag:

  • Perché dovresti interrompere l'installazione del tuo ambiente WebDev in locale
  • Il futuro dei CSS: proprietà CSS sperimentali
  • 53 tecniche CSS senza le quali non potresti vivere

Ma cosa significa, nello specifico? È anche una buona idea? E in che modo aiuterà noi sviluppatori a creare siti Web ora e in futuro?

Altro dopo il salto! Continua a leggere sotto ↓

In questo articolo cercherò di rispondere a queste domande. Ma prima di farlo, è importante chiarire quali sono i problemi oggi e perché c'è un tale bisogno di cambiamento. Parlerò quindi in modo più specifico di come Houdini risolverà questi problemi ed elencherò alcune delle funzionalità più interessanti attualmente in fase di sviluppo. Infine, offrirò alcune cose concrete che noi sviluppatori web possiamo fare oggi per contribuire a rendere Houdini una realtà.

Quali problemi sta cercando di risolvere Houdini?

Ogni volta che scrivo un articolo o costruisco una demo che mostra alcune nuove funzionalità CSS, inevitabilmente qualcuno nei commenti o su Twitter dirà qualcosa del tipo: "È fantastico! Peccato che non potremo usarlo per altri 10 anni”.

Per quanto fastidiosi e poco costruttivi siano commenti come questo, capisco il sentimento. Storicamente, ci sono voluti anni prima che le proposte di funzionalità ottenessero un'adozione diffusa. E il motivo è che, nel corso della storia del web, l'unico modo per ottenere una nuova funzionalità aggiunta ai CSS è stato passare attraverso il processo di standardizzazione.

Processo di standard
Le fasi del processo di standardizzazione. (Visualizza versione grande)

Anche se non ho assolutamente nulla contro il processo degli standard, non si può negare che può richiedere molto tempo!

Ad esempio, flexbox è stato proposto per la prima volta nel 2009 e gli sviluppatori si lamentano ancora di non poterlo utilizzare oggi a causa della mancanza di supporto per il browser. Certo, questo problema sta lentamente scomparendo perché quasi tutti i browser moderni ora si aggiornano automaticamente; ma anche con i browser moderni, ci sarà sempre un ritardo tra la proposta e la disponibilità generale di una funzionalità.

È interessante notare che questo non è il caso in tutte le aree del web. Considera come hanno funzionato di recente le cose in JavaScript:

Processo Polyfill
I passaggi del processo di polyfill. (Visualizza versione grande)

In questo scenario, il tempo che intercorre tra l'avere un'idea e l'utilizzo nella produzione a volte può essere questione di giorni. Voglio dire, sto già utilizzando le funzioni async / await in produzione e quella funzionalità non è stata implementata nemmeno in un singolo browser!

Puoi anche vedere un'enorme differenza nei sentimenti generali di queste due comunità. Nella comunità JavaScript, leggi articoli in cui le persone si lamentano del fatto che le cose si stanno muovendo troppo velocemente. Nei CSS, d'altra parte, senti persone lamentarsi dell'inutilità di imparare qualcosa di nuovo a causa di quanto tempo passerà prima che possano effettivamente usarlo.

Quindi, perché non scriviamo più Polyfill CSS?

A prima vista, scrivere più polyfill CSS potrebbe sembrare la risposta. Con buoni polyfill, CSS potrebbe muoversi alla stessa velocità di JavaScript, giusto?

Purtroppo, non è così semplice. Polyfilling CSS è incredibilmente difficile e, nella maggior parte dei casi, impossibile da fare in un modo che non distrugga completamente le prestazioni.

JavaScript è un linguaggio dinamico, il che significa che puoi utilizzare JavaScript per compilare JavaScript in polyfill. E poiché è così dinamico, è estremamente estensibile. I CSS, d'altra parte, possono essere usati raramente per il polyfill CSS. In alcuni casi, puoi trasporre CSS a CSS in una fase di compilazione (PostCSS lo fa); ma se vuoi polyfill qualsiasi cosa che dipenda dalla struttura del DOM o dal layout o dalla posizione di un elemento, dovresti eseguire la logica del tuo polyfill lato client.

Sfortunatamente, il browser non lo rende facile.

Il grafico seguente fornisce uno schema di base di come il tuo browser passa dalla ricezione di un documento HTML alla visualizzazione dei pixel sullo schermo. I passaggi colorati in blu mostrano dove JavaScript ha il potere di controllare i risultati:

Processo di rendering
Accesso JavaScript alla pipeline di rendering del browser. (Visualizza versione grande)

L'immagine è piuttosto cupa. Come sviluppatore, non hai alcun controllo su come il browser analizza HTML e CSS e lo trasforma nel modello a oggetti DOM e CSS (CSSOM). Non hai alcun controllo sulla cascata. Non hai alcun controllo su come il browser sceglie di disporre gli elementi nel DOM o su come dipinge visivamente quegli elementi sullo schermo. E non hai alcun controllo su ciò che fa il compositore.

L'unica parte del processo a cui hai pieno accesso è il DOM. Il CSSOM è alquanto aperto; tuttavia, per citare il sito Web di Houdini, è "sottospecificato, incoerente tra i browser e mancano funzionalità critiche".

Ad esempio, il CSSOM nei browser oggi non ti mostrerà le regole per i fogli di stile multiorigine e scarterà semplicemente le regole o le dichiarazioni CSS che non comprende, il che significa che se vuoi riempire una funzione in un browser che non lo supporta, non puoi usare CSSOM. Invece, devi passare attraverso il DOM, trovare i <style> e/o <link rel=“stylesheet”> , ottenere tu stesso il CSS, analizzarlo, riscriverlo e quindi aggiungerlo di nuovo al DOM.

Naturalmente, l'aggiornamento del DOM di solito significa che il browser deve quindi ripetere l'intero passaggio a cascata, layout, pittura e composito.

Processo di rendering Polyfilled
Polyfilling della pipeline di rendering del browser con JavaScript. (Visualizza versione grande)

Anche se dover eseguire nuovamente il rendering di una pagina potrebbe non sembrare un grande successo in termini di prestazioni (soprattutto per alcuni siti Web), considera la frequenza con cui ciò potrebbe potenzialmente accadere. Se la logica del tuo polyfill deve essere eseguita in risposta a cose come eventi di scorrimento, ridimensionamento della finestra, movimenti del mouse, eventi della tastiera - davvero ogni volta che qualcosa cambia - allora le cose saranno notevolmente, a volte anche paralizzanti, lente.

Questo peggiora ancora quando ti rendi conto che la maggior parte dei polyfill CSS disponibili oggi include il proprio parser CSS e la propria logica a cascata. E poiché l'analisi e la cascata sono in realtà cose molto complicate, questi polyfill sono solitamente troppo grandi o troppo pieni di bug.

Per riassumere tutto ciò che ho appena detto in modo più conciso: se vuoi che il browser faccia qualcosa di diverso da quello che pensa dovrebbe fare (dato il CSS che gli hai dato), allora devi trovare un modo per falsificarlo aggiornando e modificando tu stesso il DOM. Non hai accesso agli altri passaggi nella pipeline di rendering.

Ma perché mai dovrei voler modificare il motore di rendering interno del browser?

Questa, per me, è in assoluto la domanda più importante a cui rispondere in tutto questo articolo. Quindi, se finora hai scremato le cose, leggi questa parte lentamente e attentamente!

Dopo aver esaminato l'ultima sezione, sono sicuro che alcuni di voi stavano pensando: “Non ho bisogno di questo! Sto solo costruendo normali pagine web. Non sto cercando di hackerare le parti interne del browser o di creare qualcosa di super sofisticato, sperimentale o all'avanguardia".

Se stai pensando questo, ti consiglio vivamente di fare un passo indietro per un secondo ed esaminare davvero le tecnologie che hai utilizzato per creare siti Web nel corso degli anni. Volere l'accesso e l'aggancio al processo di stile del browser non significa solo creare demo fantasiose, ma dare a sviluppatori e autori di framework il potere di fare due cose principali:

  • per normalizzare le differenze tra browser,
  • per inventare o compilare nuove funzionalità in modo che le persone possano usarle oggi.

Se hai mai utilizzato una libreria JavaScript come jQuery, hai già beneficiato di questa capacità! In effetti, questo è uno dei principali punti di forza di quasi tutte le librerie e i framework front-end di oggi. I cinque repository JavaScript e DOM più popolari su GitHub — AngularJS, D3, jQuery, React ed Ember — fanno tutti molto lavoro per normalizzare le differenze tra browser in modo da non doverci pensare. Ognuno espone una singola API e funziona.

Ora, pensa ai CSS e a tutti i suoi problemi tra browser. Anche i framework CSS più diffusi come Bootstrap e Foundation che affermano la compatibilità cross-browser in realtà non normalizzano i bug cross-browser: li evitano semplicemente. E i bug cross-browser nei CSS non sono solo un ricordo del passato. Ancora oggi, con i nuovi moduli di layout come flexbox, ci troviamo di fronte a molte incompatibilità cross-browser.

La linea di fondo è, immagina quanto sarebbe più piacevole la tua vita di sviluppo se potessi utilizzare qualsiasi proprietà CSS e sapere per certo che avrebbe funzionato, esattamente lo stesso, in ogni browser. E pensa a tutte le nuove funzionalità di cui leggi nei post del blog o di cui senti parlare a conferenze e meetup: cose come le griglie CSS, i punti di snap CSS e il posizionamento appiccicoso. Immagina di poterli utilizzare tutti oggi e in un modo che fosse performante come le funzionalità CSS native. E tutto ciò che devi fare è prendere il codice da GitHub.

Questo è il sogno di Houdini. Questo è il futuro che la task force sta cercando di rendere possibile.

Quindi, anche se non hai mai in programma di scrivere un polyfill CSS o di sviluppare una funzionalità sperimentale, probabilmente vorresti che altre persone fossero in grado di farlo, perché una volta che questi polyfill esistono, tutti ne traggono vantaggio.

Quali funzionalità di Houdini sono attualmente in fase di sviluppo?

Ho detto sopra che gli sviluppatori hanno pochissimi punti di accesso nella pipeline di rendering del browser. In realtà, gli unici posti sono il DOM e, in una certa misura, il CSSOM.

Per risolvere questo problema, la task force Houdini ha introdotto diverse nuove specifiche che, per la prima volta, consentiranno agli sviluppatori di accedere alle altre parti della pipeline di rendering. Il grafico seguente mostra la pipeline e quali nuove specifiche possono essere utilizzate per modificare quali passaggi. (Si noti che le specifiche in grigio sono pianificate ma devono ancora essere scritte.)

Copertura delle specifiche
Dove le nuove specifiche Houdini si adattano alla pipeline di rendering del browser. (Visualizza versione grande)

Le prossime sezioni forniscono una breve panoramica di ogni nuova specifica e del tipo di funzionalità che offre. Dovrei anche notare che altre specifiche non sono menzionate in questo articolo; per l'elenco completo, vedere il repository GitHub delle bozze di Houdini.

API di analisi CSS

L'API CSS Parser non è attualmente scritta; quindi, gran parte di ciò che dico potrebbe facilmente cambiare, ma l'idea di base è che consente agli sviluppatori di estendere il parser CSS e parlargli di nuovi costrutti, ad esempio nuove regole multimediali, nuove pseudo-classi, annidamento, @extends , @apply , ecc.

Una volta che il parser conosce questi nuovi costrutti, può metterli nel posto giusto nel CSSOM, invece di scartarli.

API di proprietà e valori CSS

I CSS hanno già proprietà personalizzate e, come ho già detto, sono molto entusiasta delle possibilità che sbloccano. L'API CSS Properties and Values ​​porta le proprietà personalizzate un ulteriore passo avanti e le rende ancora più utili aggiungendo tipi.

Ci sono molte cose interessanti nell'aggiunta di tipi alle proprietà personalizzate, ma forse il più grande punto di forza è che i tipi consentiranno agli sviluppatori di eseguire la transizione e animare le proprietà personalizzate, cosa che non possiamo fare oggi.

Considera questo esempio:

 body { --primary-theme-color: tomato; transition: --primary-theme-color 1s ease-in-out; } body.night-theme { --primary-theme-color: darkred; }

Nel codice precedente, se la classe night-theme viene aggiunta all'elemento <body> , ogni singolo elemento nella pagina che fa riferimento al valore della proprietà –primary-theme-color passerà lentamente da tomato a darkred . Se volessi farlo oggi, dovresti scrivere manualmente la transizione per ciascuno di questi elementi, perché non puoi eseguire la transizione della proprietà stessa.

Un'altra caratteristica promettente di questa API è la possibilità di registrare un "apply hook", che offre agli sviluppatori un modo per modificare il valore finale di una proprietà personalizzata sugli elementi dopo il completamento del passaggio a cascata, che potrebbe essere una funzionalità molto utile per i polyfill.

CSS digitato OM

CSS Typed OM può essere considerato come la versione 2 dell'attuale CSSOM. Il suo obiettivo è risolvere molti dei problemi con il modello attuale e includere le funzionalità aggiunte dalla nuova API di analisi CSS e dall'API Proprietà e valori CSS.

Un altro obiettivo importante di Typed OM è migliorare le prestazioni. La conversione degli attuali valori di stringa del CSSOM in rappresentazioni JavaScript tipizzate in modo significativo produrrebbe sostanziali guadagni in termini di prestazioni.

API di layout CSS

L'API CSS Layout consente agli sviluppatori di scrivere i propri moduli di layout. E per "modulo di layout" intendo qualsiasi cosa che possa essere passata alla proprietà di display CSS. Ciò offrirà agli sviluppatori, per la prima volta, un modo per creare layout performanti quanto i moduli di layout nativi come display: flex e display: table .

Come caso d'uso di esempio, la libreria di layout Masonry mostra la misura in cui gli sviluppatori sono disposti a spingersi oggi per ottenere layout complessi non possibili con i soli CSS. Sebbene questi layout siano impressionanti, sfortunatamente soffrono di problemi di prestazioni, specialmente su dispositivi meno potenti.

L'API CSS Layout funziona fornendo agli sviluppatori un metodo registerLayout che accetta un nome di layout (che viene successivamente utilizzato in CSS) e una classe JavaScript che include tutta la logica di layout. Ecco un esempio di base di come definire la masonry tramite registerLayout :

 registerLayout('masonry', class { static get inputProperties() { return ['width', 'height'] } static get childrenInputProperties() { return ['x', 'y', 'position'] } layout(children, constraintSpace, styleMap, breakToken) { // Layout logic goes here. } }

Se nulla nell'esempio sopra ha senso per te, non preoccuparti. La cosa principale di cui preoccuparsi è il codice nel prossimo esempio. Dopo aver scaricato il file masonry.js e averlo aggiunto al tuo sito web, puoi scrivere CSS in questo modo e tutto funzionerà:

 body { display: layout('masonry'); }

API di pittura CSS

L'API CSS Paint è molto simile all'API Layout sopra. Fornisce un metodo registerPaint che opera proprio come il metodo registerLayout . Gli sviluppatori possono quindi utilizzare la funzione paint() nei CSS ovunque sia prevista un'immagine CSS e passare il nome che è stato registrato.

Ecco un semplice esempio che dipinge un cerchio colorato:

 registerPaint('circle', class { static get inputProperties() { return ['--circle-color']; } paint(ctx, geom, properties) { // Change the fill color. const color = properties.get('--circle-color'); ctx.fillStyle = color; // Determine the center point and radius. const x = geom.width / 2; const y = geom.height / 2; const radius = Math.min(x, y); // Draw the circle \o/ ctx.beginPath(); ctx.arc(x, y, radius, 0, 2 * Math.PI, false); ctx.fill(); } });

E può essere utilizzato in CSS in questo modo:

 .bubble { --circle-color: blue; background-image: paint('circle'); }

Ora, l'elemento .bubble verrà visualizzato con un cerchio blu come sfondo. Il cerchio sarà centrato e avrà le stesse dimensioni dell'elemento stesso, qualunque esso sia.

Worklets

Molte delle specifiche sopra elencate mostrano esempi di codice (ad esempio registerLayout e registerPaint ). Se ti stai chiedendo dove inseriresti quel codice, la risposta è negli script del worklet.

I worklet sono simili ai web worker e consentono di importare file di script ed eseguire codice JavaScript che (1) può essere richiamato in vari punti della pipeline di rendering e (2) è indipendente dal thread principale.

Gli script del worklet limiteranno notevolmente i tipi di operazioni che è possibile eseguire, il che è fondamentale per garantire prestazioni elevate.

Scorrimento e animazione compositi

Sebbene non ci siano ancora specifiche ufficiali per lo scorrimento e l'animazione compositi, in realtà è una delle funzionalità di Houdini più note e attese. Le eventuali API consentiranno agli sviluppatori di eseguire la logica in un worklet del compositore, fuori dal thread principale, con il supporto per la modifica di un sottoinsieme limitato delle proprietà di un elemento DOM. Questo sottoinsieme includerà solo proprietà che possono essere lette o impostate senza forzare il motore di rendering a ricalcolare il layout o lo stile (ad esempio, trasformazione, opacità, offset di scorrimento).

Ciò consentirà agli sviluppatori di creare animazioni basate su input e scroll altamente performanti, come intestazioni di scorrimento appiccicose ed effetti di parallasse. Puoi leggere di più sui casi d'uso che queste API stanno tentando di risolvere su GitHub.

Sebbene non ci siano ancora specifiche ufficiali, lo sviluppo sperimentale è già iniziato in Chrome. In effetti, il team di Chrome sta attualmente implementando punti di snap CSS e posizionamento permanente utilizzando le primitive che queste API alla fine esporranno. Questo è sorprendente perché significa che le API Houdini sono abbastanza performanti da poter creare nuove funzionalità di Chrome su di esse. Se avevi ancora dei timori che Houdini non sarebbe stato veloce come nativo, questo fatto da solo dovrebbe convincerti del contrario.

Per vedere un esempio reale, Surma ha registrato un video demo eseguito su una build interna di Chrome. La demo imita il comportamento dell'intestazione di scorrimento visto nelle app mobili native di Twitter. Per vedere come funziona, controlla il codice sorgente.

Cosa puoi fare ora?

Come accennato, penso che tutti coloro che creano siti Web dovrebbero preoccuparsi di Houdini; renderà tutte le nostre vite molto più facili in futuro. Anche se non utilizzi mai direttamente una specifica Houdini, quasi sicuramente utilizzerai qualcosa costruito su di essa.

E anche se questo futuro potrebbe non essere immediato, è probabilmente più vicino di quanto molti di noi pensino. I rappresentanti di tutti i principali fornitori di browser hanno partecipato all'ultimo incontro faccia a faccia di Houdini a Sydney all'inizio di quest'anno e non c'è stato molto disaccordo su cosa costruire o su come procedere.

Da quello che ho potuto dire, non è una questione di se Houdini sarà una cosa, ma quando, ed è qui che entrate tutti voi.

I fornitori di browser, come tutti gli altri che creano software, devono dare la priorità alle nuove funzionalità. E quella priorità è spesso una funzione di quanto gli utenti desiderano queste funzionalità.

Quindi, se ti interessa l'estendibilità dello stile e del layout sul Web e se vuoi vivere in un mondo in cui puoi utilizzare le nuove funzionalità CSS senza dover aspettare che passino attraverso il processo di standard, parla con i membri del team di relazioni con gli sviluppatori per i browser che utilizzi e di' loro che lo desideri.

L'altro modo in cui puoi aiutare è fornire casi d'uso del mondo reale, cose che vuoi essere in grado di fare con lo stile e il layout che sono difficili o impossibili da fare oggi. Molte delle bozze su GitHub hanno documenti sui casi d'uso e puoi inviare una richiesta pull per contribuire con le tue idee. Se un documento non esiste, puoi avviarne uno.

I membri della task force Houdini (e del W3C in generale) vogliono davvero un contributo ponderato dagli sviluppatori web. La maggior parte delle persone che partecipano al processo di scrittura delle specifiche sono ingegneri che lavorano sui browser. Spesso non sono sviluppatori web professionisti, il che significa che non sempre sanno dove sono i punti deboli.

Dipendono da noi per dirglielo.

Risorse e collegamenti

  • CSS-TAG Houdini Editor Drafts, W3C L'ultima versione pubblica di tutte le bozze Houdini
  • CSS-TAG Houdini Task Force Specifiche, GitHub Il repository ufficiale di Github in cui avvengono gli aggiornamenti e lo sviluppo delle specifiche
  • Esempi Houdini, esempi di codice GitHub che mostrano e sperimentano possibili API
  • Mailing list Houdini, W3C Un posto dove porre domande di carattere generale

Un ringraziamento speciale ai membri di Houdini Ian Kilpatrick e Shane Stephens per aver recensito questo articolo.