Generic First CSS: New Thinking On Mobile First

Publicat: 2022-03-10
Rezumat rapid ↬ Odată cu apariția designului web responsive și a abordării mobile-first, au trecut șapte ani minunati de când orice concepte noi ne-au obligat să adaptăm modul în care scriem CSS la nivelul de bază. Ei bine, nu am nimic prea inovator să vă ofer, dar am o mică surpriză. Iată: Generic First CSS.

Cred că este sigur să spun că Designul web responsiv al lui Ethan Marcotte a fost o revelație binevenită pentru dezvoltatorii web din întreaga lume. A declanșat un val cu totul nou de gândire la design și noi tehnici minunate de front-end. Domnia site-urilor de multe ori disprețuite m dot s-a încheiat și ea. În aceeași epocă și aproape la fel de influentă a fost metodologia Mobile First a lui Luke Wroblewski - o îmbunătățire solidă care s-a construit pe bazele impresionante ale lui Marcotte.

Aceste tehnici sunt la baza vieții majorității dezvoltatorilor web și ne-au servit bine, dar, din păcate, vremurile se schimbă, iar dezvoltatorii repetă în mod constant. Pe măsură ce creștem eficiența metodelor noastre și cerințele proiectului devin mai complexe, apar noi frustrări.

Călătoria către generic mai întâi

Nu pot identifica exact ce m-a făcut să schimb modul în care îmi scriu CSS-ul, deoarece a fost într-adevăr o progresie naturală pentru mine, care s-a întâmplat aproape subconștient. Privind în urmă, cred că a fost mai degrabă un produs secundar al mediului de dezvoltare în care lucram. Echipa cu care am lucrat avea un flux de lucru SCSS drăguț, cu un mic mixin frumos pentru a adăuga cu ușurință puncte de întrerupere în declarațiile noastre CSS. Probabil că folosești o tehnică similară.

