Adaptive design med grid (CSS)
Del 2: Placering af elementer




Eksplicit opdeling af brugerfladen med grid-template-areas

Placeringen af items i vores grid kan gøres eksplicit, hvilket antageligt er den intuitivt mest forståelige metode. Hvis man har navngivet sine items med grid-area parameteren (mere om denne parameter i Del 3), kan man bruge grid-template-areas, som kan have flg. værdier:

<grid-area-navnet>Navnet på grid area, som man har specificeret med grid-area.
.Et punktum betyder en tom celle


For at koden fungerer, skal alle felter angives.


Lad os se på et eksempel, så det giver mening:

Hvis vi kigger på et standard-layout som bl.a. WordPress bruger, skal vi bruge en header, en footer som begge fylder hele bredden, en smal sidebar til log-on og et område til sidens indhold. Sidebaren skal have en fast bredde, og der skal være et område til venstre for sidebaren, hvad vi gør med en tom celle med fast bredde. Så, vi skal bruge et grid på 3x3, så vi får et layout der ser således ud:

Header
IndholdTomSidebar
Footer


Denne opbygning har fire items, som vi kalder item 1 til 4 i vores stylesheet, og navngiver med grid-area:

.item-1 {
   grid-area: Header;
}

.item-2 {
   grid-area: Indhold;
}

.item-3 {
   grid-area: Sidebar;
}

.item-4 {
   grid-area: Footer;
}


Vi er nu klar til at fortælle at vi skal have et grid med tre søjler, hvor bredden på den første er auto og de to andre er hhv. 30 og 150px i bredden. Højden på alle rækker skal tilpasses indholdet, dvs. den skal være auto, og sidst, men ikke mindst, skal vi fortælle, at hvilke celler der bruges til hvilke items i vores layout:

.Container {
   display: grid;
   grid-template-columns: auto 30px 150px;
   grid-template-rows: auto;
   grid-template-areas:
      "Header Header Header"
      "Indhold . Sidebar"
      "Footer Footer Footer";
}


Vigtigt: Alle række skal have det samme antal deklarerede celler!

Vi har nu et fungerende grid. Herfra er det tilretning, så det ser pænt ud.


Eksplicit opdeling af brugerfladen med grid-template

Parameteren grid-template er en sammentrækning af grid-template-rows, grid-template-columns og grid-template-areas. Syntaksen er grid-template: "grid-template-areas" | grid-template-rows / grid-template-columns (bemærk skråstregen som adskiller). Man kan sætte værdien for alle tre parametre til none, hvorved parametrene sættes til deres initial-værdier.

Det er en sammentrækning, der nok skaber mere rod end mindre kode, som ellers er idéen med sammentrækningerne, så alene derfor anbefales det ikke at bruge grid-template. Der er også den detalje, at grid-template heller ikke laver en reset af de implicitte grid-egenskaber (grid-auto-columns, grid-auto-rows og grid-auto-flow), som man i de fleste tilfælde ønsker, så man kan også ende med nogle uønskede sideeffekter med koden.

For lige at demonstrere syntaksen, så vil koden for containeren oven over i stedet komme til at se således ud:

.Container {
   display: grid;
   grid-template:
   "Header Header Header" auto
   "Indhold . Sidebar" auto
   "Footer Footer Footer" auto / auto 30px 150px
}



Implicit opdeling af brugerfladen

I stedet for en eksplicit placering af items i grid, kan man lave en implicit placering. Det er en anden måde at tænke placering af items på end den eksplicitte, og ikke så intuitiv. Til gengæld kan man med den lave en dynamisk struktur, som den eksplicitte placering ikke tillader.

Der er to tilgange til den implicitte placering, og man kan uden problemer kombinere dem.


Automatisk genererede søjler og rækker med grid-auto-columns og grid-auto-rows

Metoden tager udgangspunk i et grid som vi kender det, f.eks. en container med to søjler der er 40px brede og to rækker der er 25px høje:

