Kafli 20: Grid

Eins og farið var yfir í umfjöllun um skalanlega vefi er sveigjanlegt umbrot, byggt á grind aðalatriðið við útfærslu. Með flexbox er hægt að komast nokkuð langt en með tækni sem er ekki beint byggð til þess að útfæra grind. Það sést best á því hversu mikla útreikninga þarf að hafa í huga og hálf „hacky“11 „Hack“ eða „hacky“ lausn er oft notað yfir lausnir sem virka en eru ekki þær bestu með tilliti til hraða eða „snyrtileika“ (kóði er langur, flókinn, illskiljanlegur eða allt þrennt). Gæti einnig verið nefnt með „code smell“ eða „technical debt“. útfærslu.

Skjáskot

Skjáskot af caniuse.com árið 2023 sýnir 94,7% stuðning við CSS grid.

Skjáskot frá höfundi.

CSS grid er CSS virkni sem er skilgreind í einingunni „CSS Grid Layout Module Level 1“ sem er í vinnslu hjá W3C. Árið 2023 er einingin ennþá í Candidate Recommendation22 CSS grid hefur verið í vinnslu hjá W3C síðan 2011 og hefur gengið á ýmsu. Seinustu ár hafa Jen Simmons og Rachel Andrew stóðu í ströngu við að ýta á og kenna fólki á tæknina meðan stuðningur var ekki almennur. stöðu en er útfærð í öllum helstu vöfrum í dag. Element notar CSS grid ef því er gefið display: grid;.

20.1 Virkni

CSS grid er notað til að skilgreina skipulag eða útlit (e. layout) á síðu með því að skilgreina raðir (e. rows) og dálka (e. columns) sem efni er staðsett í. Þetta svipar til þess þegar síður voru skipulagðar með <table> en er sérhannað til þess og tekur tillit til skalanleika. CSS grid nýtir hugtakið grind úr grafískri hönnun, ekki birtingu á töflulegum gögnum.

Þegar við skilgreinum grindina okkar notum við nákvæmar eða hlutfallslegar einingar, þó við ættum að halda okkur eins og hægt er við hlutfallslegar einingar vegna skalanleika. Við skilgreinum grid tracks og grid lines sem við staðsetjum hluta (grid items) út frá. Líkt og með flexbox tölum við um grid container ef element hefur skilgreint display: grid; og þá öll börn þess elements sem grindar hluta (grid items).

20.1.1 Grid tracks og grid lines

Grid line er lína í grid sem er talin frá byrjun (talið frá 1) að enda fyrir bæði raðir og dálka. Grid track er plássið á milli lína og er plássið þar sem hlutir lenda, bæði fyrir raðir og dálka.

Skjáskot

Mynd frá MDN: Basic concepts of grid layout.

Á mynd sést skilgreining fyrir grind þar sem við höfum fjögur grid lines fyrir dálka (talið innan grárra hringja) og þrjú grid lines fyrir raðir (talið innan svartra hringja). Grindin hefur þrjú dálka grid track og tvö raða grid track.

20.2 Gildi í CSS grid

CSS grid skilgreinir einingar og föll til þess að vinna með grind og efni innan grindur:

Út frá þessum gildum og föllum má sjá að hugsað hefur verið um að geta skilgreint skalanlegar grindur, ekki eru skilgreindar fastar stærðir heldur bil og leiðir til að úthluta plássi eftir hlutföllum.

20.3 Skilgreining á grid

Þegar við skilgreinum grind með CSS grid getum við annaðhvort skilgreint beint (e. explicit) eða óbeint (e. implicit). Bein skilgreining er gerð með grid-template-columns og grid-template-rows. Ef við skilgreinum ekki beint er dálkum og röðum raðað óbeint og grid track búin til eftir þörfum, það er að segja útfrá því hve mörgum mismumandi grid items þarf að koma fyrir. Við getum stýrt hvernig stærð er útfærð í implicit grid með grid-auto-rows og grid-auto-columns eigindunum. Við getum blandað implicit og explicit grid skilgreiningum.

Fyrir eftirfarandi HTML:

<main>
  <div class="grid">
    <!-- Fyrsta röð -->
    <div class="item item-high">Lorem ipsum</div>
    <div class="item">Lorem ipsum</div>
    <div class="item">Lorem ipsum</div>
    <div class="item item-wide">Lorem ipsum</div>
    <!-- Önnur röð -->
    <div class="item">Lorem ipsum</div>
    <div class="item item-wide">Lorem ipsum</div>
    <div class="item">Lorem ipsum</div>
    <div class="item">Lorem ipsum</div>
    <!-- Þetta item býr til þriðja row trackið -->
    <div class="item">Lorem ipsum</div>
  </div>
</main>

skilgreinum við grind með:

main {
  max-width: 1200px;
  margin: 0 auto;
}
.grid {
  display: grid;
  /* explicit fjórir dálkar sem vilja taka jafnt pláss */
  grid-template-columns: repeat(4, 1fr);
  /* implicit raðir sem eiga að vera minnst 200px eða eins háar og þær þurfa */
  grid-auto-rows: minmax(200px, auto);
  gap: 10px;
}
.item {
  padding: 1rem;
  width: 100%;
  background-color: #999;
}
.item-high { min-height: 300px; background-color: #0f0; }
.item-wide { min-width: 400px; background-color: #0ff; }

og fáum eftirfarandi útlit:

Skjáskot

Birting á grind í 1300px breiðum Firefox vafra.

Skjáskot frá höfundi.

þar sem við höfum fjóra beina (e. explicit) dálka (það verða ekki fleiri en fjórir þrátt fyrir magn og breidd efnis) og óbeinar (e. implicit) raðir (það verða til eins margar raðir og efni krefst). Það sem við sjáum að grind er birt:

20.4 Staðsetning á hlutum á grid

Þegar við höfum skilgreint grindina okkar viljum við oft getað staðsett efni nákvæmlega, við getum þá notað: sjálfvirka staðsetningu, Línu (e. line-based) staðsetningu eða nefnd svæði.

Sjálfvirk staðsetning er sjálfgefin og nýtir grindar hluta staðsetningar reikniritið (e. grid item placement algorithm) til að staðsetja hluta í grind.

20.4.1 Línu staðsetning

Við getum skilgreint hvernig hlutar eru staðsettir í grind með því að nota línu staðsetningu:

Fyrir eftirfarandi HTML:

<main>
  <div class="grid-container">
    <div class="col col-12">
      <div class="box">100% dálkur</div>
    </div>
    <div class="col col-6">
      <div class="box">50% dálkur</div>
    </div>
    <div class="col col-3">
      <div class="box">25% dálkur</div>
    </div>
    <div class="col col-3">
      <div class="box">25% dálkur</div>
    </div>
    <div class="offset-3 col col-3">
      <div class="box">25% dálkur sem byrjar frá 25%</div>
    </div>
    <div class="col col-6">
      <div class="box">50% dálkur</div>
    </div>
  </div>
</main>

skilgreinum við grind með:

:root {
  --max-width: 1400px;
  --columns: 12;
  --gutter: 30px;
  --offset: 20px;
}
main {
  margin: 0 auto;
  width: calc(100% - (2 * var(--offset)));
  max-width: var(--max-width);
}
.grid-container {
  display: grid;
  grid-template-columns: repeat(var(--columns), 1fr);
  gap: var(--gutter);
}
.col-12 { grid-column-end: span 12; }
.col-6 { grid-column-end: span 6; }
.col-3 { grid-column-end: span 3; }
.offset-3 { grid-column-start: 4; }

og fáum eftirfarandi útlit:

Skjáskot

Birting á grind í 1400px breiðum Firefox vafra með grind lagða yfir.

Skjáskot frá höfundi.

20.4.2 Nefnd svæði

Með því að nota grid-template-areas getum við gefið svæðum nöfn til að einfalda staðsetningu og síðan notað grid-area til að tilgreina hvaða element fari í hvaða nefnda svæði. Við getum einnig blandað nefndum svæðum og línu staðsetningu, t.d. með grid-column: first / middle;.

Fyrir eftirfarandi HTML:

<div class="container">
  <header>Header</header>
  <nav>Navigation</nav>
  <main>Main area</main>
  <footer>Footer</footer>
</div>

skilgreinum við grind með nefndum svæðum:

.container {
  display: grid;
  width: 100%;
  min-height: 100vh;
  /* skilgreinum „mobile first“ nefnda grind */
  grid-template-areas:
    "header"
    "nav"
    "main"
    "foot";
  /* skiptum lóðréttu plássi út frá hlutfalli af viewport með vh */
  grid-template-rows:
    minmax(10vh, auto) minmax(20vh, auto) minmax(60vh, auto) minmax(10vh, auto);
}
@media (min-width: 1000px) {
  .container {
    grid-template-areas:
      "header header"
      "nav    main"
      "nav    foot";
    /* áfram hlutfallslega en núna aðeins þrjár raðir */
    grid-template-rows:
      minmax(20vh, auto) minmax(60vh, auto) minmax(20vh, auto);
    /* höfum tvö dálka og skilgreinum hlutfallslega með fr */
    grid-template-columns: 2fr 8fr;
  }
}
/* staðsetjum hvert og eitt element í nefnd svæði */
header { grid-area: header; background-color: #8ca0ff; }
nav { grid-area: nav; background-color: #ffa08c; }
main { grid-area: main; background-color: #ffff64; }
footer { grid-area: foot; background-color: #8cffa0; }

og fáum eftirfarandi útlit:

Skjáskot

Birting á grind í 1000px breiðum Firefox vafra.

Skjáskot frá höfundi.
Skjáskot

Birting á grind í 500px breiðum Firefox vafra.

Skjáskot frá höfundi.