Acest minunat mic mixin SCSS a făcut dintr-o dată ușor să scrieți interogări media super granulare. Luați un bloc de biografie ipotetică care arată cam așa:

 .bio { display: block; width: 100%; background-color: #ece9e9; padding: 20px; margin: 20px 0; @include media('>=small') { max-width: 400px; background-color: white; margin: 20px auto; } @include media('>=medium') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Fig.1. În primul rând, mobilul tipic cu interogări media în cascadă

Funcționează bine — am scris multe CSS ca acesta în trecut. Cu toate acestea, într-o zi mi-am dat seama că suprascrierea declarațiilor CSS pe măsură ce lățimea dispozitivului creștea pur și simplu nu avea sens. De ce să declari o proprietate CSS pentru ca aceasta să fie doar suprascrisă în următoarea declarație?

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

Acesta este ceea ce m-a determinat să încep să scriu interogări media compartimentate , spre deosebire de abordarea mai comună a interogărilor media care cascadă în sus (sau în jos), ca exemplul din Fig.1.

În loc să scriu interogări media care cresc în cascadă odată cu creșterea dimensiunii ecranului, am început să creez interogări media vizate care să încapsuleze stiluri la lățimea dorită a ecranului. Mixin-ul de interogări media și-ar veni cu adevărat în sine aici. Acum interogările mele media SCSS încep să arate astfel:

 .bio { display: block; width: 100%; padding: 20px; margin: 20px 0; @include media('>=small', ' < medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', ' < large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', ' < huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Fig.2. Un exemplu de interogări media compartimentate

Această nouă abordare mi s-a părut mai intuitivă, a redus nevoia de a reseta stilurile de la punctul de întrerupere anterior și a făcut CSS-ul mai ușor de citit. Mai important, a făcut ca interogările media să se auto-documenteze într-un mod mai semnificativ.

Totuși, încă nu am fost 100% mulțumit de cele de mai sus, se părea că mai era o problemă majoră de depășit.

Problema cu Mobile First

Problema cu mobil primul este că, prin definiție, cel mai probabil va trebui să înlocuiți stilurile mobile-first în interogările media ulterioare. Se simte ca un pic de anti-model.

Deci, pentru mine, răspunsul a fost evident: să luăm ideea de compartimentare a interogărilor media până la concluzia sa logică – vom compartimenta, de asemenea, stilurile specifice mobile în propriile interogări media. Știu, știu, asta contravine convenției comune pe care am învățat-o de-a lungul anilor. „Mobile First” este atât de omniprezent încât este, de obicei, una dintre întrebările de „aptitudini” pe care le pune un manager de angajare. Deci, cu siguranță orice alternativă trebuie să fie greșită, nu-i așa? Aceasta este de obicei partea în care oamenii scutură din cap la mine în timp ce rostesc mai întâi mobil , iar și iar.

Bine, așa că vom străpunge dogma primul mobil și vom compartimenta toate stilurile noastre în interogările media relevante. Ceea ce ne rămâne acum sunt stiluri generice pure declarate pe un selector CSS, cu toate celelalte stiluri specifice dispozitivului încapsulate în interogări media care se aplică numai dimensiunilor relevante ale ecranului. Acum avem Generic First CSS :

 .bio { display: block; width: 100%; @include media('>=0', ' < small') { padding: 20px; margin: 20px 0; } @include media('>=small', ' < medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', ' < large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', ' < huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') { max-width: 1000px; padding: 50px; margin: 50px auto; } }

Fig.3. Un exemplu de Generic First CSS

Da, există puțin mai multe interogări media, totuși, văd acest lucru ca un beneficiu, orice dezvoltator poate acum să se uite la acest CSS și să vadă exact ce stiluri sunt aplicate la fiecare dimensiune a ecranului, fără a avea suprasolicitarea cognitivă de a alege media- specificitatea interogării.

Acest lucru poate fi grozav pentru persoanele care nu sunt familiarizate cu baza de cod sau chiar cu viitorul dvs.!

Când să nu se compartimenteze

Există încă momente în care compartimentarea interogărilor media este o povară și, în unele cazuri, o interogare media veche >= este în regulă. Amintiți-vă, tot ceea ce încercăm să facem este să evităm suprascrierile de proprietate.

Dev Tool Bliss

O consecință majoră neintenționată a scrierii compartimentate Generic First CSS este experiența pe care o veți obține din panoul de stil al instrumentelor pentru dezvoltatori. Fără cascada de interogare media, veți avea acum o imagine de ansamblu mai clară asupra stilurilor aplicate — Nu veți avea un panou de stil plin de declarații eliminate din regulile de interogare media suprascrise — Zgomotul a dispărut! Acesta – pentru mine – este unul dintre cele mai mari beneficii ale tehnicii Generic First CSS. Aduce un pic de sens în plus experienței de depanare CSS, iar acest lucru își merită greutatea în aur. Mulțumește-mi mai târziu.

Înainte și după captură de ecran a modului în care prima abordare generică CSS afectează panoul de stil al instrumentelor de dezvoltare Chrome.
Fig.4. Cât de generic, mai întâi, css compartimentat poate ajuta să aducă bucurie și minte în consola dvs. de dezvoltare. (Previzualizare mare)

Implicații de performanță

Deci, toate aceste beneficii Generic First CSS încep să sune destul de bine, dar cred că există o ultimă întrebare cheie care cred că trebuie abordată. Este vorba despre optimizarea performanței. Acum nu știu încă sigur, dar am bănuiala că interogările media complet compartimentate pot avea un ușor avantaj de performanță.

Browserele efectuează o sarcină de randare numită calcul al stilului calculat . Este modul browserului de a calcula ce stiluri trebuie aplicate unui element la un moment dat. Această sarcină este întotdeauna efectuată la încărcarea inițială a paginii, dar poate fi efectuată și dacă conținutul paginii se modifică sau dacă au loc alte acțiuni ale browserului. Orice spor pe care îl puteți oferi vitezei procesului va fi grozav pentru încărcarea inițială a paginii și ar putea avea un efect compus asupra ciclului de viață al paginilor site-ului dvs.

Deci, revenind la primul CSS generic: Există probleme de performanță legate de faptul că browserul trebuie să elaboreze specificul CSS al unei multitudini de interogări media în cascadă?

Pentru a răspunde la asta, am conceput un caz de testare care poate fi folosit pentru a măsura orice avantaje sau chiar dezavantaje ale vitezei.

Cazul de testare

Cazul de testare este format dintr-o pagină HTML de bază care scoate un bloc „bio” de 5000 de ori, marcajul este același pentru fiecare bloc, dar clasele sunt ușor diferite (diferențiator numeric), CSS-ul pentru acest bloc este, de asemenea, afișat de 5000 de ori , numele claselor fiind singurul lucru care diferă. CSS-ul ieșit este transmis printr-un instrument numit CSS MQPacker, acest lucru ajută la reducerea dramatică a dimensiunii fișierului CSS care utilizează o mulțime de interogări media inline, combinând toate instanțele separate ale unei interogări media specifice într-un singur instrument - Este un instrument grozav care probabil va beneficia cele mai moderne baze de cod CSS — l-am folosit ca instrument cli autonom printr-o sarcină npm în pachetul de proiecte de testare.json, îl puteți folosi și ca plugin postcss, ceea ce este frumos și convenabil!

Primul caz de testare este un exemplu de interogări media în cascadă pe mobil, al doilea caz de testare este o primă variantă generică compartimentată a CSS. CSS-ul pentru aceste cazuri este puțin verbos și probabil ar putea fi scris în termeni mult mai conciși, dar într-adevăr servește doar ca un exemplu aproximativ pentru a testa argumentul.

Testul a fost rulat de 20 de ori pentru fiecare variantă CSS din desktop Google Chrome v70, nu un set masiv de date, dar suficient pentru a-mi oferi o idee aproximativă despre un câștig/pierdere de performanță.

Valorile de testare pe care am ales să le folosesc sunt:

  • Timpul general de încărcare a paginii
    O valoare de bază pentru a verifica timpul de încărcare a paginii folosind marcatorii Performance API la începutul <head> și chiar la sfârșitul <body>
  • Stilul de recalculare
    Timp din panoul de performanță al instrumentelor de dezvoltare.
  • Redarea generală a paginii
    Timp din panoul de performanță al instrumentelor de dezvoltare.
Tabel cu rezultate din profilul de performanță Google Chrome
Fig.5. Valoarea cheie măsurată este „Recalculați stilul”. (Previzualizare mare)

Tabel cu rezultate (toate ori în milisecunde)

În primul rând mobil În primul rând generic
Timp de încărcare Calculați stiluri Timp total de randare Timp de încărcare Calculați stiluri Timp total de randare
1135 565,7 1953 1196 536,9 2012
1176 563,5 1936 1116 506,9 1929
1118 563,1 1863 1148 514,4 1853
1174 568,3 1929 1124 507.1 1868
1204 577,2 1924 1115 518,4 1854
1155 554,7 1991 1177 540,8 1905
1112 554,5 1912 1111 504,3 1886
1110 557,9 1854 1104 505,3 1954
1106 544,5 1895 1148 525,4 1881
1162 559,8 1920 1095 508,9 1941
1146 545,9 1897 1115 504,4 1968
1168 566,3 1882 1112 519,8 1861
1105 542,7 1978 1121 515,7 1905
1123 566,6 1970 1090 510,7 1820
1106 514,5 1956 1127 515,2 1986
1135 575,7 1869 1130 504,2 1882
1164 545,6 2450 1169 525,6 1934
1144 565 1894 1092 516 1822
1115 554,5 1955 1091 508,9 1986
1133 554,8 2572 1001 504,5 1812
AVG 1139,55 557,04 1980 1119.1 514,67 1903.15

Fig.6. 20 de teste care măsoară valorile de încărcare/randare a cheilor pentru primul CSS mobil vs primul CSS generic.

Din setul meu de date, desigur, mic, se pare că suspiciunea mea inițială ar putea fi corectă. În medie, văd că sarcina de recalculare a stilului durează cu 42 ms mai puțin, ceea ce reprezintă o creștere a vitezei cu 7,6% și, prin urmare, timpul general de randare scade și el. Diferența nu este uimitoare, dar este o îmbunătățire. Nu cred că setul de date este suficient de mare pentru a fi 100% concludent, iar cazul de testare este puțin nerealist, dar sunt foarte bucuros că nu văd o degradare a performanței.

Aș fi foarte interesat să văd prima metodologie generică aplicată la o bază de cod existentă în lumea reală, care a fost scrisă în primul mod mobil - metricile înainte de după ar fi mult mai realiste pentru practica de zi cu zi.

Și dacă cineva are sugestii despre cum să automatizeze acest test printr-un set mai larg de iterații, vă rog să-mi spuneți în comentarii! Mi-aș imagina că trebuie să existe un instrument care poate face asta.

Concluzie

Pentru a recapitula beneficiile acestei noi metodologii de dezvoltare...

  • CSS care face exact așa cum este intenționat, fără nicio a doua ghicire;
  • Interogări media cu auto-documentare;
  • O experiență mai bună cu instrumentele de dezvoltare;
  • Pagini care se redau mai rapid.

Aș dori să cred că nu sunt singura persoană care susține scrierea CSS în acest stil. Dacă ai adoptat deja prima mentalitate generică, ura! Dar dacă nu, cred că îți vor plăcea foarte mult beneficiile pe care le aduce. Personal, am beneficiat foarte mult de experiența simplă a instrumentelor de dezvoltare, care în sine va fi un foarte pozitiv pentru mulți dezvoltatori. natura de auto-documentare a acestui mod de a vă scrie interogările media va avea, de asemenea, beneficii pentru dvs. și pentru echipa mai largă (dacă aveți una). Și, în sfârșit, aceste beneficii nu vă vor costa nimic în termeni de performanță și, de fapt, s-a dovedit că au câștiguri marginale de viteză!

Cuvântul final

Ca toate metodologiile de dezvoltare, s-ar putea să nu fie pentru toată lumea, dar am căzut în Generic First CSS destul de natural, acum îl văd ca pe un mod valoros de lucru care îmi oferă toate beneficiile mobile first cu câteva completări pozitive noi care fac sarcina grea de dezvoltare front-end care poate fi mai ușoară.

Resurse

Test Case Repo

Dacă doriți să porniți cazul de testare și să încercați singur, îl puteți găsi pe GitHub, mi-ar plăcea să văd câteva rapoarte de la alții.

Instrumente

  • CSS MQPacker
  • Includeți media