.Container {
   display: grid;
   grid-template-columns: 40px 40px
   grid-template-rows: 25px 25px
}


Det som de implicitte angivelser kan, er at tillade at man refererer til placeringer der ikke findes, dvs. i et grid på 2x2 celler kan man godt placere et item i række 3, celle 5.

Hvis man i det ovenstående grid specificerer, at man vil have item-1 i række 1, celle 1 og item-2 i række 2, celle 4 med grid-column og grid-row (gennemgås i del 3), ser koden således ud:

.item-1 {
   grid-column: 1 / 2;
   grid-row: 1 / 2;
}

.item-2 {
   grid-column: 5 / 6;
   grid-row: 2 / 3;
}


item-1
item-2


Defaultvidden og -højden (track size) for de autogenererede rækker/søjler er 0px, hvilket i virkeligheden er ubrugeligt, men man kan specificere sine track sizes på de autogenererede rækker/søjler, med de to variabler grid-auto-columns og grid-auto-rows, f.eks. en container med autogenererede søjler der er 60px brede og automatisk tilpasning af højden:

.Container {
   grid-auto-columns: 60px
   grid-auto-rows: auto
}


Eftersom vi med grid-column har specificeret at der skal være tre ekstra søjler, og nu har specificeret, at disse er 60px brede, kommer grid nu til at se således ud.

item-1
item-2



Flow af items med grid-auto-flow

Man kan på sin brugerflade ønske at have items der har en fast placering og andre der skal flyde rundt på den resterende plads, afhængig af viewportens størrelse. Til dette formål har vi grid-auto-flow, som kan antage flg. værdier:

VærdiEffekt
rowAutomatisk placering af items på række i koderækkefølge
columnAutomatisk placering af items i søjler i koderækkefølge
denseAutomatisk placering af items i grid, hvor der er plads, uanset koderækkefølge
row denseAutomatisk placering af items i rækker i grid, hvor der er plads, uanset koderækkefølge
column denseAutomatisk placering af items i søjler i grid, hvor der er plads, uanset koderækkefølge


Bemærk: Dense placerer efter hvor der er plads, hvilket ikke nødvendigvis er i en hensigtsmæssig rækkefølge for sidens læselighed. Man skal derfor bruge dense med lidt omtanke.

Lad os lige se på et lille eksempel:

Hvis vi har en container med seks items, kaldet item-1 til -6, i et grid på 6x2 celler, hvor item-1 og -6 skal danne en venstre og højre søjle på siden (f.eks. et navigationspanel til venstre og en reklamesøjle til højre):

item-1 item-6


Koden for containeren med de 6 items er:

<DIV CLASS="Container">

   <DIV CLASS="item-1">item-1</DIV>
   <DIV CLASS="item-2">item-2</DIV>
   <DIV CLASS="item-3">item-3</DIV>
   <DIV CLASS="item-4">item-4</DIV>
   <DIV CLASS="item-5">item-5</DIV>
   <DIV CLASS="item-6">item-6</DIV>

</DIV>


Den tilhørende klasse .Container er indtil videre:

.Container {
   display: grid;
   grid-template-columns: 40px 40px 40px 40px 40px 40px;
   grid-template-rows: 25px 25px;
}


Og klasserne for item-1 og -6 er:

.item-1 {
   grid-column: 1;
   grid-row: 1 / 3;
}

.item-6 {
   grid-column: 6;
   grid-row: 1 / 3;
}


Vi vil have de resterende items til at flyde. Her sætter vi flow til at være i række, så vi tilføjer dette til containeren:

.Container {
   display: grid;
   grid-template-columns: 40px 40px 40px 40px 40px 40px;
   grid-template-rows: 25px 25px;
   grid-auto-flow: row;
}


Fordi vi bruger grid-auto-flow, behøver vi ikke at specificerer hvor vi vil have item-2 til -5. De vil automatisk blive anbragt på række mellem item-1 og 6, dvs. sådan her:

