Interogări despre elemente și cum le puteți utiliza astăzi

Publicat: 2022-03-10
Rezumat rapid ↬ De ceva timp, ne-am confruntat cu limitele a ceea ce poate face CSS . Cei care construiesc layout-uri responsive vor recunoaște în mod liber frustrările și neajunsurile CSS care ne obligă să apelăm la preprocesoare CSS, pluginuri și alte instrumente care să ne ajute să scriem stilurile pe care nu le putem scrie numai cu CSS. Chiar și totuși, ne confruntăm cu limitări cu ceea ce instrumentele actuale ne ajută să realizăm.

Gândiți-vă pentru o clipă la o structură fizică. Dacă construiți un edificiu mare cu material slab, este nevoie de mult sprijin extern pentru a-l ține împreună, iar lucrurile trebuie supraconstruite pentru a rămâne rezistente. Când construiți un site web din HTML, CSS și JavaScript, acest suport extern poate arăta ca cadre, pluginuri, preprocesoare, transpilere, instrumente de editare, manageri de pachete și procese de compilare.

Mai multe după săritură! Continuați să citiți mai jos ↓

În loc să adaug încă un plugin în partea de sus a stivei, m-am întrebat dacă, extinzând unul dintre limbajele de bază, CSS , am putea consolida materialul din care sunt construite site-urile web, dezvoltând site-uri web mai bune, mai puternice, care necesită mai puțin suport extern și instrumente. a construi.

Starea curentă a interogărilor elementului

Cu instrumente precum preprocesoarele CSS, scriem CSS pe scurt, pentru a fi extins ulterior în forma sa completă (înainte de a fi vizualizat într-un browser). Pluginurile pot funcționa pe pagină alături de elementele pe care le afectează, dar pentru a aplica stiluri, fie scriu stiluri CSS direct în HTML, fie comută numele claselor care aplică diferite reguli CSS. În ambele cazuri, trebuie să scriem sau să generăm CSS-ul de care vom avea nevoie înainte ca pagina să se încarce efectiv.

Problema

Problema cu această metodă este că chiar și cele mai bune pluginuri necesită adesea personalizare și configurare în fiecare aspect pe care îl utilizați. De asemenea, atunci când JavaScript scrie stiluri pentru dvs., poate fi dificil să păstrați împreună logica bazată pe plugin și stilurile dvs. CSS atunci când refactorizați sau reutilizați codul.

O altă problemă cu preprocesoarele este că orice erori scrise în scurtătură se transformă rapid într-o dezordine mult mai mare odată ce CSS-ul este extins în forma sa completă. Când folosim pluginuri, adăugăm multe puncte potențiale de eșec. Este posibil să folosim mai multe plugin-uri pentru a realiza o mână de lucruri diferite care ar putea fi toate inutile dacă CSS ar fi puțin mai puternic. Acest lucru creează o povară suplimentară de întreținut pentru dezvoltatori, pentru browsere pentru a reda și pentru utilizatori de descărcat.

Există vreo speranță pentru viitorul dezvoltării web?

În 2013, Tyson Matanich a scris un articol intitulat „Media Queries Are Not the Answer: Element Query Polyfill”, care a introdus conceptul de interogări de elemente unui public larg. A început o discuție despre modul în care ar putea fi construite pluginuri și polyfills pentru a naviga prin deficiențele CSS.

De atunci, în timp ce așteptăm ca funcțiile CSS să avanseze, au fost lansate o serie de pluginuri care permit dezvoltatorilor să folosească interogări de elemente în câteva moduri diferite.

Ce sunt interogările de elemente?

Interogările de elemente sunt ca interogările media, cu excepția faptului că regulile lor se aplică proprietăților elementelor reale, mai degrabă decât cele ale ferestrei de vizualizare a browserului.

Cum a apărut EQCSS

La sfârșitul anului 2013, m-am trezit lucrând la partea frontală a unei aplicații web Ruby on Rails. Aplicația trebuia să afișeze informații detaliate pentru utilizatori, iar scopul a fost să construiască o interfață receptivă care să aibă rezultate la fel de bine pe telefoane, tablete și browsere desktop. Acest lucru a reprezentat câteva provocări, una dintre acestea fiind că o mare parte din conținutul important care trebuia afișat a fost cel mai bine afișat în tabele - da, elemente reale ale table (pentru a afișa tranzacții financiare, înregistrări sportive etc.).

