Query sugli elementi e come utilizzarli oggi

Pubblicato: 2022-03-10
Riassunto veloce ↬ Per un po' di tempo ci siamo imbattuti nei limiti di ciò che i CSS possono fare . Coloro che creano layout reattivi ammetteranno liberamente le frustrazioni e le carenze dei CSS che ci costringono a ricorrere a preprocessori CSS, plug-in e altri strumenti per aiutarci a scrivere gli stili che non siamo in grado di scrivere con i CSS da soli. Tuttavia, ci imbattiamo in dei limiti con ciò che gli strumenti attuali ci aiutano a realizzare.

Pensa per un momento a una struttura fisica. Se stai costruendo un grande edificio con materiale debole, è necessario molto supporto esterno per tenerlo insieme e le cose devono essere sovradimensionate per rimanere robuste. Quando crei un sito Web con HTML, CSS e JavaScript, questo supporto esterno potrebbe assomigliare a framework, plug-in, preprocessori, transpiler, strumenti di modifica, gestori di pacchetti e processi di compilazione.

Altro dopo il salto! Continua a leggere sotto ↓

Invece di aggiungere ancora un altro plug-in in cima allo stack, mi chiedevo se, estendendo uno dei linguaggi principali, CSS , avremmo potuto rafforzare il materiale da cui sono costruiti i siti Web, sviluppando siti Web migliori e più forti che richiedono meno supporto e strumenti esterni costruire.

Le query sullo stato attuale degli elementi

Con strumenti come i preprocessori CSS, scriviamo CSS in forma abbreviata, da espandere in seguito nella sua forma completa (prima di essere visualizzati in un browser). I plugin sono in grado di operare sulla pagina insieme agli elementi che influenzano, ma per applicare gli stili, scrivono gli stili CSS direttamente in HTML o attivano i nomi delle classi che applicano regole CSS diverse. In entrambi i casi, dobbiamo scrivere o generare il CSS di cui avremo bisogno prima che la pagina venga effettivamente caricata.

Il problema

Il problema con questo metodo è che anche i migliori plugin spesso richiedono personalizzazione e configurazione in ogni layout che utilizzi. Inoltre, quando JavaScript scrive stili per te, può essere difficile tenere insieme la logica basata su plug-in e gli stili CSS durante il refactoring o il riutilizzo del codice.

Un altro problema con i preprocessori è che qualsiasi errore scritto in stenografia si gonfia rapidamente in un pasticcio molto più grande una volta che il CSS è stato espanso nella sua forma completa. Quando si utilizzano i plug-in, aggiungiamo molti potenziali punti di errore. Potremmo utilizzare più plugin per realizzare una manciata di cose diverse che potrebbero non essere tutte inutili se i CSS fossero un po' più potenti. Ciò crea un onere aggiuntivo da mantenere per gli sviluppatori, per il rendering dei browser e per il download da parte degli utenti.

C'è qualche speranza per il futuro dello sviluppo web?

Nel 2013, Tyson Matanich ha scritto un articolo intitolato "Le query sui media non sono la risposta: Polyfill delle query sugli elementi", che ha introdotto il concetto di query sugli elementi a un vasto pubblico. Ha dato il via a una discussione su come creare plug-in e polyfill per aggirare le carenze dei CSS.

Da allora, mentre aspettiamo che le funzionalità CSS avanzino, sono stati rilasciati numerosi plug-in che consentono agli sviluppatori di utilizzare le query sugli elementi in diversi modi.

Cosa sono le query sugli elementi?

Le query degli elementi sono come le query multimediali, tranne per il fatto che le loro regole si applicano alle proprietà degli elementi effettivi, piuttosto che a quelle del viewport del browser.

Come è nato EQCSS

Alla fine del 2013, mi sono ritrovato a lavorare sul front-end di un'app Web Ruby on Rails. L'app doveva mostrare informazioni dettagliate agli utenti e l'obiettivo era creare un'interfaccia reattiva che funzionasse ugualmente bene su telefoni, tablet e browser desktop. Ciò ha posto alcune sfide, una delle quali era che gran parte del contenuto importante da visualizzare era visualizzato al meglio nelle tabelle: sì, gli elementi della table effettivi (per mostrare transazioni finanziarie, record sportivi, ecc.).

Il progetto EQCSS è nato come risultato di una ricerca sulle query sui media degli elementi. Ora è stato finalmente rilasciato e puoi usarlo oggi. Controlla le demo.

Ho creato stili reattivi utilizzando media query che visualizzavano correttamente l'elemento della table per browser di diverse dimensioni. Ma non appena una di quelle tabelle reattive è stata visualizzata in un modello che conteneva una barra laterale, improvvisamente tutti i miei punti di interruzione reattivi si sono trasformati in punti di rottura reattivi. Semplicemente non tenevano conto della barra laterale larga 200 pixel, facendo sì che le cose si sovrapponessero e appaiano rotte.