item-1item-2item-3item-4item-5item-6


I det viste eksempel er alle items lige store, men det behøver de ikke være, og man kunne sagtens forestille sig items der havde varierende størrelse. Hvis f.eks. item-3 bliver dobbelt så bredt som de andre items, omarrangerers items i gruppen item-2 til -5:

item-1item-2item-3item-4item-6
item-5


Havde vi i stedet haft grid-auto-flow: column, havde det set således ud:

item-1item-2item-4 item-6
item-3item-5



Udslutning af grid i containeren

Det grid man har lavet, behøver ikke at være stort nok til at udfylde hele grid-containeren. Det kunne f.eks. være fordi alle søjler er med fast bredde, som til sammen er mindre end hele containerens bredde. Udslutningen af grid i containeren styres af justify-content. Det er helt analogt til udslutning af tekst og udslutning af items i flexbox. Værdierne som justify-items kan antage er:

VærdiEffekt
startGrid er alignet med containerens forkant
endGrid er alignet med containerens bagkant
centerGrid er centreret i containeren
stretchGrid strækkes til at udfylde containerens i bredden. Kræver at mindst en af søjlerne i grid ikke har faste bredder.
space-between Søjlerne i grid adskilles og fordeles i bredden med samme afstand. Afstanden til containerens sider ændres ikke.
space-aroundSøjlerne i grid adskilles og fordeles i bredden med samme afstand. Afstanden til containerens sider er halvdelen af afstandene mellem søjlerne.
space-evenlySøjlerne i grid adskilles og fordeles i bredden med samme afstand. Dette inkluderer afstanden til containerens sider.


justify-content: start


justify-content: end


justify-content: center


justify-content: stretch


justify-content: space-between


justify-content: space-around


justify-content: space-evenly



Lodret udslutning af grid

Det grid man har lavet, behøver ikke at være stort nok til at udfylde hele grid-containeren. Det kunne f.eks. være fordi alle rækker er med fast højde, som til sammen er mindre end hele containerens højde. Lodret udslutningen af grid i containeren styres af align-content. Det er helt analogt til vertical-align af tekst og lodret udslutning af items i flexbox. Værdierne som align-content kan antage er:

VærdiEffekt
startGrid er alignet med containerens top
endGrid er alignet med containerens bund
centerGrid er centreret i containeren
stretchGrid strækkes til at udfylde containerens i højden. Kræver at rækkerne i grid ikke har faste højder.
space-between Rækkerne i grid adskilles og fordeles i højden med samme afstand. Afstanden til containerens top og bund ændres ikke.
space-aroundRækkerne i grid adskilles og fordeles i højden med samme afstand. Afstanden til containerens top og bund er halvdelen af afstandene mellem rækkerne.
space-evenlyRækkerne i grid adskilles og fordeles i højden med samme afstand. Dette inkluderer afstanden til containerens top og bund.


align-content: start


align-content: end


align-content: center


align-content: stretch


align-content: space-between


align-content: space-around


align-content: space-evenly



Vandret og lodret udslutning af grid samtidig

Variablen place-content er en sammentrækning af align-content og justify-content. Syntaxen er place-content: align-content / justify-content (bemærk skråstreg som adskiller). Variablen understøttes angiveligt ikke af Edge-browseren pt. (august 2019), så man bør overveje om det er en variabel man vil bruge, eller evt. teste om den er kommet til at fungere efter denne side er skrevet. Som altid frarådes herfra at bruge disse sammentrukne variabler, da man mister overskuelighed i koden.


Den samlede variabel grid

Man kan samle alle sine variabler for sit grid i en variabel der blot hedder grid. Syntaksen er grid: grid-template-rows grid-template-columns grid-template-areas grid-auto-rows grid-auto-columns grid-auto-flow. Af hensyn til kodens overskuelighed frarådes det at bruge denne sammentrukne variabel.