Proiectul EQCSS a venit ca rezultat al cercetării privind interogările element media. Acum, a fost lansat în sfârșit și îl puteți folosi astăzi. Verificați demo-urile.

Am creat stiluri responsive folosind interogări media care afișau corect elementul table pentru browsere de diferite dimensiuni. Dar de îndată ce unul dintre acele tabele receptive a fost afișat într-un șablon care conținea o bară laterală, brusc toate punctele mele de întrerupere receptive s-au transformat în puncte de întrerupere receptive. Pur și simplu nu au luat în considerare bara laterală de 200 de pixeli, ceea ce a făcut ca lucrurile să se suprapună și să pară rupte.

Un alt obstacol: Numele de utilizator variau în lungime de la 3 la 20 de caractere și mi-am dorit să pot ajusta automat dimensiunea fontului fiecărui nume de utilizator în funcție de numărul de caractere pe care îl conține. Trebuia să pun fiecare nume de utilizator în bara laterală și a fost dificil să aleg o dimensiune a fontului suficient de mică pentru a se potrivi unui nume de utilizator de 20 de caractere, dar suficient de mare pentru ca privitorul să vadă un nume de utilizator de 3 caractere.

Pentru a rezolva probleme de genul acesta, deseori m-am trezit copiend interogări media întregi, duplicând secțiuni mari din baza mea de cod, pur și simplu pentru că aveam nevoie de o modalitate mai inteligentă de a aplica stilurile responsive în fiecare aspect. M-am bazat pe JavaScript ca o altă soluție improvizată, scriind multe funcții aproape identice care ar urmări o pagină și ar aplica stiluri în locuri unde CSS nu ar putea ajunge. După un timp, sarcina adăugată a acestui cod duplicat a început să împovărească baza de cod și a făcut modificările dificil de făcut.

Știam că trebuie să existe o soluție mai bună și după un timp am început să mă gândesc: nu am nevoie de interogări media — ceea ce am nevoie sunt interogări de elemente!

Cercetare și dezvoltare

Prin 2014, am început să experimentez diferite moduri de a informa CSS-ul despre proprietățile elementelor așa cum au apărut pe pagină, astfel încât să pot aplica stiluri mai bune. Speram să descopăr o abordare care să-mi permită să scriu stiluri care combină frumusețea CSS cu puterea JavaScript.

Unele abordări abandonate la care am renunțat includ adăugarea de atribute la etichetele HTML pentru a adăuga suport receptiv și încercarea de a găsi modalități de a încorpora blocuri întregi de cod CSS în instrucțiunile if bazate pe JavaScript pentru a produce un fel de monstru Frankenstein corelat împreună din JavaScript. și CSS.

Dar, în loc să ușureze lucrurile, toate abordările mele eșuate aveau un lucru în comun: au adăugat mai multă muncă! Știam că soluția potrivită va simplifica și reduce munca care trebuie făcută, așa că am continuat să caut. Prin aceste experimente, am ajuns să am o idee rafinată a tipului de sintaxă care ar fi necesară pentru ca interogările de elemente să funcționeze bine.

După cum am menționat, pentru un site web construit din HTML, CSS și JavaScript, suportul extern vine sub formă de cadre, pluginuri, preprocesoare, transpilere, instrumente de editare, manageri de pachete și procese de compilare. În loc să adaug încă un plugin în partea de sus a stivei, m-am întrebat dacă, prin extinderea unuia dintre limbajele de bază, CSS, am putea consolida materialul din care sunt construite site-urile web, construind site-uri web mai bune, mai puternice, care necesită mai puțin suport extern și instrumente pentru a construi.

Nașterea unei sintaxe

Până la sfârșitul anului 2014, dotat cu o viziune mai bună asupra sintaxei necesare, l-am contactat pe Maxime Euziere, un jucător fenomenal de cod JavaScript și i-am cerut părerea despre posibilitatea extinderii CSS folosind JavaScript în browser în timpul execuției. Nu doar că m-a informat că se poate, dar s-a oferit să mă ajute să o fac! Am numit sintaxa EQCSS, prescurtare de la „element query CSS”. Numele este, de asemenea, un semn din cap către cuvântul „exces”, deoarece tot ceea ce face este peste ceea ce poate face CSS.

Necesitatea