Un altro ostacolo: i nomi utente variavano in lunghezza da 3 a 20 caratteri e mi sono ritrovato a desiderare di poter regolare automaticamente la dimensione del carattere di ciascun nome utente in base al numero di caratteri che conteneva. Avevo bisogno di inserire ogni nome utente nella barra laterale ed era difficile scegliere una dimensione del carattere abbastanza piccola da contenere un nome utente di 20 caratteri ma abbastanza grande da consentire allo spettatore di vedere un nome utente di 3 caratteri.

Per aggirare problemi come questi, mi trovavo spesso a copiare intere query multimediali, duplicando ampie sezioni della mia base di codice, semplicemente perché avevo bisogno di un modo più intelligente per applicare gli stili reattivi in ​​ogni layout. Mi sono affidato a JavaScript come un'altra soluzione improvvisata, scrivendo molte funzioni quasi identiche che avrebbero guardato una pagina e applicato stili in luoghi in cui i CSS non potevano raggiungere. Dopo un po', il carico aggiuntivo di tutto questo codice duplicato ha iniziato ad appesantire la base del codice e ha reso difficili le modifiche.

Sapevo che doveva esserci una soluzione migliore e dopo un po' ho iniziato a pensare: non ho bisogno di media query, quello di cui ho bisogno sono le query sugli elementi!

Ricerca e sviluppo

Nel 2014 ho iniziato a sperimentare modi diversi per informare i CSS sulle proprietà degli elementi così come apparivano sulla pagina, in modo da poter applicare stili migliori. Speravo di scoprire un approccio che mi avrebbe permesso di scrivere stili che combinassero la bellezza dei CSS con la potenza di JavaScript.

Alcuni approcci abbandonati a cui ho rinunciato includono l'aggiunta di attributi ai tag HTML per aggiungere un supporto reattivo e il tentativo di trovare modi per incorporare interi blocchi di codice CSS all'interno di istruzioni if ​​basate su JavaScript per produrre una sorta di mostro di Frankenstein rattoppato da JavaScript e CSS.

Ma invece di rendere le cose più facili, tutti i miei approcci falliti avevano una cosa in comune: hanno aggiunto più lavoro! Sapevo che la soluzione giusta avrebbe semplificato e ridotto il lavoro da svolgere, quindi ho continuato a cercare. Attraverso questi esperimenti, mi sono ritrovato con un'idea precisa del tipo di sintassi necessaria per il corretto funzionamento delle query sugli elementi.

Come accennato, per un sito Web creato da HTML, CSS e JavaScript, il supporto esterno si presenta sotto forma di framework, plug-in, preprocessori, transpiler, strumenti di modifica, gestori di pacchetti e processi di compilazione. Invece di aggiungere ancora un altro plug-in in cima allo stack, mi chiedevo se, estendendo uno dei linguaggi principali, CSS, potessimo rafforzare il materiale con cui sono costruiti i siti Web, costruendo siti Web migliori e più forti che richiedono meno supporto esterno e strumenti per costruire.

La nascita di una sintassi

Entro la fine del 2014, dotato di una migliore visione della sintassi necessaria, ho contattato Maxime Euziere, un fenomenale golfer di codice JavaScript e gli ho chiesto la sua opinione sulla possibilità di estendere CSS utilizzando JavaScript nel browser in fase di runtime. Non solo mi ha informato che è possibile, ma si è offerto di aiutarmi a farlo! Abbiamo chiamato la sintassi EQCSS, abbreviazione di "element query CSS". Il nome è anche un cenno alla parola "eccesso", perché tutto ciò che fa è in eccesso rispetto a ciò che può fare CSS.

L'esigenza

Il mio requisito per la sintassi era che fosse il più vicino possibile al CSS , così vicino che gli evidenziatori della sintassi sarebbero stati ingannati nel pensare che fosse CSS standard. Quindi, ho mappato la sintassi CSS per le query sugli elementi che avevano un senso: il tipo di sintassi che sorprende le persone non esiste già.

Sapevo che se avessimo esteso il supporto del browser per CSS utilizzando JavaScript, il plug-in avrebbe dovuto essere il più leggero e semplice possibile per portare a termine il lavoro, il che escludeva l'uso di librerie come jQuery per creare il plug-in. Avevo bisogno di una libreria JavaScript pura che aggiungesse le funzionalità che desidero in futuro nei browser che devo supportare oggi.

In questo momento, la discussione nella comunità CSS è incentrata sulle regole @ personalizzate e le discussioni sulle query sugli elementi sono ancora preliminari. Probabilmente siamo ancora lontani anni da qualsiasi specifica CSS ufficiale per funzionalità come questa e, anche dopo una specifica, dovremo comunque attendere un supporto sufficiente per il browser prima di poter utilizzare tali funzionalità nei siti Web.

Aspettare che queste funzionalità vengano aggiunte ai CSS non ha senso quando abbiamo bisogno di questa funzionalità per creare e riparare siti Web oggi.

Il risultato

