Adaptive design med grid (CSS).
Del 1: Søjler, rækker, celler og items




Hvad går det ud på?

En af de metoder man kan anvende til adaptive design er det der hedder grid. Det er en feature der er kommet med CSS3 og som har store anvendelsesmuligheder.

Det som grid går ud på, er at opdele brugerfladen i søjler og rækker, som man allokerer til forskellige dele af sit layout, f.eks. header, footer, sidebar, osv. Fordelen ved at bruge grid, i stedet for den klassiske tabel, er at grid er fleksibel, så de elementer man har i sit grid kan flyttes rundt og ændre størrelse. I forhold til de udfordringer som er opstået med varierende skærmstørrelser, fordi vi tilgår internettet på mange forskellige devices, giver grid nogle klare designmæssige fordele. Især hvis man kombinerer det med flexbox i sidens layout-elementer.


De enkelte elementer i grid

Grid er, ligesom flexbox, bygget op om en container og items, men modsat flexbox, er der en række strukturelle elementer, som er nødvendige at holde styr på. Så, hvis vi starter fra en ende af:

Containeren og items
Containeren er den overordnede beholder til items, dvs. med enkelte undtagelser, vil dette være en DIV, der kommer umiddelbart efter BODY-tag'en. Variablen man skal bruge er display:grid, dvs. noget i retning af dette her:

<BODY>
<DIV STYLE="display:grid">

</DIV>
</BODY>


Har man brug for det, er der også display:inline-grid.

Sædvanligvis skal man have en del styling på sin container, så normalt vil man have en klasse der indeholder display:grid i stedet. Det behøver strengt taget ikke at være en DIV man bruger. Det skal nødvendigvis være en tag der kan indeholde andre elementer, men det behøver ikke være en DIV. De child-elementer man nu indsætter i grid, bliver nu automatisk til grid items. Også her anbefales at bruge DIV. Selv hvis man skal bruge f.eks. et billede eller en IFRAME til video, er det erfaringsmæssigt bedst at bruge en DIV og have sit billede eller video deri. Lad os sige, at vi har fire items, så kommer det til at se således ud:

<BODY>
<DIV STYLE="display:grid">

<DIV CLASS="Item-1"> </DIV>
<DIV CLASS="Item-2"> </DIV>
<DIV CLASS="Item-3"> </DIV>
<DIV CLASS="Item-4"> </DIV>

</DIV>
</BODY>


Grid line
Grid lines er linjerne der opdeler ens grid. Hvis vi ser på et 3x2 grid, er det overgangen mellem de dannede rækker eller søjler, og man skelner mellem lodrette (column grid lines) og vandrette (row grid lines). Her en lodret grid line fremhævet med rødt:



Grid cell
Grid cell er, som navnet antyder, en celle. Her er det grid cell 2 i første række der er markeret:



Grid track
Grid track er det der er mellem to grid lines der ligger ved siden af hinanden, dvs. en række eller søjle af celler. Her er det grid track mellem 2. og 3. lodrette grid line der er markeret:



Grid area
Grid area er et område bestående af flere sammenhængende celler. Det må gerne være over flere rækker og søjler, men behøver ikke at være det, men kan godt i stedet være en del af et grid track. Her er det grid area mellem 1. og 3. lodrette grid line og 1. og 3. vandrette grid line der er markeret:




Afstande mellem rækker og søjler

Som default er cellerne i ens grid sat til at sidde sammen, men man kunne godt forestille sig, at man ville have noget mellemrum mellem cellerne, svarende til en tabel hvor man har border-collapse:separate og en angivelse af afstanden mellem cellerne med border-spacing.

Variablerne hedder hhv. grid-column-gap og grid-row-gap og en angivelse af den ønskede afstand, f.eks.:

.Container {
   grid-column-gap: 10px;
   grid-row-gap: 10px
}

Så cellerne adskilles således:

Man skal være opmærksom på, at der kun kommer afstand mellem cellerne. Afstanden til containerens sider er uændrede.

Det er planen, at de to variabler skal erstattes af column-gap og row-gap dvs. de gamle navne uden præfixet grid-. De nye variabelnavne fungerer allerede for nogle browsere, i de nye versioner. Syntaxen bliver i så fald:

.Container {
   column-gap: 10px;
   row-gap: 10px
}


Der er en samlet version af grid-column-gap og grid-row-gap. Denne hedder grid-gap hvor værdierne er grid-row-gap grid-column-gap, i den rækkefølge. Syntaxen bliver således:

.Container {
   grid-gap: 10px 10px;
}

Hvis man kun angiver én værdi for grid-gap, sættes grid-row-gap og grid-column-gap til samme værdi.


Søjler og rækker i grid