Cerința mea pentru sintaxă a fost ca aceasta să fie cât mai aproape posibil de CSS - atât de aproape încât evidențiatorii de sintaxă ar fi păcăliți făcându-le să creadă că este CSS standard. Așadar, am mapat sintaxa CSS pentru interogări de elemente care au avut sens - tipul de sintaxă de care oamenii sunt surprinși nu există deja.

Știam că, dacă urma să extindem suportul pentru browser pentru CSS utilizând JavaScript, atunci pluginul ar trebui să fie cât mai ușor și simplu posibil pentru a face treaba, ceea ce exclude utilizarea bibliotecilor precum jQuery pentru a construi pluginul. Aveam nevoie de o bibliotecă JavaScript pur care să adauge funcțiile pe care le doresc în viitor în browserele pe care trebuie să le suport astăzi.

În acest moment, discuția în comunitatea CSS este axată pe reguli personalizate @ , iar discuțiile despre interogări de elemente sunt încă preliminare. Probabil că suntem încă la câțiva ani distanță de orice specificație CSS oficială pentru caracteristici ca aceasta și, chiar și după o specificație, va trebui să așteptăm suficient suport pentru browser înainte de a putea folosi aceste funcții pe site-uri web.

Așteptarea ca aceste funcții să fie adăugate la CSS nu are sens atunci când avem nevoie de această funcționalitate pentru a construi și a remedia site-uri web astăzi.

Rezultatul

Rezultatul acestei cercetări a fost crearea unei sintaxe care include un nou set de condiții avansate de răspuns, stiluri definite și noi selectori pentru elementele de direcționare, precum și o bibliotecă JavaScript pur numită EQCSS.js. În plus, a fost furnizat suport pentru Internet Explorer (IE) 8 într-un polyfill extern opțional. Atât plugin-ul, cât și polyfill au fost lansate sub licența MIT și sunt libere de utilizat pentru toată lumea.

Cazuri de utilizare pentru interogări de elemente

Dezvoltatori de pluginuri

Când creează componente și widget-uri UI, dezvoltatorii sunt adesea limitați de interogări media. Adesea trebuie să alegem între construirea multor machete diferite care pot fi configurate de persoana care utilizează pluginul și simplificarea interfeței până la punctul în care puteți construi o soluție unică.

Dar atunci când proiectăm plugin-uri și interfețe cu interogări de elemente, putem scrie cu ușurință stiluri responsive care acoperă toate situațiile pe care le anticipăm, făcându-le cu adevărat rezistente la glonț, indiferent de conținutul pe care utilizatorul îl introduce sau de unde apare pluginul. Să presupunem că am putea stila un widget cu aspecte care variază de la 150 la 2000 de pixeli lățime. Apoi, indiferent unde este afișat acel widget pe un site web, ar arăta întotdeauna grozav.

Constructori de șabloane

Când creați prototipuri pentru un site web, este obișnuit să reorganizați elementele de design pe pagină și să vă gândiți la design ca la o colecție de componente modulare. Dacă ați scris interogări media CSS, uneori acesta poate fi un caz de optimizare prematură . Prin proiectarea cu interogări de elemente, păstrați condițiile receptive independente de aspect, oferindu-vă mult mai multă flexibilitate pentru a muta lucrurile fără a fi nevoie să reluați la fel de mult stilurile.

Lucrurile pe care le-am considerat deosebit de utile pe care le-am proiectat sau imitat folosind interogări de elemente includ:

  • bare de navigare,
  • modale,
  • formulare de înscriere și autentificare,
  • subsol,
  • grafice de prețuri,
  • pagini de destinație,
  • Mese,
  • casete cu file,
  • acordeoane,
  • widget-uri din bara laterală,
  • playere media,
  • secțiuni de mărturie.

Orice element de design poate fi „delimitat” și portat oriunde - de la o pagină la alta sau de la un site la altul.

Suport dispozitiv

Una dintre problemele cu care vă confruntați atunci când susțineți web-ul pe dispozitive mobile este abundența de hardware. Piața dispozitivelor este mai fragmentată decât oricând, iar noi dispozitive apar în fiecare zi. Nu mai putem menține o listă cu browserele și dispozitivele pe care le suportăm, așa că este crucial să știm că un design funcționează peste tot, chiar și pe dispozitivele care nu au fost încă lansate.

Folosind interogări de elemente, puteți proiecta site-uri web într-un mod mai bun și puteți elimina unele dintre aceste diferențe între browsere.