Il risultato di questa ricerca è stata la creazione di una sintassi che include un nuovo set di condizioni reattive avanzate, stili con ambito e nuovi selettori per gli elementi di targeting, nonché una libreria JavaScript pura denominata EQCSS.js. Inoltre, il supporto per Internet Explorer (IE) 8 è stato fornito in un polyfill esterno opzionale. Sia il plug-in che il polyfill sono stati rilasciati con licenza MIT e sono gratuiti per tutti.

Casi d'uso per query sugli elementi

Sviluppatori di plugin

Durante la creazione di componenti e widget dell'interfaccia utente, gli sviluppatori spesso si trovano limitati dalle query multimediali. Spesso dobbiamo scegliere tra la creazione di molti layout diversi che possono essere configurati dalla persona che utilizza il plug-in e la semplificazione dell'interfaccia al punto da poter creare una soluzione unica.

Ma quando progettiamo plug-in e interfacce con query sugli elementi, possiamo facilmente scrivere stili reattivi che coprano tutte le situazioni che prevediamo, rendendoli davvero a prova di proiettile, indipendentemente dal contenuto inserito dall'utente o da dove viene visualizzato il plug-in. Supponiamo di poter modellare un widget con layout che vanno da 150 a 2000 pixel di larghezza. Quindi, indipendentemente da dove viene visualizzato quel widget su un sito Web, sarebbe sempre fantastico.

Costruttori di modelli

Durante la prototipazione di un sito Web, è comune riorganizzare gli elementi di design sulla pagina e pensare al design come a un insieme di componenti modulari. Se hai scritto query multimediali CSS, a volte questo può essere un caso di ottimizzazione prematura . Progettando con query elemento, mantieni le condizioni reattive indipendenti dal layout, offrendoti molta più flessibilità per spostare le cose senza dover rielaborare troppo gli stili.

Le cose che ho trovato particolarmente utili per aver progettato o simulato utilizzando le query degli elementi includono:

  • barre di navigazione,
  • modali,
  • moduli di iscrizione e di accesso,
  • piè di pagina,
  • grafici dei prezzi,
  • pagine di destinazione,
  • tavoli,
  • caselle di tabulazione,
  • fisarmoniche,
  • widget della barra laterale,
  • lettori multimediali,
  • sezioni testimoniali.

Qualsiasi elemento di design può essere "mirato" e portato ovunque, da pagina a pagina o da sito Web a sito Web.

Supporto del dispositivo

Uno dei problemi che si incontrano quando si supporta il Web su dispositivi mobili è l'abbondanza di hardware. Il mercato dei dispositivi è più frammentato che mai e ogni giorno compaiono nuovi dispositivi. Non possiamo più mantenere un elenco dei browser e dei dispositivi che supportiamo, quindi è fondamentale sapere che un design funziona ovunque, anche su dispositivi che non sono ancora stati rilasciati.

Utilizzando le query degli elementi, puoi progettare siti Web in un modo migliore ed eliminare alcune di queste differenze tra browser.

Molti articoli scritti di recente sulla necessità di query sugli elementi illustrano in dettaglio molti dei casi d'uso. Quindi, andiamo avanti con come usarli!

Come scrivere query sugli elementi

Iniziare con EQCSS è facile. Tutto ciò di cui hai bisogno per iniziare a utilizzare la sintassi EQCSS è includere JavaScript da qualche parte nel tuo HTML.

Download di EQCSS.js

Se vuoi clonare il progetto EQCSS da GitHub, puoi digitare:

 git clone https://github.com/eqcss/eqcss.git

Se usi npm, puoi aggiungere EQCSS al tuo progetto con il seguente comando:

 npm install eqcss

Aggiunta di EQCSS.js al tuo HTML

Dopo aver scaricato EQCSS, puoi aggiungerlo al tuo codice HTML con un tag di script :

 <script src="EQCSS.js"></script>

Questo file ( EQCSS.js ) include il supporto per tutti i browser attuali, incluso IE 9 e versioni successive. Per supportare IE 8, avremmo dovuto utilizzare molti altri polyfill. Tieni presente che IE 8 non supporta nemmeno le query multimediali CSS senza un polyfill, quindi è piuttosto sorprendente che siamo stati in grado di far funzionare anche le query sugli elementi lì. Per includere il supporto di IE 8 per un sito Web che utilizza EQCSS, aggiungi il seguente collegamento prima del collegamento al plug-in principale:

 <!‐‐[if lt IE 9]><script src="EQCSS‐polyfills.js"></script><![endif]‐‐>

Esecuzione di EQCSS

Per impostazione predefinita, il plug-in EQCSS calcolerà tutti gli stili che trova una volta caricata la pagina e anche ogni volta che rileva il ridimensionamento del browser, in modo simile alle query multimediali. Puoi anche chiamare EQCSS.apply() manualmente con JavaScript per ricalcolare gli stili in qualsiasi momento, il che può essere utile una volta aggiornato il contenuto della pagina.

Scrittura della query elemento CSS

Il plug-in EQCSS.js può leggere gli stili in un paio di modi diversi. Puoi includere EQCSS in qualsiasi tag di style su una pagina HTML. Puoi anche scrivere EQCSS in un foglio di stile CSS esterno.

