flexbox
Dropp unødvendige tabeller og «float». Her får du en innføring i «Flexbox»
For en del år siden, etter at bruken av rammer (frames) gikk av moten, var det vanlig å bruke tabeller når man skulle dele inn websider i ulike seksjoner. Selv om dette – med celler som spenner over flere kolonner eller rader – hadde det med å skape litt vanskeligheter for utviklerne, gjorde det nytten, fordi sidene stort sett skulle vises på pc-skjermer.
Riktignok var det nok litt forskjell på oppløsningen til disse skjermene. Men tok man utgangspunkt i skjermer med relativt lav oppløsning, ville sidene se brukbare ut hos de aller fleste.
Den mobile weben, og da særlig med introduksjonen av smartmobiler, endret dette. Nå skulle websidene også kunne leses på små skjermer med dårligere oppløsning enn selv de dårligste pc-skjermene.
I mange tilfeller førte dette til at nettstedeierne lagde to versjoner av nettstedet, en vanlig utgave og en mobilutgave. Dette førte til betydelig merarbeid. Samtidig økte floraen av skjermstørrelser og -oppløsninger. I stedet for å lage enda flere versjoner av hver side, tok mange i bruk det som gjerne kalles for responsiv eller flytende design, hvor plasseringen og størrelsen på innholdet tilpasses størrelsen på skjermen.
Dette har i flere år vært mulig å få til med bare HTML og CSS, primært på grunn av Media Queries og @media-regelen i CSS, som gjør det enkelt å definere egne CSS-regler for enheter og skjermer som har visse egenskaper, for eksempel skjermbredde på mer enn et gitt antall piksler. I 2011 fikk IE9, som den siste av de store nettleserne, støtte for CSS3 Media Queries. Før dette har man måttet bruke JavaScript for å bestemme skjermbredden – slik som i dette eksempelet fra 2004.
Samtidig har man ved hjelp av for eksempel div-elementet eller listeelementer som ul og li, kombinert med float- og posisjoneringsreglene i CSS, kunnet lage seksjonsinndelte sider uten å bruke tabeller. Men heller ikke dette oppleves alltid som det perfekte verktøyet for oppgaven, spesielt når man skal lage en webapplikasjon med et relativt omfattende brukergrensesnitt eller innhold som varierer i størrelse.
I mange år har CSS-standardiseringsmiljøet jobbet med få fram alternative måter for å definere layouten til websider. I særlig grad er det to CSS-moduler som utpeker seg, CSS Flexible Box Layout Module Level 1 (Flexbox) og CSS Grid Layout Module Level 1 (Grid Layout). I denne artikkelen konsentrerer vi oss om Flexbox.
Flexbox
Mest aktuell i dag er Flexbox, siden den allerede i flere år har blitt støttet av alle moderne nettlesere. Også Internet Explorer 11 har egentlig offisielt full støtte for Flexbox. Men det er flere feil i implementeringen, og ingenting tyder på at de noen gang vil bli rettet, siden Microsoft velger å bruke ressursene på Edge i stedet.
Å bruke moderne webteknologier som dette, forutsetter at man er villige til å ignorere brukerne av Internet Explorer og andre utdaterte nettlesere. Man kan selvfølgelig lage en reserveløsning for disse. Men da forsvinner mye av hensikten ved å ta i bruk de nye teknologiene, nemlig å gjøre det enklere å få til ting.
Før vi går videre, er det viktig å understreke at Flexbox ikke er noen universalløsning som alene kan erstatte bruken av float. Den skal primært egne seg for opprette én rekke/kolonne med seksjoner i én retning, horisontalt eller vertikalt, for eksempel en meny, eller andre mindre områder på sidene. Flexbox er fleksibelt og tilpasningsdyktig, men dette kan gå litt utover opplevelsen av kontroll, siden hver rad eller kolonne opptrer som en ny Flexbox som ikke tar hensyn til hvordan elementene i den forrige er plassert.
Skal man derimot opprette et mer tradisjonelt rutenett (grid), er det Grid Layout man etter hvert bør vurdere å ta i bruk. Les mer om dette valget her.
Når man leser gjennomgangen nedenfor, kan det være lurt å opprette en enkel HTML-fil å teste i mens man leser. Da er det mye enklere å forstå konseptene.
Et eksempel på en slik HTML-snutt, er den nedenfor, som gir en Flexbox med tre barneelementer på en horisontal linje. Det er kun CSS-regelen display:flex; som har noe med Flexbox å gjøre i dette enkle utgangspunktet. Resten av CSS-en er der bare for å sette størrelser, farger og kantlinjer tilsvarende det vi har brukt i illustrasjonene i saken.
<!doctype html><html><head><style type="text/css"> #test { /* regler for flexboksen */ display:flex; border: 3px solid black; padding:5px; height:250px; max-width:800px; background-color: lightgrey; } #test div{ /* regler for hver av barneelementene */ border: 3px solid blue; color: white; font-weight:bold; font-size:30px; background-color:grey; }</style></head><body> <div id="test" > <div id="item1" >item1</div> <div id="item2">item2 more text</div> <div id="item3">items3</div> </div></body></html>
Display: flex
I tradisjonell websidelayout forholder man seg til layoutmodusene «block» og «inline», hvor den førstnevnte er vertikalt orientert, mens «inline» er horisontalt orientert. I tillegg har man layoutmodusene tabell og posisjonering.
Med Flexbox etablerer man en flex-konteiner med CSS-regelen display: flex. Denne konteineren kan så fylles med en rekke barneelementer som kan fordeles i enhver flytretning. Barneelementene kan ha en fleksibel størrelse, slik at de kan fylle ut ubrukt plass i flex-konteineren, eller krympes for å ikke flyte over grensene til konteineren.
Elementene og innholdet kan justeres både horisontalt og vertikalt.
Retning
De spesielle CSS-egenskapene til flex-konteineren, som for eksempel kan være et div- eller section-element, styrer primært retningen og justeringen til barneelementene.
Barneelementene kan vises horisontalt fra venstre mot høyre eller fra høyre mot venstre, eller vertikalt ovenfra og ned, eller nedenfra og opp. Dette kontrolleres med CSS-egenskapen flex-direction og verdiene row, row-reverse, column og column-reverse.
Det er tre ulike egenskaper man kan bruke for å stille opp innholdet en flex-konteiner på. Den første er justify-content, som justerer innholdet langs det som er den horisontale hovedaksen (main axis) til hver linje med barneelementer i konteineren. Gruppen av barneelementer kan venstre- eller høyrejusteres, eller sentreres.
Men de kan også fordeles på linjen slik at det er lik avstand mellom dem – uavhengig av bredden på det enkelte barneelementet. Dette gjøres med justify-content-verdien space-between. Det første og det siste barneelementet vil da plasseres helt ytterst, henholdsvis til venstre og høyre, i konteineren (men likevel avhengig av padding-verdiene), mens resten fordeles jevnt i plassen som gjenstår.
Utfylling
Det er også mulig å fylle ut like mye på hver side av alle barneelementene, også til venstre for det første barneelementet og til høyre for det siste, med justify-content-verdien space-around. Men fordi alle elementene setter av plass på begge sider, vil anstanden mellom hvert av elementene være dobbelt så stor som den avstanden det første og det siste elementet har til konteinerkanten.
Tilsvarende kan man også justere barneelementene vertikalt på en linje i konteineren ved hjelp av align-items-egenskapen. Standardverdien for denne er stretch, noe som innebærer at alle barneelementene strekkes til hele høyden av konteineren, med mindre høyden til barneelementene allerede er fastsatt med height eller max-height.
Man kan også justere barneelementene slik at grunnlinjen til hvert element sidestilles. Dette gjøres med align-items-egenskapen baseline.
I utgangspunktet vil alle barneelementene i en flex-konteiner stilles opp på én linje.
Men ved behov, enten fordi man ønsker det eller fordi den horisontale plassen er for liten til at alle barneelementene kan vises med ønsket bredde, kan bryte elementene som ikke får plass på den første linje, ned på linjen(e) under.
Brekking
Dette gjøres ved å sette verdien til egenskapen flex-wrap til wrap. Det er også mulig å snu kryssaksen med verdien wrap-reverse, slik at aksen starter nederst. Da vil barneelementer som ikke får plass på den første linjen, bli vist på linjen(e) over i stedet.
Dersom konteineren består av flere linjer, bruker man align-content-egenskapen til å justere innholdet vertikalt. Da kan man bruke de samme verdiene som støttes av justify-content og oppnå den sammen fordelingen og justeringen av barneelementene, bare vertikalt.
Individuelle egenskaper
Alt vi har skrevet til nå, er egenskaper som gjelder for hele samlingen av barneelementer i en flex-konteiner. Men i mange tilfeller ønsker man at enkelte barneelementer skal behandles individuelt.
I tillegg til de mange velkjente egenskapene som man kan gi HTML-elementer, kan individuelle barneelementer i en flex-konteiner også ha egenskapen align-self. Denne fungerer helt identisk med align-items-egenskapen til konteineren, men gjør det mulig for individuelle barneelementer å bryte ut av mønsteret som de andre må følge. Dersom alle elementene er toppjusterte med align-items: flex-start, kan ett eller flere barneelementer for eksempel være bunnjusterte ved hjelp av align-self: flex-end.
Plassfordeling
Barneelementene har også flere andre egenskaper. I utgangspunktet tar hvert barneelement nøyaktig den plassen som innholdet krever, uten at for eksempel tekst brytes. Blir elementene samlet sett større enn konteineren, vises de på utsiden av grensene til denne.
Med egenskapene flex-grow, flex-shrink og flex-basis kan man justere hvordan bredden til hvert element skal opptre. Standardverdien for flex-grow er 0. Økes denne til 1, vil elementet også forsyne seg av den eventuelt ledige, horisontale plassen som gjenstår i konteineren, når alle de andre elementene i flexboksen har fått den bredden innholdet krever.
Dersom flex-grow-verdien til alle barneelementene er satt til 1, vil den ledige, horisontale plassen i konteineren bli fordeles likt på alle barneelementene, uavhengig av hvor stor plass barneelementet i utgangspunktet har. Men dette gjelder bare når flex-basis-egenskapen har standardverdien auto.
Er flex-basis til et barneelement satt til å være en gitt bredde, for eksempel 50px, anses dette som bredden barneelementet skal få tildelt, allerede før den ledige, horisontale plassen fordeles.
Men også verdien til flex-grow kan settes høyere. Har man for eksempel tre barneelementer på en linje i en flex-konteiner, hvorav to har flex-grow-verdien 1 og den siste har flex-grow-verdien 2, vil den sistnevnte få tildelt dobbelt så mye av den ledige plassen som hver av de to andre.
Rekkefølgen
Den siste egenskapen vi tar med i vår gjennomgang av Flex Layout, er barneelementegenskapen order. Barneelementenes rekkefølge kan nemlig styres med CSS-regler, delvis uavhengig av rekkefølgen de er lagt inn i HTML-koden. Standardverdien for order er 0. Jo lavere tallverdi, desto tidligere i rekken vises barneelementet. Også negative verdier er tillatt.
I en kommende artikkel skal vi gjøre en tilsvarende gjennomgang av hvordan Grid Layout kan tas i bruk. Det som er den aktuelle utgaven av Grid Layout, støttes foreløpig ikke av alle moderne nettlesere, men det er trolig kun et tidsspørsmål før støtten er på plass i nettleserne som gjenstår.