Multe articole scrise recent despre necesitatea interogărilor de elemente ilustrează multe dintre cazurile de utilizare în detaliu. Deci, haideți să trecem mai departe cu cum să le folosim!

Cum se scrie interogări de elemente

Începeți cu EQCSS este ușor. Tot ce aveți nevoie pentru a începe să utilizați sintaxa EQCSS este să includeți JavaScript undeva în HTML.

Se descarcă EQCSS.js

Dacă doriți să clonați proiectul EQCSS din GitHub, puteți tasta:

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

Dacă utilizați npm, puteți adăuga EQCSS la proiectul dvs. cu următoarea comandă:

 npm install eqcss

Adăugarea EQCSS.js la HTML

După ce ați descărcat EQCSS, îl puteți adăuga la HTML cu o etichetă de script :

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

Acest fișier ( EQCSS.js ) include suport pentru toate browserele actuale, inclusiv IE 9 și versiunile ulterioare. Pentru a suporta IE 8, ar fi trebuit să folosim o mulțime de alte polyfills. Rețineți că IE 8 nu acceptă nici măcar interogări media CSS fără o completare polivalentă, așa că este destul de uimitor că am reușit să facem și interogări de elemente să funcționeze acolo. Pentru a include suport IE 8 pentru un site web care utilizează EQCSS, adăugați următorul link înainte de linkul către pluginul principal:

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

Rularea EQCSS

În mod implicit, pluginul EQCSS va calcula orice stiluri pe care le găsește odată ce pagina se încarcă și, de asemenea, ori de câte ori detectează că browserul este redimensionat, similar interogărilor media. De asemenea, puteți apela manual EQCSS.apply() cu JavaScript pentru a recalcula stilurile în orice moment, ceea ce poate fi util odată ce conținutul a fost actualizat pe pagină.

Scrierea elementelor de interogare CSS

Pluginul EQCSS.js poate citi stilurile în câteva moduri diferite. Puteți include EQCSS în orice etichete de style dintr-o pagină HTML. De asemenea, puteți scrie EQCSS într-o foaie de stil CSS externă.

Dacă doriți să păstrați codul bazat pe EQCSS separat de CSS, puteți încărca sintaxa EQCSS folosind eticheta de script cu tipul setat la text/eqcss . Puteți adăuga stiluri în linie într-o etichetă ca aceasta sau puteți face un link către o foaie de stil .eqcss externă cu <script type=“text/eqcss” src=styles.eqcss></script> , care ar încărca un fișier numit styles.eqcss .

Interogarea Anatomia unui element

Scoping stil

Sintaxa din EQCSS pentru scrierea interogărilor element este foarte asemănătoare cu formatarea interogărilor media CSS, dar în loc de @media , începem interogarea cu @element . Singura altă informație pe care trebuie să o furnizăm este cel puțin un selector căruia ar trebui să se aplice aceste stiluri. Iată cum ați crea un domeniu nou pentru un element numit <div class=“widget”> :

 @element '.widget' { }

Elementul dintre ghilimele (în acest caz, .widget ) poate fi orice selector CSS valid. Cu această interogare, am creat un nou domeniu de aplicare pentru elementul .widget . Nu am inclus încă nicio condiție de răspuns pentru domeniul de aplicare, așa că orice stil dintr-o interogare ca aceasta s-ar aplica în orice moment elementului în domeniu.

Fără capacitatea de a defini stilurile la unul sau mai multe elemente (în loc de întreaga pagină deodată), nu am fi capabili să aplicăm interogări receptive doar acelor elemente. Odată ce am creat acel domeniu de aplicare la nivel de element, utilizarea caracteristicilor mai avansate ale sintaxei EQCSS devine ușoară - cum ar fi selectorul meta $parent , de exemplu - deoarece JavaScript are acum un punct de referință de la care să calculeze lucruri precum parentNode al domeniului de aplicare. element. Acesta este uriaș!

Adevărat, CSS include deja un selector direct-descendent, cu > , care ne permite să selectăm elemente care sunt copii direcți ai elementului specificat. Dar CSS în prezent nu oferă nicio modalitate de a călători în cealaltă direcție în sus în arborele genealogic, pentru a selecta un element care conține un alt element, pe care l-ar numi elementul părinte. Specificația „CSS Selectors Level 4” include acum un selector :has() , care funcționează în mod similar cu selectorul :has() al jQuery, dar în prezent suportul pentru browser este nul. CSS acoperit face posibil un alt tip de selector de părinte.

