Stilizarea celulelor goale cu conținut generat și aspect grilă CSS
Publicat: 2022-03-10O problemă comună cu aspectul grilei este atunci când un nou venit la metoda de aspect se întreabă cum să stileze o celulă grilă care nu conține niciun conținut. În specificația actuală de Nivel 1, acest lucru nu este posibil, deoarece nu există nicio modalitate de a viza o celulă sau o zonă de grilă goală și de a aplica stil. Aceasta înseamnă că pentru a aplica stilul, trebuie să inserați un element.
În acest articol, voi arunca o privire asupra modului de utilizare a conținutului generat CSS pentru a obține stilul celulelor goale fără a adăuga elemente goale redundante și voi arăta câteva cazuri de utilizare în care această tehnică are sens.
Privind mai atent la BFC
Dacă ați făcut vreodată un aspect cu CSS, probabil că știți ce este BFC. Înțelegerea de ce funcționează și cum să creați unul este util și vă poate ajuta să înțelegeți cum funcționează aspectul în CSS. Citiți un articol înrudit →
De ce nu putem modela deja zonele goale?
Paragraful de deschidere al specificației rețelei spune:
„Acest modul CSS definește un sistem de layout bidimensional bazat pe grilă, optimizat pentru proiectarea interfeței cu utilizatorul. În modelul de aspect al grilei, copiii unui container grilă pot fi poziționați în sloturi arbitrare într-o grilă de aspect flexibilă sau de dimensiuni fixe predefinite.”
Expresia cheie aici este „copiii unui container grilă”. Specificația definește crearea unei grile pe elementul părinte, în care elementele secundare pot fi poziționate. Nu definește nici un stil al acelei grile, nici măcar nu merge până la a implementa ceva de genul proprietății column-rule
o avem în Aspectul cu mai multe coloane. Noi stilăm elementele copil, și nu grila în sine, ceea ce ne face nevoită să avem un element oarecare pentru a-i aplica acel stil.
Utilizarea elementelor redundante ca un cârlig de stil
O modalitate de a insera ceva pentru stil este să inserați un element redundant în document, de exemplu, un span sau un div. Dezvoltatorii tind să nu le placă această idee, în ciuda faptului că au adăugat „învelișuri de rând” suplimentare redundante de ani de zile pentru a realiza layout-uri de grilă folosind float. Poate că acel element evident gol este mai dezagreabil decât redundanța oarecum ascunsă a elementului de înveliș!
Elementele complet goale devin elemente de grilă și pot avea fundaluri și chenare adăugate la fel ca un element care conține conținut, așa cum demonstrează acest exemplu.
Eric Meyer, în articolul său A List Apart Faux Grid Tracks, pledează pentru utilizarea elementului b
ca element redundant de alegere, deoarece nu conferă nicio semnificație semantică, este scurt și, de asemenea, destul de evident în marcaj ca un cârlig.
Este puțin probabil ca inserarea altor câteva elemente div
sau b
să fie cea mai mare crimă împotriva markupurilor bune pe care ați comis-o vreodată, așa că nu mi-aș pierde somnul în privința alegerii acelei abordări dacă este necesar. Dezvoltarea web implică deseori alegerea celei mai puțin suboptime abordări pentru a duce la bun sfârșit munca până când este concepută o soluție mai bună. Prefer totuși să-mi păstrez stilul într-un singur loc, dacă este posibil, în siguranță în foaia de stil. Dacă nu altceva, este mai ușoară reutilizarea stilurilor, fără a fi nevoie să vă faceți griji cu privire la marcajul suplimentar necesar. Din acest motiv, tind să mă uit la conținutul generat, lucru cu care sunt foarte familiarizat din munca pe care am făcut-o cu formatarea cărților cu CSS, unde îți petreci cea mai mare parte a timpului lucrând cu această caracteristică.
Utilizarea conținutului generat ca un cârlig de stil
Conținutul generat CSS utilizează pseudoclasele CSS ::before
și ::after
împreună cu proprietatea content
pentru a insera un fel de conținut în document. Ideea de inserare a conținutului v-ar putea face să credeți că aceasta este pentru inserarea textului și, deși acest lucru este posibil, în scopurile noastre suntem interesați să inserăm un element gol ca un copil direct al Containerului nostru Grid. Cu un element inserat îl putem stila.
În exemplul de mai jos am un element care conține, care va deveni Containerul meu Grid, cu un alt element imbricat în interior. Acest singur copil direct va deveni un articol Grid. Am definit o grilă cu trei coloane și trei rânduri pe container și apoi am poziționat un singur articol folosind linii grilă, astfel încât să se așeze în celula grilă din mijloc.
<div class="grid"> <div class="item"></div> </div>
.grid { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-gap: 10px; } .grid > * { border: 2px solid rgb(137,153,175); } .item { grid-column: 2; grid-row: 2; }
Dacă ne uităm la acest exemplu, utilizând Firefox Grid Inspector pentru a suprapune liniile Grid, putem vedea cum există celelalte celule goale ale grilei, totuși, pentru a adăuga un fundal sau un chenar, ar trebui să adăugați un copil suplimentar. elemente. Care este exact ceea ce permite Conținutul generat.
În CSS-ul meu adaug un șir gol, ::before
și ::after
Grid Container. Acestea vor deveni imediat Elemente Grid și se vor întinde pentru a-și umple recipientul. Apoi adaug stilul de care am nevoie pentru casete, adăugând în acest caz o culoare de fundal și le poziționez așa cum aș face orice element obișnuit al grilei.
.grid::before { content: ""; background-color: rgb(214,232,182); grid-column: 3; grid-row: 1; } .grid::after { content: ""; background-color: rgb(214,232,182); grid-column: 1; grid-row: 3; }
În document avem încă un singur element copil, elementele de stilare redundante sunt conținute în CSS, ceea ce pare perfect rezonabil deoarece sunt acolo doar în scopuri de stil.
Limitări ale abordării conținutului generat
Problema evidentă cu această abordare va deveni evidentă dacă decideți că doriți să stilați și celulele grilei din dreapta sus și din stânga jos. Puteți aplica doar o singură bucată de conținut generat în partea de sus și una în partea de jos a containerului, pseudo-elementele multiple ::before
și ::after
nu sunt permise. Metoda nu va funcționa dacă doriți să vă creați o tablă CSS Grid! Dacă descoperiți că trebuie să faceți o mulțime de stiluri pentru celule goale, atunci pentru viitorul previzibil, abordarea „Filler B” explicată mai sus este probabil să fie cel mai bun pariu.
Metoda conținutului generat ar putea, de asemenea, să deruteze un viitor dezvoltator care lucrează la proiectul tău. Deoarece țintăm containerul, dacă reutilizați acea clasă în altă parte, va aduce conținutul generat, acest lucru este util dacă asta doriți. În exemplul următor, am adăugat linii decorative de fiecare parte a unui titlu, ar fi rezonabil ca fiecare instanță a unui h1
să aibă acele linii. Ar fi, totuși, foarte confuz dacă nu ai fi conștient că acest lucru se va întâmpla! O linie de comentariu deasupra regulilor containerului vă va ajuta aici. În zilele noastre tind să lucrez într-o bibliotecă de modele, care într-adevăr ajută aceste componente într-un singur loc, făcând mai evident ce se întâmplă atunci când o clasă este aplicată unui element.
Titluri fanteziste
Unul dintre trucurile mele preferate de conținut generat este să stilizez titlurile. În trecut, a trebuit să resping stilurile de titluri care aveau nevoie de wrapper-uri suplimentare și piese de poziționare absolută pentru a le realiza. Când conținutul provine dintr-un CMS, este adesea imposibil să adăugați acele wrapper-uri redundante.
Cu Grid și conținut generat, putem adăuga o linie de fiecare parte a titlului nostru fără a adăuga niciun marcaj suplimentar. Linia va crește și se va micșora în funcție de spațiul disponibil și va reveni elegant la un antet simplu centrat atunci când Grid nu este disponibil în browsere.
Markup-ul nostru este un simplu h1
.
<h1>My heading</h1>
În regulile pentru h1
creez o grilă cu trei coloane. Valoarea grid-template-columns
1fr
oferă o pistă de 1 fr, apoi una de auto
și o pistă finală de 1fr
. Cele două piese de 1fr
vor împărți spațiul disponibil rămas după ce titlul a ocupat spațiul necesar pentru a fi așezat în interiorul piesei cu dimensiune auto
.
Am adăugat proprietatea text-align
cu o valoare de center
în ordinea în care titlul meu este introdus în browserele fără grilă.
h1 { text-align: center; display: grid; grid-template-columns: 1fr auto 1fr; grid-gap: 20px; }
Acum adăugăm conținutul nostru generat, pentru a adăuga o linie înainte și după textul titlului. Înglob aceste reguli într-o interogare de caracteristici, astfel încât să nu primim niciun conținut ciudat generat în browsere fără aspect de grilă.
Linia în sine este o chenar pe elementul generat.
@supports (display: grid) { h1:before, h1:after { content: ""; align-self: center; border-top: 1px solid #999; } }
Asta este tot ce trebuie să faci! Puteți folosi aceeași tehnică pentru a adăuga orice stil sau chiar o pictogramă pe ambele părți ale unui element, deasupra sau sub elementul. Prin plasarea articolului pe o pistă separată, știți că nu există nicio șansă ca elementul să se suprapună textului titlului, ceea ce tinde să fie problema când încercați să faceți acest tip de lucru cu poziționare absolută. De asemenea, aveți avantajul modalităților precise în care articolele pot fi aliniate unul față de celălalt în grilă.
Acesta este un exemplu frumos de îmbunătățire posibilă folosind aspectul grilei de care ați putea profita chiar dacă nu sunteți încă pregătit să vă îndreptați către o reproiectare majoră folosind grila. Se întoarce foarte frumos la un titlu simplu, oamenii cu browsere compatibile primesc atingerea suplimentară și toată lumea primește conținutul. O abordare similară a fost adoptată de Eric Meyer, folosind conținutul generat pentru a adăuga citate ușor de stilat și poziționabil la un element blockquote.
Cu aceste caracteristici mici, adesea nu încep să mă gândesc că voi folosi Grid Layout. În momentul în care încep să-mi dau seama cum să-mi implementez designul, îmi dau seama că este metoda de aspect pe care o aleg. Din acest motiv, îi încurajez pe oameni să nu se gândească la Grid ca fiind pentru aspectul paginii peste componente, dacă faceți acest lucru, s-ar putea să pierdeți o mulțime de oportunități în care vă poate ajuta.
Adăugarea de fundaluri și margini în zonele designului dvs
De asemenea, putem folosi conținutul generat pentru a stivui articole; De fapt, mai mult de un articol poate ocupa o anumită celulă de grilă. Aceasta poate include acele articole inserate cu conținut generat.
În exemplul următor, am un design cu două secțiuni de conținut și un articol cu lățime completă. În spatele conținutului se află un fundal care rulează și sub elementul cu lățime completă.
Marcajul are un container cu secțiunile și elementul de lățime completă ca copii direcți, iar eu folosesc plasarea pe linii pentru a-mi plasa articolele pe grilă.
<article class="grid"> <section class="section1"> <p>…</p> </section> <div class="full-width"> <img src=“placeholder.jpg” alt=“Placeholder”> </div> <section class="section2"> <p>…</p> </section> </article>
.grid { display: grid; grid-template-columns: 1fr 20px 4fr 20px 1fr; grid-template-rows: auto 300px auto; grid-row-gap: 1em; } .section1 { grid-column: 3; grid-row: 1; } .section2 { grid-column: 3; grid-row: 3; } .full-width { grid-column: 1 / -1; grid-row: 2; background-color: rgba(214,232,182,.5); padding: 20px 0; }
Acest lucru îmi oferă aspectul cu imaginea la lățime completă și două secțiuni de conținut plasate; totuși, dacă adaug fundalul secțiunilor, acesta se va opri deasupra row-gap
dintre section
și imaginea cu lățime completă.
.section { background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); }
Dacă am îndepărtat grid-row-gap
și am folosit umplutura pentru a face spațiu, tot nu ar activa efectul de fundal care rulează sub panoul cu lățime completă.
Aici putem folosi conținutul generat. Adaug conținut generat ::before
de containerul grilă și îi dau o culoare de fundal. Dacă nu fac nimic altceva, acest lucru va poziționa conținutul în prima celulă a grilei.
.grid::before { content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); }
Apoi pot poziționa conținutul folosind poziționarea bazată pe linii pentru a se întinde peste zona care ar trebui să arate culoarea de fundal.
.grid::before { content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); grid-column: 2 / 5; grid-row: 1 / 4; }
Puteți vedea exemplul complet în acest CodePen.
Controlul stivei cu z-index
În exemplul de mai sus, conținutul generat este inserat cu ::before
. Aceasta înseamnă că celelalte elemente vin după el, se află în partea de jos a stivei și astfel se va afișa în spatele restului conținutului, unde vreau eu. De asemenea, puteți utiliza z-index
pentru a controla stiva. Încercați să schimbați selectorul ::before
la ::after
. Fundalul conținutului generat se află acum deasupra tuturor, așa cum puteți vedea din modul în care chenarul trece peste imagine. Acest lucru se datorează faptului că acum a devenit ultimul lucru din containerul grilă, este vopsit ultimul și astfel apare „de sus”.
Pentru a schimba acest lucru, trebuie să dați acestui element o proprietate z-index
mai mică decât orice altceva. Dacă nimic altceva nu are o valoare z-index
, cel mai simplu lucru de făcut este să dai conținutului tău generat un z-index
de -1
. Acest lucru va face ca acesta să fie primul lucru din stivă, ca element cu cel mai mic z-index
.
.grid::after { z-index: -1; content: ""; background-color: rgba(214,232,182,.3); border: 5px solid rgb(214,232,182); grid-column: 2 / 5; grid-row: 1 / 4; }
Adăugarea de fundaluri în acest fel nu trebuie să se limiteze la eliminarea unui fundal complet în spatele conținutului dvs. Posibilitatea de a scoate blocuri de culoare în spatele unei părți a designului dvs. ar putea crea unele efecte interesante.
Este acesta ceva pe care specificația l-ar putea rezolva în viitor?
Adăugarea de fundaluri și margini se simte ca o caracteristică lipsă a specificației CSS Grid și una despre care grupul de lucru a discutat împreună cu mulți membri ai comunității (firul de discuții este pe GitHub).
Dacă aveți cazuri de utilizare care nu sunt ușor de rezolvat cu conținut generat, atunci adăugați-vă gândurile la acel fir. Comentariile și cazurile dvs. de utilizare ajută la demonstrarea interesului dezvoltatorilor pentru această funcție și, de asemenea, vă asigurați că orice propunere acoperă genul de lucruri pe care trebuie să le faceți.
Mai multe exemple, vă rog!
Dacă acest articol vă încurajează să experimentați cu conținutul generat sau, dacă aveți deja un exemplu, vă rugăm să îl adăugați în comentarii. Toată lumea este nou în utilizarea Grid în producție, așa că există o mulțime de „ Nu m-am gândit niciodată la asta! ” momente de avut, deoarece combinăm Grid cu alte metode de layout.