CSS Subgrid: Alinierea Perfectă a Cardurilor Imbricate
Cea mai mare limitare a specificației originale CSS Grid era faptul că o grilă se oprea la copiii direcți. Elementele aflate în interiorul unui card (titlu, paragraf, buton de preț) nu puteau comunica cu elementele din cardul vecin. Specificația CSS Grid Level 2: Subgrid elimină definitiv această problemă.
1. De ce grilele imbricate obișnuite eșuau?
Dacă declarai display: grid pe un container părinte și apoi display: grid pe fiecare card copil, cele două grile funcționau complet izolat. Cardul copil își calcula propriile rânduri fără să știe nimic despre conținutul sau înălțimea cardurilor din jur.
Pentru a repara acest lucru, dezvoltatorii erau nevoiți să recurgă la scripturi JavaScript greoaie care măsurau înălțimile sau la înălțimi fixe artificiale (precum min-height: 80px pe titluri), o abordare fragilă la traduceri sau ecrane diferite.
2. Sintaxa Nativă Subgrid: grid-template-rows: subgrid
Cu Subgrid, îi ceri copilului să împrumute rândurile sau coloanele definite deja pe containerul părinte:
/* 1. Containerul parinte defineste grila principala */
.pricing-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
/* 2. Fiecare card ocupa 4 randuri din grila parinte si activeaza Subgrid */
.card {
grid-row: span 4; /* Ofera spatiu pentru: Header, Feature-list, Pret, Buton */
display: grid;
grid-template-rows: subgrid; /* Magia: imprumuta cele 4 randuri ale parintelui! */
}
3. Scenariu Real din Producție: Tabelul de Prețuri (Pricing Cards)
Iată structura HTML tipică a unui set de carduri de abonament:
<div class="pricing-grid">
<!-- Cardul 1 -->
<article class="card">
<h3 class="card-title">Pachet Starter</h3>
<p class="card-desc">Pentru mici proiecte personale.</p>
<div class="card-price">9 € / lună</div>
<button class="btn btn-primary">Comandă acum</button>
</article>
<!-- Cardul 2: titlu mult mai lung pe 3 randuri -->
<article class="card">
<h3 class="card-title">Pachet Enterprise Profesional pentru Companii Mari</h3>
<p class="card-desc">Include suport dedicat 24/7, SLA garantat de 99.9% și servere dedicate de mare viteză.</p>
<div class="card-price">99 € / lună</div>
<button class="btn btn-primary">Comandă acum</button>
</article>
</div>
Datorită liniei grid-template-rows: subgrid;:
- Toate titlurile
.card-titlevor avea garantat exact aceeași înălțime, determinată de cel mai lung titlu din oricare dintre cele 3 coloane; - Toate descrierile
.card-descvor începe și se vor termina exact la aceeași linie orizontală; - Toate butoanele de acțiune din subsol vor fi riguros aliniate milimetric pe aceeași linie de bază, fără niciun spațiu gol inestetic.
4. Moștenirea și Suprascrierea Gap-ului
În mod implicit, un subgrid moștenește proprietatea gap a grilei părinte. Cu toate acestea, ai flexibilitatea deplină de a seta un gap diferit exclusiv în interiorul subgrid-ului:
.card {
display: grid;
grid-template-rows: subgrid;
row-gap: 8px; /* Reducem spatierea dintre elementele interne ale cardului */
}
5. Suport Cross-Browser și Îmbunătățire Progresivă (Progressive Enhancement)
În prezent, CSS Subgrid se bucură de suport universal complet pe toate browserele moderne (Google Chrome 117+, Firefox 71+, Apple Safari 16+, Microsoft Edge 117+).
Dacă trebuie să oferi compatibilitate pentru browsere mai vechi, folosește direct interogarea nativă @supports:
/* Fallback clasic cu Flexbox pentru browsere legacy */
.card {
display: flex;
flex-direction: column;
}
.card button {
margin-top: auto; /* Impinge butonul in partea de jos */
}
/* Extensie moderna pentru browsere care inteleg Subgrid */
@supports (grid-template-rows: subgrid) {
.card {
grid-row: span 4;
display: grid;
grid-template-rows: subgrid;
}
}
Specificații W3C și Referințe Consultate:
- W3C CSS Grid Layout Module Level 2 (Subgrid specification): w3.org/TR/css-grid-2/#subgrids
- MDN Web Docs — CSS Subgrid: developer.mozilla.org/CSS_grid_layout/Subgrid
- Can I Use — CSS Subgrid Browser Support: caniuse.com/css-subgrid