Acum că am deschis un domeniu de aplicare în contextul elementului .widget , putem scrie stiluri din perspectiva sa pentru a viza propriul său element părinte:

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

Un alt exemplu de selectoare speciali care pot fi utilizate în orice interogare de element sunt selectoarele $prev și $next , care reprezintă elementele frate anterioare și următoare. Chiar dacă CSS poate ajunge la următorul frate al widget-ului nostru cu un selector precum .widget + * , nu există nicio modalitate în CSS de a ajunge înapoi și de a selecta elementul care vine direct înaintea altui element.

 <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>

Interogări de elemente

Dezvoltatorii folosesc cel mai frecvent interogări media CSS pentru design responsive, aplicând stiluri bazate pe înălțimea sau lățimea ferestrei de vizualizare a browserului. Sintaxa EQCSS acceptă multe tipuri noi de condiții de răspuns. În loc să lucrați numai cu lățimea și înălțimea browserului, puteți scrie stiluri care se aplică elementelor pe baza propriilor proprietăți, cum ar fi câte elemente copil conține sau câte caractere sau linii de text sunt în element în acest moment. .

Adăugarea acestor condiții receptive la stilurile dvs. de acoperire este similară cu modul în care ați formata interogările media: ați adăuga and (condition: value) pentru fiecare condiție pe care doriți să o verificați. În acest exemplu, vom verifica dacă elementele .widget sunt afișate cu o lățime de cel puțin 500 de pixeli pe pagină.

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

Sintaxa unei interogări de element se descompune după cum urmează:

  • interogare element @element selector_list [ condition_list ] { css_code }
  • lista de selectoare " css selector [ "," css selector ]* "
  • listă de condiții and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
  • număr valoare number [ css unit ]
  • condiția interogării 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
  • unitate 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

Ca un alt exemplu, iată cum se scrie o interogare care transformă în roșu elementul body atunci când elementul .widget atinge 500 de pixeli lățime:

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

Rețineți că elementul body se schimbă atunci când .widget atinge o anumită lățime, nu elementul .widget în sine!

Condiții de interogare a elementelor

Mai jos este lista completă a condițiilor receptive pe care EQCSS le acceptă.

Condiții bazate pe lățime

  • demonstrație min-width pentru pixeli, demonstrație pentru procente
  • demo max-width pentru pixeli, demo pentru procente

Condiții bazate pe înălțime

  • demonstrație de min-height pentru pixeli, demonstrație pentru procente
  • demo max-height pentru pixeli, demo pentru procente

Condiții bazate pe numărare

  • demo min-characters pentru elemente de bloc, demonstrație pentru intrări de formular
  • demo max-characters pentru elemente de bloc, demo pentru intrări de formular
  • demo min-lines
  • demo max-lines
  • demo min-children
  • demo max-children

Condiții bazate pe defilare

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

Puteți combina orice număr de aceste condiții în interogările dvs. de elemente pentru stiluri de răspuns cu adevărat multidimensionale. Acest lucru vă oferă mult mai multă flexibilitate și control asupra modului de redare a elementelor. De exemplu, pentru a micșora dimensiunea fontului unui antet care are mai mult de 15 caractere atunci când este disponibil pentru afișare mai puțin de 600 de pixeli de spațiu, puteți combina condițiile pentru max‐characters: 15 și max‐width: 600px :

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

Meta selectoare

Una dintre problemele cu care s-ar putea să întâmpinați odată ce începeți să scrieți stiluri definite cu condiții de răspuns este că, atunci când mai multe instanțe ale aceluiași selector sunt pe o pagină, utilizarea acelui selector în interogarea elementului va aplica stiluri tuturor instanțelor acelui selector de pe pagina. pagina când oricare dintre ele îndeplinește condițiile. Luând exemplele noastre .widget de mai devreme, să presupunem că avem două widget-uri pe pagină (poate unul în bara laterală și altul afișat la lățime completă) și am scris interogarea elementului nostru astfel:

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

Aceasta ar însemna că, atunci când oricare dintre elementele .widget de pe pagină are o lățime de cel puțin 500 de pixeli, stilul s-ar aplica ambelor elemente .widget . Probabil că nu este ceea ce dorim să se întâmple în majoritatea cazurilor. Aici intervin metaselectorii!