Variablerne grid-template-columns og grid-template-rows er der hvor man specificerer hvor mange søjler og rækker man vil have, dvs. antallet af celler, og hvilken størrelse cellerns skal have. Der ligger også i de to variabler, at man kan give rækker og søjler et navn. Syntaksen for begge er navnet i kantede paranteser efterfulgt af størrelsen. Ved angivelse af størrelse har man flere muligheder:

absolut størrelseFast størrelse f.eks. px, mm, osv.
relativ størrelseFast andel af den samlede bredde/højde, dvs. % af samlede bredde/højde
autoFleksibel størrelse, svarende til den tilgængelige plads i bredde og højde.
frFraktion af den frie plads i containeren


I praksis vil man kombinere typerne af størrelsesangivelse, efter hvad der er mest hensigtsmæssigt, og dette er problemfrit. Lad os se på nogle eksempler, så det giver mere mening.

Opbygningen
Antallet af rækker og søjler specificeres ved at man angiver en bredde/højde, adskilt med mellemrum. Her er det en container med fire søjler, hvor de yderste er 40px brede og de to inderste er 50px brede. Der er to rækker, hvor den øverste er 20px høj og den nederste er 100px høj:

.Container {
   grid-template-columns: 40px 50px 50px 40px;
   grid-template-rows: 20px 100px;
}

I modsætning til størrelse, er navngivningen ikke påkrævet. Navnet skrives i kantede paranteser foran bredden. Her navngiver vi anden søjle og første række:

.Container {
   grid-template-columns: 40px [søjle 2] 50px 50px 40px;
   grid-template-rows: [række 1] 20px 100px;
}

Fordi opbygningen er som den er, kan man derfor godt komme ud for at en celle får to navne, og dette er ikke noget problem.

Har man flere søjler eller rækker med samme størrelse efter hinanden, kan man bruge repeat(), hvor man angiver antal gentagelser og bredde/højde. Her skal man i sagens natur udvise lidt omtanke, hvis man angiver størrelsen i procenter. Koden for en container med 3 søjler à 40px bredde, efterfulgt af en søjle med 100px bredde, vil se således ud:

.Container {
   grid-template-columns: repeat(3, 40px) 100px;
}

Hvis man angiver et navn på søjlen/rækken der skal gentages, får disse også sammen navn. Her får vi således tre søjler med navnet test-søjle:

.Container {
   grid-template-columns: repeat(3, [test-søjle] 40px) 100px;
}

Skal man senere referere til en specifik søjle af de tre, gør med dette ved at skrive navn og nummer, dvs. den tredje af de tre ens søjler hedder "test-søjle 3".


Absolut størrelsesangivelse
Absolut størrelsesangivelse er en fast størrelse, angivet i f.eks. px, mm, cm, osv. I dag, hvor vi har så mange forskellige devices med forskellig skærmopløsning, er px gerne det mest hensigtsmæssige at anvende, f.eks.:

.Container {
   grid-template-columns: 40px 50px 50px 40px;
}



Relativ størrelsesangivelse
Relativ størrelsesangivelse er en fast størrelsesandel, angivet i %. I dag, hvor vi har så mange forskellige devices med forskellig skærmopløsning, er px gerne det mest hensigtsmæssige at anvende, men kode med procentandele er f.eks.:

.Container {
   grid-template-columns: 20% 60% 20%;
}



auto
Fleksibel størrelsesangivelse med auto er den resterende bredde/højde. Til sider kombinerer man ofte elementer der har en fast bredde og elementer der så må bruge den tiloversblevne plads, afhængig af størrelsen på viewporten. Dette kunne f.eks. være et navigationspanel eller en reklamesøjle. For brugere af WordPress er det f.eks. log-in-panelet i højre side. Et grid med tre søjler, hvor de to yderste skal være 100px i bredden, og den midterste søjle tager resten af viewportens bredde bliver således:

.Container {
   grid-template-columns: 100px auto 100px;
}

Man kan som sådan godt have flere søjler med auto, også ved siden af hinanden, men har man brug for dette, giver det mere mening af bruge fraktion, fr.


fr
Fraktionen fr er egentlig en slags underinddeling af auto, idet en resterende bredde/højde deles op i fraktioner. Skal man have en søjle i 100px bredde og den resterende plads i tre lige store søjler, kommer det til at se således ud:

.Container {
   grid-template-columns: 100px 1fr 1fr 1fr;
}

Søjlerne behøver ikke at være ved siden af hinanden. Her er søjlen på 100px søjle nr. 2 i rækken:

.Container {
   grid-template-columns: 1fr 100px 1fr 1fr;
}

Det indbyrdes størrelsesforhold behøver heller ikke være 1:1. Her er søjlen længst til højre gjort dobbelt så stor som de to andre:

.Container {
   grid-template-columns: 100px 1fr 1fr 2fr;
}