artikler
CSS Grid Layout: Snart er ventetiden over
Nå begynner også den siste, gjenstående biten å komme på plass.
Som vi skrev for en måneds tid siden, har webstandardmiljøet og nettleserleverandørene de siste årene jobbet for å etablere webstandarder som gjør det enklere å definere strukturen til websider og webapplikasjoner.
I den forrige artikkelen gikk vi gjennom hvordan det som formelt heter CSS Flexible Box Layout Module Level 1, men som gjerne omtales som flexbox, kan brukes.
Flexbox er en ganske moden teknologi som støttes av alle moderne nettlesere, selv om spesifikasjonen ennå ikke har blitt godkjent som en webstandard av W3C.
I denne artikkelen skal vi se nærmere på en litt teknologi som er noe mindre moden, men som kanskje vil være mer nyttig for det store flertallet av webutviklere, nemlig CSS Grid Layout Module Level 1, Grid Layout eller bare «grids».
Utdatert i IE og Edge
Det første offentlige utkastet til CSS Grid Layout ble primært skrevet av Microsoft-ansatte så tidlig som i 2011. Ikke lenge etter skal Internet Explorer ha fått eksperimentell støtte for det. Men i ettertid har spesifikasjonsutkastet blitt oppdatert en rekke ganger og nye forfattere har kommet til, uten at implementeringen i IE eller etterfølgeren Edge skal ha blitt fornyet.
Det betyr at Edge er den eneste moderne nettleseren som ikke støtter den oppdaterte spesifikasjonen. For i mars kom både Firefox 52, Chrome 57 og Safari 10.1 med offisiell støtte for CSS Grid Layout. Det samme gjelder de øvrige, Blink- og Chromium-baserte nettleserne.
Venter på Microsoft
Selv om en av redaktørene av dagens spesifikasjonsutkast til CSS Grid Layout er fra Microsoft, så er det først i løpet av den siste måneden at Microsoft har kunngjort konkrete planer om å implementere CSS Grid Layout i nettleseren. På statussiden heter det nå at teknologien er under utvikling.
Det betyr trolig at det bare er et tidsspørsmål før også Edge får støtte for den oppdaterte grids-spesifikasjonen. Det er først da man kan forsvare å bruke den på offentlige websider.
Velger man fortsatt å støtte Internet Explorer, må man enten lage en spesialløsning for IE eller droppe CSS Grid Layout fullstendig i mange år framover.
Til saken
Så hva er egentlig CSS Grid Layout, og hva er forskjellen mellom dette og flexbox?
CSS Grid Layout er ifølge spesifikasjonen en ny layoutmodell for CSS som har kraftige egenskaper til å kontrollere størrelsen og posisjonen til bokser på en webside, samt boksenes innhold.
Dette kan man kanskje si gjelder flexbox også. Men der hvor flexbox handler om å plassere bokser langs én enkelt akse, hvor det er plassfordelingen lang denne aksen som er det sentrale, er CSS Grid Layout optimalisert for layouter hvor man ønsker å rette inn innhold i to dimensjoner, uten å være så avhengig av det underliggende HTML-hierarkiet for å bygge mer komplekse layouter.
I tillegg er CSS Grid Layout optimalisert for responsiv design av brukergrensesnitt.
I likhet med flex, er grid en verdi til CSS-egenskapen display. Denne vil omdanne et konteinerelement, for eksempel en div eller hele body, til en grid på block-nivå.
Grunnleggende eksempel
Selv om CSS Grid Layout har en del felles med Flex Box, så er mulighetene med CSS Grid Layout betydelig større, men også litt mer krevende å sette seg inn i. I denne artikkelen skal vi derfor bare gå gjennom hvordan man kan bruke CSS Grid Layout til å definere en temmelig enkel, men mye brukt brukergrensesnittutforming, før vi mot slutten henviser til langt mer omfattende gjennomganger av hva CSS Grid Layout åpner for.
Den klassiske nettsteddesignen som vi har i tankene, er kanskje litt «ut» for tiden, men fungerer likevel godt som et eksempel for hvordan CSS Grid Layout kan brukes. Den består i praksis av et hode («masthead»), et navigasjonsfelt, en bunntekst («footer») og et felt for selve innholdet. Den vil typisk se slik ut:
Det har «alltid» vært mulig å lage websider med en slik utforming, men med CSS Grid Layout er det enklere og mer fleksibelt enn med tabell og float, spesielt når man også skal ta hensyn til ulike skjermstørrelser og dermed bruke responsiv design.
Terminologi
Siden vi nå skal gå i gang med selve grid-kodingen, er det på tide å forklare noen grunnleggende begreper som beskriver grid-en, eller rutenettet. Dette er nødvendig å forstå for at man senere skal kunne definere hvilke deler av grid-en som skal brukes til hva.
Det første er grid lines. Dette er de horisontale og vertikale linjene som grid-en er delt opp i. Området mellom parallelle linjer, enten horisontalt eller vertikalt, kalles for grid tracks. Dette tilsvarer kolonnene og radene i en vanlig tabell. Krysningspunktet mellom en grid-kolonne og en grid-rad kalles for en grid cell. En slik celle behøver ikke å ha noe innhold. Flere tilstøtende celler kan logisk sett samles i en grid area, omgitt av fire grid-linjer.
Flere veier til målet
Eksempelsiden over tar utgangspunkt i følgende enkle HTML-snutt:
<!DOCTYPE html><head> <style type="text/css"> </style></head><body> <header>Hode</header> <nav>Navigasjon</nav> <main>Hovedområdet</main> <footer>Bunntekst</footer></body>
Resten er gjort med CSS. Bortsett fra noen enkle CSS-regler for teksten og fargene, er alt annet basert på CSS Grid Layout.
Det første vi har gjort, er å definere selve grid-en. Vi har valgt å dele siden inn i to kolonner og tre rader. Det har vi gjort med disse CSS-reglene:
body { display: grid; grid-template-rows: 100px auto 100px; grid-template-columns: minmax(150px, 1fr) 3fr;}
Den første regelen forteller at body-elementet skal være en grid, altså et rutenett. De to neste reglene forteller hvordan dette rutenettet skal deles inn.
Med regelen grid-template-rows oppgir man antallet rader i rutenettet. For hver rad oppgir man en verdi for høyden. Her har vi satt den øverste og den nederste raden til å være 100 piksler høye, mens høyden til den midterste raden justerer seg selv for å fylle den resterende plassen i grid-konteineren, i dette tilfellet body.
Fraction unit
Med grid-template-columns oppgir vi over at det skal være to kolonner. Her utnytter vi også noen flere av valgmulighetene CSS Grid Layout tilbyr. Den første verdien, som gjelder for kolonnen lengst til venstre, oppgir vi en minimums- og en maksimumsbredde. Minimumsbredden er 150 piksler, mens maksimumsbredden er 1fr. Det sistnevnte er en forkortelse av fraction unit. Den andre kolonnen har bredden 3fr.
Dette innebærer at begge kolonnene bidrar til å fylle hele bredden i grid-en, men at høyrekolonnen skal være tre ganger så bred som venstrekolonnen, så sant det er plass til det. I eksempelet over er det ikke plass til å opprettholde dette forholdet dersom den tilgjengelige bredden er mindre enn 600 piksler, siden venstrespalten aldri kan være mindre enn 150 piksler bred.
Da har vi definert at grid-en og grid-elementene, altså innholdet i grid-konteineren, blir fordelt bortover den første raden så lenge det er flere plasser (kolonner) igjen. Deretter går man videre til neste rad, og så videre.
Spenn
Nå er ikke dette riktig det vi ønsker. Vi ønsker at noen av elementene skal strekke seg over flere celler, og på riktig sted.
Det er flere måter å gjøre dette på med CSS Grid Layout, men den enkleste handler rett og slett om å fortelle rader og/eller kolonner hvert element skal spenne over. Det gjør vi i eksempelet nedenfor, også her bruker vi to ulike teknikker.
header { grid-column: 1 / 3;}nav { grid-row: 2 / span 2;}footer{ grid-column: 2 / 3; grid-row: 3 / span 1;}
Hodet på websiden vår, altså header-elementet, skal spenne over begge de to kolonnene. Vi bruker her CSS-regelen grid-column, med verdiene 1 og 3. Dette skyldes at verdiene man oppgir, ikke referer til kolonnene, men til de vertikale grid-linjene som kolonnene ligger mellom.
Navigasjons- eller sidefeltet, som utgjøres av nav-elementet, skal være i den venstre kolonnen, men spenne over to rader.
Med grid-row-regelen har vi oppgitt at det skal starte ved den andre grid-linjen, men i stedet for å oppgi at det skal sluttet ved den fjerde grid-linjen, har vi oppgitt at det skal spenne over to rader (altså med span 2)
Bunnteksten, som footer-elementet utgjør, skal i vårt eksempel ligge på den tredje raden og spenne over den andre kolonnen. Selv om vi ikke har oppgitt noen grid-row-verdi for nav eller grid-column-verdi for header, så er CSS-reglene tilstrekkelige for at nettleseren skal finne ut hvordan grid-elementene skal plasseres.
CSS-styrt plassering
For main-elementet, altså hovedområdet, har vi ikke oppgitt verdier for verken grid-row eller grid-column. Det betyr at elementet blir plassert der det er ledig plass. I alle fall i dette eksempelet har rekkefølgen som de fire grid-elementene er oppgitt på i HTML-kode, ingen betydning.
Men vi kan gjerne sette footer først og header sist, og siden vil se akkurat lik ut.
Dette gjør at plasseringen av elementene styres fullt og helt av CSS-reglene, noe som er ideelt når man dynamisk skal kunne tilpasse brukergrensesnittet til ulike skjermbredder.
Alternative metoder
Med de nevnte grid-template-rows- og grid-template-columns-reglene kan man også gi grid-linjer navn.
I eksempelet nedenfor har vi definert at nav-elementet skal starte på grid-linjen mellom den første og den andre raden, og slutte etter den tredje raden, samt at header-elementet skal starte på den første vertikale grid-linjen og avsluttes på den siste.
body { display: grid; grid-template-rows: 100px [nav-start] auto 100px [nav-slutt]; grid-template-columns: [header-start] minmax(150px, 1fr) 3fr [header-slutt];}
I stedet for å skrive:
header { grid-column: 1 / 3;}nav { grid-row: 2 / span 2;}
kan vi da skrive:
header { grid-column: header-start / header-slutt;}nav { grid-row: nav-start / nav-slutt;}
Resultatet blir det samme. Ved å bruke grid-area man gjøre det hele mer kompakt:
body { display: grid; grid-template-rows: 100px auto 100px; grid-template-columns: minmax(150px, 1fr) 3fr; grid-template-areas: "header header" "nav main" "nav footer";}header { grid-area: header;}nav { grid-area: nav;}
Til grid-template-areas oppgir man navnene på de ulike cellene i grid-en. Hver rad, fra topp til bunn, defineres med en tekststreng hvor navnene på cellene er atskilt med et mellomrom. Celler som har identiske navn, slås sammen til samme grid-area.
De to siste reglene i eksempelet over forteller hvilke HTML-elementer hvert grid-area tilhører.
Ressurser
I CSS Grid Layout har man tilsvarende regler som i Flex Layout for å justere grid-elementene og elementenes innhold horisontalt og vertikalt. Man kan justere størrelsen på grid-linjene og eller å få elementene til å fordele seg automatisk andre rekkefølger eller retninger. Det finnes også flere regler som kombinerer to eller flere andre regler, slik at man kan skrive det hele mer kompakt.
Det er mange som har kommet med detaljerte guider og andre ressurser for hvordan benytter CSS Grid Layout utover det som er vist i dette eksempelet. Det er alltid lurt å ta en titt i blant på selve spesifikasjonen, men det finnes guider og eksempler som er enklere å forstå. Grid by Example er et godt utgangspunkt og forfatteren holder et timelangt foredrag om CSS Grid Layout i denne videoen.
Som referanse kan denne detaljerte gjennomgangen til CSS-Tricks være nyttig, mens Mozilla har en omfattende gjennomgang på denne siden.
Et litt artig eksempel på hva man kan bruke CSS Grid Layout til, er dette monopolbrettet.
Les også: Tror mange vil skrive om webapplikasjonene sine for å ta i bruk WebAssembly