Se desideri mantenere il tuo codice basato su EQCSS separato dal tuo CSS, puoi caricare la sintassi EQCSS utilizzando il tag script con il tipo impostato su text/eqcss . Puoi aggiungere stili in linea in un tag come questo, o collegarti a un foglio di stile .eqcss esterno con <script type=“text/eqcss” src=styles.eqcss></script> , che caricherebbe un file chiamato styles.eqcss .

Anatomia di una query di elemento

Ambito di stile

La sintassi in EQCSS per la scrittura di query di elementi è molto simile alla formattazione delle query multimediali CSS, ma invece di @media , iniziamo la query con @element . L'unica altra informazione che dobbiamo fornire è almeno un selettore a cui dovrebbero applicarsi questi stili. Ecco come creare un nuovo ambito per un elemento denominato <div class=“widget”> :

 @element '.widget' { }

L'elemento tra le virgolette (in questo caso, .widget ) può essere un qualsiasi selettore CSS valido. Con questa query, abbiamo creato un nuovo ambito sull'elemento .widget . Non abbiamo ancora incluso alcuna condizione reattiva per l'ambito, quindi qualsiasi stile in una query come questa si applicherebbe all'elemento con ambito in ogni momento.

Senza la possibilità di applicare gli stili a uno o più elementi (anziché all'intera pagina in una volta), non saremmo in grado di applicare query reattive solo a quegli elementi. Una volta creato quell'ambito a livello di elemento, utilizzare le funzionalità più avanzate della sintassi EQCSS diventa facile, come il metaselettore $parent , ad esempio, perché JavaScript ora ha un punto di riferimento da cui calcolare cose come il parentNode elemento. Questo è enorme!

Vero, CSS include già un selettore discendente diretto, con > , che ci consente di selezionare elementi che sono figli diretti dell'elemento specificato. Ma attualmente i CSS non offrono alcun modo per viaggiare nell'altra direzione su per l'albero genealogico, per selezionare un elemento che contenga un altro elemento, che si chiamerebbe il suo elemento genitore. La specifica "CSS Selectors Level 4" ora include un selettore :has() , che funziona in modo simile al selettore :has() di jQuery, ma attualmente il supporto del browser è nullo. CSS con ambito rende possibile un diverso tipo di selettore padre.

Ora che abbiamo aperto un ambito nel contesto dell'elemento .widget , possiamo scrivere stili dalla sua prospettiva per indirizzare il proprio elemento padre:

 @element '.widget' { $parent { /* These styles apply to the parent of .widget */ } }

Un altro esempio di selettori speciali che possono essere utilizzati in qualsiasi query di elemento sono i selettori $prev e $next , che rappresentano gli elementi di pari livello precedente e successivo. Anche se CSS può raggiungere il fratello successivo del nostro widget con un selettore come .widget + * , non c'è modo in CSS di tornare indietro e selezionare l'elemento che viene direttamente prima di un altro elemento.

 <section> <div>This will be the previous item</div> <div class="widget">This is the scoped element</div> <div>This will be the next item</div> </section> <style> @element '.widget' { $prev { /* These styles apply to the element before .widget */ } $next { /* These styles apply to the element after .widget */ } } </style>

Query sugli elementi

Gli sviluppatori utilizzano più frequentemente le query multimediali CSS per il design reattivo applicando stili in base all'altezza o alla larghezza del riquadro di visualizzazione del browser. La sintassi EQCSS supporta molti nuovi tipi di condizioni reattive. Invece di lavorare solo con la larghezza e l'altezza del browser, puoi scrivere stili che si applicano agli elementi in base alle loro proprietà, ad esempio quanti elementi figlio contiene o quanti caratteri o righe di testo sono presenti nell'elemento al momento .

L'aggiunta di queste condizioni reattive ai tuoi stili con ambito è simile a come formatteresti le media query: aggiungeresti and (condition: value) per ogni condizione che desideri controllare. In questo esempio, verificheremo se gli elementi .widget visualizzano almeno 500 pixel di larghezza sulla pagina.

 @element '.widget' and (min‐width: 500px) { /* CSS rules here */ }

La sintassi di una query di elemento è suddivisa come segue:

  • elemento query @element selector_list [ condition_list ] { css_code }
  • elenco dei selettori " css selector [ "," css selector ]* "
  • elenco delle condizioni and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
  • valore number [ css unit ]
  • condizione della query min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
  • unità CSS % | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax % | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax

Come altro esempio, ecco come scrivere una query che trasforma l'elemento body in rosso quando l'elemento .widget raggiunge 500 pixel di larghezza:

 @element '.widget' and (min‐width: 500px) { body { background: red; } }

Nota che l'elemento body cambia quando il .widget raggiunge una certa larghezza, non l'elemento .widget stesso!

Condizioni di ricerca degli elementi

Di seguito è riportato l'elenco completo delle condizioni reattive supportate da EQCSS.

Condizioni basate sulla larghezza

  • demo di min-width per pixel, demo per percentuali
  • demo max-width per pixel, demo per percentuali

Condizioni basate sull'altezza

  • demo min-height per pixel, demo per percentuali
  • demo max-height per pixel, demo per percentuali

Condizioni basate sul conteggio

  • demo di min-characters minimi per elementi a blocchi, demo per input di moduli
  • demo max-characters per elementi a blocchi, demo per input di moduli
  • demo min-lines minime
  • demo max-lines
  • demo min-children
  • demo max-children

Condizioni basate sullo scorrimento

  • demo min-scroll-y
  • demo max-scroll-y
  • demo min-scroll-x
  • demo max-scroll-x

Puoi combinare un numero qualsiasi di queste condizioni nelle query degli elementi per stili reattivi veramente multidimensionali. Questo ti dà molta più flessibilità e controllo sul modo in cui gli elementi vengono visualizzati. Ad esempio, per ridurre la dimensione del carattere di un'intestazione che contiene più di 15 caratteri quando sono disponibili meno di 600 pixel di spazio per la visualizzazione, è possibile combinare le condizioni per max‐characters: 15 e max‐width: 600px :

 h1 { font‐size: 24pt; } @element 'h1' and (min‐characters: 16) and (max‐width: 600px) { h1 { font‐size: 20pt; } }

Metaselettori

Uno dei problemi che potresti incontrare una volta che inizi a scrivere stili con ambito con condizioni reattive è che, quando più istanze dello stesso selettore si trovano su una pagina, l'utilizzo di quel selettore nella query dell'elemento applicherà gli stili a tutte le istanze di quel selettore sul pagina quando uno di essi soddisfa le condizioni. Prendendo i nostri esempi .widget di prima, supponiamo di avere due widget sulla pagina (forse uno nella barra laterale e un altro visualizzato a tutta larghezza) e di aver scritto la nostra query di elemento in questo modo:

 @element '.widget' and (min‐width: 500px) { .widget h2 { font‐size: 14pt; } }

Ciò significherebbe che quando uno degli elementi .widget sulla pagina è largo almeno 500 pixel, lo stile si applicherà a entrambi gli elementi .widget . Questo probabilmente non è ciò che vogliamo che accada nella maggior parte dei casi. È qui che entrano in gioco i meta-selettori!

Le due parti che compongono la nostra query di elemento sono il selettore e la condizione reattiva. Quindi, se vogliamo scegliere come target solo gli elementi della pagina che corrispondono contemporaneamente sia al selettore che alle condizioni reattive, possiamo utilizzare il meta selettore $this . Possiamo riscrivere il nostro ultimo esempio in modo che lo stile si applichi solo agli elementi .widget che corrispondono alla condizione min‐width: 500px :

 @element '.widget' and (min‐width: 500px) { $this h2 { font‐size: 14pt; } }

Un certo numero di nuovi selettori sono supportati dalla sintassi EQCSS che non sono nei normali CSS. Ecco l'elenco completo:

  • $this demo
  • $parent
  • $root demo
  • $prev
  • $next demo

Questi selettori funzioneranno solo in una query di elementi.

Aprire il portale tra JavaScript e CSS

  • eval(') demo

L'ultima e ultima caratteristica di EQCSS è la più selvaggia di tutte: eval(') . Attraverso questa porta si trova tutta la potenza di JavaScript, accessibile dai CSS. Sebbene JavaScript possa applicare stili agli elementi, attualmente ha difficoltà a raggiungere alcune cose, come gli pseudo-elementi :before e :after . Ma cosa accadrebbe se CSS potesse raggiungere JavaScript dall'altra direzione? Invece di impostare le proprietà CSS di JavaScript, cosa accadrebbe se CSS potesse essere a conoscenza di JavaScript?

È qui che entra in eval(') . Puoi accedere e valutare qualsiasi JavaScript, se utilizzare il valore di una variabile JavaScript nel tuo CSS, per eseguire un JavaScript one-liner (come eval('new Date().getFullYear()') ), per accertare i valori sul browser e altri elementi che JavaScript può misurare (come eval('innerHeight') ) o per eseguire una funzione JavaScript e utilizzare il valore che restituisce nei tuoi stili CSS. Ecco un esempio che restituisce 2016 in un elemento <footer> :

 @element 'footer' { $this:after { content: " eval('new Date().getFullYear()')"; } }

Usando $it inside eval(')

Durante la valutazione di JavaScript, eval(') funziona anche dal contesto dell'elemento con ambito attivo, lo stesso elemento a cui si applicano gli stili per $this . Puoi usare $it in JavaScript scritto in eval(') come segnaposto per l'elemento con ambito se ti aiuta a strutturare il codice, ma se omesso, funzionerà allo stesso modo. Ad esempio, supponiamo di avere un div con la parola "ciao". Il codice seguente genererebbe "ciao ciao":

 <div>hello</div> <style> @element 'div' { div:before { content: "eval('$it.textContent') "; } } </style>

Qui, $it riferisce al div perché è il selettore attualmente con ambito. Puoi anche omettere $it e scrivere il seguente codice per visualizzare la stessa cosa:

 @element 'div' { div:before { content: "eval('textContent') "; } }

eval(') può essere utile in situazioni in cui CSS non è a conoscenza di misurazioni o eventi che si verificano sulla pagina dopo che è stata caricata. Ad esempio, gli elementi iframe utilizzati per incorporare i video di YouTube hanno una larghezza e un'altezza specificate. Sebbene tu possa impostare la larghezza su auto in CSS, non esiste un modo semplice per mantenere le corrette proporzioni tra larghezza e altezza quando il video si espande per riempire lo spazio disponibile.

Una soluzione alternativa comune per mantenere le proporzioni reattive durante il ridimensionamento consiste nel posizionare il contenuto che deve mantenere le proporzioni in un wrapper, quindi aggiungere il riempimento al wrapper con un valore basato sul rapporto tra larghezza e altezza che si desidera mantenere. Funziona, ma richiede di conoscere in anticipo le proporzioni di tutti i video, oltre a richiedere più markup HTML (un elemento wrapper) per ogni video che desideri incorporare in modo reattivo. Moltiplicalo su ogni sito Web che ha video reattivi, e questo è un sacco di cruft che non dovrebbe esserci se i CSS fossero solo un po 'più intelligenti.

Forse un approccio migliore alle proporzioni reattive prevede il posizionamento di ogni video in un wrapper senza riempimento e quindi la scrittura di una libreria JavaScript che calcola le proporzioni di ogni video che trova e applica la corretta quantità di riempimento a ciascun wrapper.

Ma cosa accadrebbe se CSS potesse accedere direttamente a quelle misurazioni? Non solo potremmo consolidare il CSS per tutte le diverse proporzioni in un'unica regola, ma se potessimo valutarlo una volta caricata la pagina, potremmo scrivere una regola che ridimensiona in modo reattivo qualsiasi video che gli forniremo in futuro. E potremmo fare tutto senza involucri!

Se questo sembra troppo bello per essere vero, dai un'occhiata. Ecco com'è semplice scrivere elementi iframe senza wrapper ridimensionando in modo reattivo in EQCSS:

 @element 'iframe' { $this { margin: 0 auto; width: 100%; height: eval('clientWidth/(width/height)'); } }

Qui, width e height si riferiscono agli attributi width=“” e height=“” nell'iframe in HTML. JavaScript può eseguire il calcolo di (width/height) , che ci fornisce le proporzioni; e per applicarlo a qualsiasi larghezza, dividiamo semplicemente la larghezza corrente dell'elemento iframe per il rapporto.

Questo ha la concisione e la leggibilità dei CSS e tutta la potenza di JavaScript. Nessun wrapper aggiuntivo richiesto, nessuna classe extra e nessun CSS aggiuntivo.

Fai attenzione con eval(') , però. C'è un motivo per cui le espressioni CSS erano considerate pericolose in passato, e c'è anche un motivo per cui abbiamo provato l'idea. Se non stai attento a quanti elementi li stai applicando sulla pagina o con la frequenza con cui ricalcoli gli stili, JavaScript potrebbe finire per eseguire cose centinaia di volte più del necessario. Per fortuna, EQCSS ci consente di invocare EQCSS.apply() o EQCSS.throttle() per ricalcolare manualmente gli stili, in modo da avere un maggiore controllo sull'aggiornamento degli stili.

La zona di pericolo!

Possono verificarsi altri problemi se si creano query con condizioni o stili in conflitto. EQCSS, come CSS, viene letto dall'alto verso il basso utilizzando una gerarchia di specificità. Sebbene i CSS siano un linguaggio dichiarativo, contengono alcune funzionalità avanzate. Sono solo un paio di passi dall'essere Turing-completo come linguaggio di programmazione. Finora, il debug di CSS è stato un affare piuttosto semplice, ma EQCSS sposta i CSS dall'essere un semplice linguaggio dichiarativo interpretato ad essere un linguaggio di fogli di stile dinamico con un ulteriore livello di interpretazione tra CSS e il browser. Con questo nuovo territorio arriva una serie di potenziali nuove insidie.

Ecco un esempio di un ciclo reciproco in EQCSS, qualcosa a cui le normali media query CSS sono immuni in base alla progettazione:

 @element '.widget' and (min‐width: 300px) { $this { width: 200px; } }

Lo chiamo jekyll: hide; CSS. Ma oltre a uno stile che si attiva continuamente, c'è anche la possibilità di scrivere più query che si attivano a vicenda, in quello che chiamiamo un "ciclo reciproco a doppia inversione", il più brutto di tutti:

 @element '.widget' and (min‐width: 400px) { $this { width: 200px; } } @element '.widget' and (max‐width: 300px) { $this { width: 500px; } }

In teoria, quello sfortunato widget rimarrebbe bloccato in un loop, ridimensionando tra 200 e 500 pixel fino alla fine del tempo, incapace di accontentarsi di una larghezza. Per casi come questo, EQCSS calcola semplicemente le regole nell'ordine in cui vengono valutate, premia il vincitore e va avanti. Se dovessi riorganizzare l'ordine in cui appaiono queste regole, quest'ultimo stile vincerebbe sempre se hanno la stessa specificità.

Alcune persone dicono che la capacità di creare loop (o anche loop reciproci double-inverted) è un difetto di progettazione, ma per evitare che i loop siano possibili, dovresti limitare la potenza di EQCSS in modo da rimuovere la maggior parte dei il valore fornito dalla sintassi. D'altra parte, creare loop infiniti in JavaScript è molto semplice, ma non è visto come un difetto del linguaggio: è visto come una prova del suo potere! È lo stesso con le query sugli elementi.

Debug delle query sugli elementi

Attualmente, il debug delle query sugli elementi può sembrare un po' come il debug delle query multimediali prima che avessimo strumenti come l'ispettore Web per mostrarci gli stili così come venivano calcolati sulla pagina. Per ora, il debug e lo sviluppo di query sugli elementi richiedono allo sviluppatore di mantenere un modello mentale di quale comportamento reattivo dovrebbe verificarsi. In futuro, potrebbe essere possibile creare strumenti per sviluppatori compatibili con EQCSS, ma per ora gli strumenti per sviluppatori in tutti i principali browser sono a conoscenza solo degli stili che EQCSS ha già applicato agli elementi della pagina e non sono a conoscenza di le condizioni reattive che EQCSS sta osservando.

Come progettare con le query sugli elementi

Il modo più semplice per utilizzare le query degli elementi è convertire i progetti esistenti utilizzando le query multimediali in query degli elementi, "liberando" gli elementi e i loro stili reattivi da un layout e semplificando il riutilizzo di quel codice in altre pagine e progetti. La seguente query multimediale e query elemento potrebbe significare la stessa cosa:

 footer a { display: inline-block; } @media (max‐width: 500px) { footer a { display: block; } }
 footer a { display: inline-block; } @element 'footer' and (max‐width: 500px) { $this a { display: block; } }

La differenza è che, nell'esempio originale, i link a piè di pagina rimangono come display: block finché il browser non è largo almeno 500 pixel. Il secondo esempio, utilizzando le query degli elementi, avrebbe lo stesso aspetto ma solo se l'elemento del footer di pagina fosse a larghezza intera.

Dopo aver liberato questo stile dalla sua media query originale, ora possiamo posizionare il piè di pagina in un contenitore di qualsiasi larghezza ed essere sicuri che quando il piè di pagina ha bisogno dello stile reattivo da applicare (cioè quando è più stretto di 500 pixel), sarà applicato.

  1. Assicurati che EQCSS.js sia presente nell'HTML del documento di destinazione.
  2. Sostituisci @media con @element nel CSS.
  3. Aggiungi un selettore CSS all'ambito di ogni query @element .
  4. Facoltativo: sostituisci le occorrenze dell'elemento con ambito con $this nelle query degli elementi.

A meno che il componente di progettazione che stai convertendo non sia stato originariamente progettato per essere visualizzato utilizzando l'intera larghezza della finestra del browser, probabilmente dovrai modificare i punti di interruzione dopo la conversione in query di elementi.

Evitare il lock-in

L'esperienza di creazione di stili EQCSS è simile all'esperienza di scrittura di CSS normali: tutte le tue proprietà e tecniche CSS preferite sono ancora lì, solo con alcune funzionalità aggiuntive che li aiutano a lavorare insieme in nuovi modi. Poiché EQCSS restituisce CSS standard al browser, qualsiasi funzione CSS per cui il browser ha il supporto integrato funzionerà se utilizzata con EQCSS. Se un giorno le funzionalità come le query degli elementi e gli stili con ambito sono specificate in CSS e supportate nei browser, potresti iniziare a usarle immediatamente nel tuo codice EQCSS, continuando a fare affidamento su EQCSS per le altre funzionalità che il browser non ha tuttavia supporta in modo nativo.

Poiché puoi utilizzare la sintassi EQCSS sia direttamente nei CSS che nel proprio script, con il tipo text/eqcss , se CSS sviluppasse mai una sintassi per le query di elementi nativi, saresti comunque in grado di caricare EQCSS come script ed evitare conflitti .

Guardando al futuro, una soluzione che gli sviluppatori di browser stanno sperimentando in questo momento è Houdini, che aprirebbe l'accesso agli sviluppatori di plugin per estendere i CSS in nuovi modi, come aggiungere il supporto al browser stesso. Un giorno, potrebbe essere possibile scrivere plug-in più efficienti che interpretano la sintassi EQCSS e portano queste funzionalità ai browser in un modo più diretto e performante di quanto consentito dall'attuale libreria JavaScript.

Quindi, dovremmo ancora utilizzare le query sui media?

Sì, anche se le query sugli elementi forniscono molti modi nuovi ed entusiasmanti per indirizzare gli elementi con stili, le query multimediali (sebbene limitate) verranno sempre eseguite più velocemente nel browser rispetto a uno stile che si basa su JavaScript per il calcolo. Tuttavia, le media query CSS sono molto più di un semplice stile HTML per gli schermi. Le query multimediali CSS supportano anche le query basate sulla stampa e altri modi in cui i siti Web visualizzano le informazioni. EQCSS può essere utilizzato insieme alle media query per cose come gli stili di stampa, quindi non è necessario ritirare la media query solo perché ora è possibile utilizzare anche le query degli elementi!

Progettare con 2020 Vision

La cosa migliore che possiamo fare per il futuro dei CSS è sperimentare queste idee il più possibile oggi. Nessuna quantità di brainstorming e teorizzazione su queste funzionalità sarà utile quanto cercare effettivamente di implementarle e metterle in uso, scoprendo le tecniche che le rendono utili e potenti.

Oltre a fornire una soluzione per le query sugli elementi, si spera che EQCSS.js serva anche come piattaforma per altri esperimenti sull'estensione dei CSS. If you have an idea for a new responsive condition, a new CSS property or a new selector to use in your code, forking EQCSS.js and modifying it to include your idea can get you most of the way there with little effort.

Modular Design

In designing layouts using element queries, the biggest shift is learning how to stop viewing the DOM from the top down and from the perspective of only the root HTML element, and to start thinking about individual elements on the page from their own perspectives within the document.

The old paradigms of “desktop-first” and “mobile-first” responsive design aren't relevant any longer — the new way of building layouts approaches design “element-first.” Using element queries enables you to work on the individual parts that make up a layout, in isolation from one another, styling them to a greater level of detail. If you are using a modular approach for your back-end code already but have so far been unable to package your CSS with your modules because of the difficulties of styling with media queries alone, then element queries will finally allow you to modularize your styles in the same way.

Thinking Element-First

Element-first design is in the same spirit as the atomic design principle but looks different in practice from how most people have implemented atomic design in the past.

For example, let's say you have some HTML like the following, and the desired responsive behavior can be explained as, “The search input and button are displayed side by side until the form gets too narrow. Then, both the input and the button should be stacked on top of each other and displayed full width.”

 <form> <input type=search> <input type=button value=Search> </form>

Desktop-First Approach

In a desktop-first mindset, you would write styles for the desktop layout first and then add responsive support for smaller screens.

 input { width: 50%; float: left; } @media (max‐width: 600px) { input { width: 100%; float: none; } }

Mobile-First Approach

In a mobile-first mindset, you would design the mobile view first and add support for the side-by-side view only when the screen is wide enough.

 input { width: 100%; } @media (min‐width: 600px) { input { width: 50%; float: left; } }

Element-First Approach

In the first two examples, the media breakpoint was set to 600 pixels, and not because that's how wide the inputs will be when they switch. Chances are, the search input is probably inside at least one parent element that would have margins or padding. So, when the browser is 600 pixels wide, those inputs might be somewhere around 550 or 525 pixels wide on the page. In a desktop-first or mobile-first approach, you're always setting breakpoints based on the layout and how elements show up within it. With an element-first layout, you're saying, “I don't care how wide the browser is. I know that the sweet spot for where I want the inputs to stack is somewhere around 530 pixels wide.” Instead of using a media query to swap that CSS based on the browser's dimensions, with element-first design, we would scope our responsive style to the form element itself, writing a style like this:

 input { width: 100% } @element 'form' and (min‐width: 530px) { $this input { width: 50%; float: left; } }

The code is similar to that of the two previous methods, but now we are free to display this search input anywhere — in a sidebar or full width. We can use it in any layout on any website, and no matter how wide the browser is, when the form itself doesn't have enough room to display the inputs side by side, it will adapt to look its best.

Resources For Getting Started

EQCSS-Enabled Template

 <!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title></title> <style></style> </head> <body> <!‐‐[if lt IE 9]><script src="https://elementqueries.com/EQCSS‐polyfills.min.js"></script><![endif]‐‐> <script src="https://elementqueries.com/EQCSS.min.js"></script> </body> </html>

Demos

  • Responsive Aspect Ratio
  • Sticky Scroll Header
  • Blockquote Style
  • Calendario
  • Content Demo
  • Counting Children Demo
  • Date Demo
  • Zastrow-style Element Query Demo Demo
  • Flyout Demo
  • Headline Demo
  • Media Player Demo
  • Message Style Demo
  • Modal Demo
  • Nav Demo
  • Parent Selector Demo
  • Pricing Chart Demo
  • Responsive Tables Demo
  • Scroll-triggered Blocker Demo
  • Signup Form Demo
  • Testimonials Block Demo
  • Tweet-Counter Demo
  • JS Variables Demo
  • Responsive Scaling Demo
  • Geometric Design Demo
  • Responsive Order Form
  • Element Query Grid
  • JS Functions in CSS
  • Responsive Content Waterfall

Ulteriori letture

You can find the EQCSS project on GitHub, demos, documentation and articles on the EQCSS website. An ever-growing number of Codepens use EQCSS, and you can create your own pen by forking the batteries-included template that comes hooked up with EQCSS. You can also play with the EQCSS tool that I built to preview if your EQCSS code is working as expected.

Happy hacking!