Cele două părți care alcătuiesc interogarea elementului nostru sunt selectorul și condiția de răspuns. Deci, dacă dorim să vizam doar elementele din pagină care se potrivesc atât cu selectorul, cât și cu condițiile de răspuns în același timp, putem folosi meta selectorul $this . Putem rescrie ultimul nostru exemplu, astfel încât stilul să se aplice numai elementelor .widget care se potrivesc min‐width: 500px condiția:

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

O serie de selectoare noi sunt acceptate de sintaxa EQCSS care nu sunt în CSS obișnuit. Iată lista completă:

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

Acești selectori vor funcționa numai într-o interogare de element.

Deschiderea portalului între JavaScript și CSS

  • eval(') demo

Ultima și ultima caracteristică a EQCSS este cea mai sălbatică dintre toate: eval(') . Prin această ușă se află toată puterea JavaScript, accesibilă din CSS. Deși JavaScript poate aplica stiluri elementelor, în prezent îi este greu să ajungă la unele lucruri, cum ar fi pseudoelementele :before și :after . Dar dacă CSS ar putea ajunge la JavaScript din cealaltă direcție? În loc să seteze JavaScript proprietățile CSS, ce se întâmplă dacă CSS ar putea fi conștient de JavaScript?

Aici intervine eval(') . Puteți să accesați și să evaluați orice JavaScript, fie că doriți să utilizați valoarea unei variabile JavaScript în CSS-ul dvs., pentru a executa un JavaScript one-liner (cum ar fi eval('new Date().getFullYear()') ), pentru a stabili valori despre browser și alte elemente pe care JavaScript le poate măsura (cum ar fi eval('innerHeight') ) sau pentru a rula o funcție JavaScript și a utiliza valoarea pe care o returnează în stilurile dvs. CSS. Iată un exemplu care scoate 2016 într-un element <footer> :

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

Folosind $it în interiorul eval(')

În timpul evaluării JavaScript, eval(') funcționează și din contextul elementului activ, același element căruia i se aplică stilurile pentru $this . Puteți folosi $it în JavaScript scris în eval(') ca substituent pentru elementul în domeniu dacă vă ajută să structurați codul, dar dacă este omis, va funcționa în același mod. De exemplu, să presupunem că avem un div cu cuvântul „bună ziua” în el. Următorul cod va scoate „hello hello”:

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

Aici, $it se referă la div , deoarece este selectorul în domeniu. Puteți, de asemenea, să omiteți $it și să scrieți următorul cod pentru a afișa același lucru:

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

eval(') poate fi util în situațiile în care CSS nu este conștient de măsurători sau evenimente care au loc pe pagină după ce aceasta s-a încărcat. De exemplu, elementele iframe utilizate pentru încorporarea videoclipurilor YouTube vin cu o lățime și o înălțime specificate. Deși puteți seta lățimea la auto în CSS, nu există o modalitate ușoară de a menține raportul corect de aspect între lățime și înălțime atunci când videoclipul se extinde pentru a umple spațiul disponibil.

O soluție obișnuită pentru menținerea raporturilor de aspect receptive în timpul scalarii este să plasați conținutul care trebuie să-și mențină raportul de aspect într-un înveliș, apoi să adăugați umplutură în înveliș cu o valoare bazată pe raportul dintre lățime și înălțime pe care doriți să-l mențineți. Acest lucru funcționează, dar necesită să cunoașteți raportul de aspect al tuturor videoclipurilor în avans, precum și mai multă markup HTML (un element de înveliș) pentru fiecare videoclip pe care doriți să îl încorporați în mod receptiv. Înmulțiți-l pe fiecare site web care are videoclipuri responsive și este o mulțime de lucruri care nu ar trebui să existe dacă CSS ar fi doar puțin mai inteligent.

Poate că o abordare mai bună a raporturilor de aspect receptive implică plasarea fiecărui videoclip într-un înveliș fără umplutură și apoi scrierea unei biblioteci JavaScript care calculează raportul de aspect al fiecărui videoclip pe care îl găsește și aplică cantitatea corectă de umplutură fiecărui înveliș.

Dar dacă CSS ar putea accesa direct acele măsurători? Nu numai că am putea consolida CSS pentru toate raporturile de aspect diferite într-o singură regulă, dar dacă l-am putea evalua odată ce pagina se încarcă, am putea scrie o regulă care să redimensioneze în mod receptiv orice videoclip pe care i-l oferim vreodată în viitor. Și am putea face totul fără nici un ambalaj!

Dacă acest lucru pare prea frumos pentru a fi adevărat, verificați asta. Iată cât de simplu este să scrieți fără wrapper elemente iframe cu răspunsuri redimensionate în EQCSS:

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

Aici, width și height se referă la atributele width=“” și height=“” din iframe în HTML. JavaScript poate efectua calculul (width/height) , care ne oferă raportul de aspect; și pentru a o aplica la orice lățime, am împărți doar lățimea curentă a elementului iframe la raport.

Aceasta are succinta și lizibilitatea CSS și toată puterea JavaScript. Nu sunt necesare wrapper-uri suplimentare, fără clase suplimentare și fără CSS suplimentar.

Ai grijă totuși cu eval(') . Există un motiv pentru care expresiile CSS erau considerate periculoase în trecut și există și un motiv pentru care am încercat ideea. Dacă nu sunteți atent la câte elemente le aplicați pe pagină sau la cât de des recalculați stilurile, atunci JavaScript ar putea ajunge să ruleze lucrurile de sute de ori mai mult decât este necesar. Din fericire, EQCSS ne permite să invocăm EQCSS.apply() sau EQCSS.throttle() pentru a recalcula stilurile manual, astfel încât să avem mai mult control asupra momentului în care stilurile sunt actualizate.

Zona de pericol!

Alte probleme pot apărea dacă creați interogări cu condiții sau stiluri conflictuale. EQCSS, ca și CSS, este citit de sus în jos folosind o ierarhie de specificitate. Deși CSS este un limbaj declarativ, conține unele caracteristici avansate. Sunt doar câțiva pași de a fi Turing-complet ca limbaj de programare. Până acum, depanarea CSS a fost o chestiune destul de simplă, dar EQCSS transformă CSS de la a fi pur și simplu un limbaj declarativ interpretat într-un limbaj dinamic pentru foi de stil, cu un strat suplimentar de interpretare între CSS și browser. Odată cu acest nou teritoriu, vine o varietate de noi capcane potențiale.

Iată un exemplu de buclă reciprocă în EQCSS, ceva la care interogările media CSS normale sunt imune prin proiect:

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

Eu îl numesc jekyll: hide; CSS. Dar, pe lângă un stil care se declanșează continuu, există și posibilitatea de a scrie mai multe interogări care se declanșează reciproc, în ceea ce numim o „buclă reciprocă dublă inversată”, cea mai urâtă dintre toate:

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

În teorie, acel widget nefericit ar fi blocat într-o buclă, redimensionând între 200 și 500 de pixeli până la sfârșitul timpului, neputând să se stabilească pe o lățime. Pentru cazuri ca acesta, EQCSS pur și simplu calculează regulile în ordinea în care sunt evaluate, acordă câștigătorul și trece mai departe. Dacă ar fi să rearanjați ordinea în care apar aceste reguli, stilul din urmă ar câștiga întotdeauna dacă sunt de aceeași specificitate.

Unii oameni spun că abilitatea de a crea bucle (sau chiar bucle reciproce dublu inversate) este un defect de proiectare, dar pentru a preveni posibilele bucle, ar trebui să limitați puterea EQCSS într-un mod care ar elimina majoritatea valoarea pe care o oferă sintaxa. Pe de altă parte, crearea de bucle infinite în JavaScript este foarte ușoară, dar asta nu este privit ca un defect al limbajului - este văzut ca o dovadă a puterii sale! Este același lucru cu interogările de elemente.

Depanare interogări de elemente

În prezent, interogările de elemente de depanare se pot simți un pic ca depanarea interogărilor media înainte de a avea instrumente precum inspectorul web care să ne arate stilurile așa cum au fost calculate pe pagină. Deocamdată, depanarea și dezvoltarea interogărilor de elemente necesită dezvoltatorului să mențină un model mental al comportamentului receptiv care ar trebui să se întâmple. În viitor, ar putea fi posibilă construirea de instrumente pentru dezvoltatori compatibile cu EQCSS, dar de acum, instrumentele pentru dezvoltatori din toate browserele majore sunt conștiente doar de stilurile pe care EQCSS le-a aplicat deja elementelor de pe pagină și nu sunt conștienți de acestea. condițiile de răspuns pe care EQCSS le urmărește.

Cum să proiectați cu interogări de elemente

Cea mai simplă modalitate de a utiliza interogări de elemente este de a converti modelele existente folosind interogări media în interogări de elemente, „eliberând” elementele și stilurile lor receptive dintr-un singur aspect și făcând ușoară reutilizarea codului respectiv în alte pagini și proiecte. Următoarea interogare media și interogare despre element ar putea însemna același lucru:

 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; } }

Diferența este că, în exemplul original, linkurile de subsol rămân ca display: block până când browserul are o lățime de cel puțin 500 de pixeli. Al doilea exemplu, folosind interogări de elemente, ar arăta la fel, dar numai dacă elementul de footer ar avea lățime completă.

După ce am eliberat acest stil de interogarea media inițială, acum putem plasa subsolul într-un container de orice lățime și să ne asigurăm că atunci când subsolul are nevoie de un stil receptiv pentru a fi aplicat (adică atunci când este mai îngust de 500 de pixeli), acesta va fi aplicat.

  1. Asigurați-vă că EQCSS.js este prezent în HTML-ul documentului de destinație.
  2. Înlocuiți @media cu @element în CSS.
  3. Adăugați un selector CSS în domeniul de aplicare al fiecărei interogări @element .
  4. Opțional: Înlocuiți aparițiile elementului în domeniu cu $this în interogările elementului.

Cu excepția cazului în care componenta de design pe care o convertiți a fost proiectată inițial pentru a fi afișată folosind lățimea completă a ferestrei de vizualizare a browserului, probabil că va trebui să modificați punctele de întrerupere după conversia la interogări de elemente.

Evitarea blocării

Experiența de a crea stiluri EQCSS este similară cu experiența de a scrie CSS obișnuit: Toate proprietățile și tehnicile CSS preferate sunt încă acolo, doar cu câteva caracteristici suplimentare care îi ajută să lucreze împreună în moduri noi. Deoarece EQCSS emite CSS standard către browser, orice caracteristică CSS pentru care browserul dvs. are suport încorporat va funcționa atunci când este utilizată cu EQCSS. Dacă într-o zi caracteristici, cum ar fi interogările de elemente și stilurile de acoperire, sunt specificate în CSS și acceptate în browsere, atunci veți putea începe să le utilizați imediat în codul dvs. EQCSS, bazându-vă în continuare pe EQCSS pentru celelalte caracteristici pe care browserul nu le folosește. totuși sprijină nativ.

Deoarece puteți folosi sintaxa EQCSS atât direct în CSS, cât și în propriul script, cu tipul text/eqcss , dacă CSS dezvoltă vreodată o sintaxă pentru interogări de elemente native, veți putea încărca EQCSS ca script și evita conflictele .

În așteptare, o soluție pe care dezvoltatorii de browser o experimentează în acest moment este Houdini, care ar deschide accesul dezvoltatorilor de pluginuri pentru a extinde CSS în moduri noi, cum ar fi adăugarea de suport pentru browserul însuși. Într-o zi, ar putea fi posibil să scrieți pluginuri mai eficiente care interpretează sintaxa EQCSS și să aducă aceste funcții la browsere într-un mod mai direct și mai performant decât permite biblioteca actuală JavaScript.

Deci, ar trebui să folosim în continuare interogări media?

Da, chiar dacă interogările de elemente oferă multe modalități noi și interesante de a viza elementele cu stiluri, interogările media (deși limitate) vor rula întotdeauna mai rapid în browser decât un stil care se bazează pe JavaScript pentru a calcula. Cu toate acestea, interogările media CSS sunt pentru mai mult decât pentru stilul HTML pentru ecrane. Interogările media CSS acceptă, de asemenea, interogări tipărite și alte moduri prin care site-urile web afișează informații. EQCSS poate fi folosit împreună cu interogări media pentru lucruri precum stilurile de imprimare, deci nu este nevoie să retrageți interogarea media doar pentru că acum pot fi utilizate și interogările de elemente!

Proiectare cu 20⁄ 20 Vision

Cel mai bun lucru pe care îl putem face pentru viitorul CSS este să experimentăm pe cât posibil aceste idei astăzi. Nici o cantitate de brainstorming și teoretizare despre aceste caracteristici nu va fi la fel de utilă ca încercarea de a le implementa și a le pune în aplicare, descoperind tehnicile care le fac utile și puternice.

Pe lângă faptul că oferă o soluție pentru interogările de elemente, EQCSS.js, sperăm, să servească și ca platformă pentru alte experimente de extindere a 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
  • Calendar
  • 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

Lectură suplimentară

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!