Over CSS display:flex (Flexbox)

Met de introductie van display:flex en display:inline-flex is het veel eenvoudiger geworden om flexibele lay-outs te maken met alleen CSS. Deze techniek is in korte tijd zo populair geworden, dat het een eigen naam heeft gekregen: Flexbox.

Met Flexbox is het mogelijk om responsive websites te maken.

Op deze bladzijde wordt beschreven hoe je Flexbox kunt inzetten voor een responsive lay-out. De focus ligt daarbij op display:flex (dus op block-elementen) omdat die het meest worden gebruikt.
Een goede toepassing van inline-flex ben ik nog nergens tegengekomen. Ken je er een? Stuur een mailtje!

Bij het schrijven van dit verhaal is uitgegaan van diverse bronnen. De belangrijkste zijn:
• w3schools.com, in het bijzonder de HTML-DOM- en CSS-references over display:flex en daarmee gerelateerde zaken.
• CSS-tricks.com, in het bijzonder de bladzijde over het toepassen van Flexbox.

Toepassing van Flexbox in je eigen website vraagt een hoop studie en proberen. De hierboven genoemde link helpt daarbij. Deze bladzijde beperkt zich tot een eenvoudige opsomming van de CSS-eigenschappen van Flexbox en wat ze doen.

Structuur
Een Flexbox bestaat altijd uit een container waarbinnen zich elementen bevinden die zich "flex" gedragen. De container wordt ook parent genoemd. De elementen in de container worden child genoemd. Deze namen worden in de rest van dit verhaal gebruikt.
Deze structuur kan worden genest. De children kunnen zelf ook flexbox zijn, dus parent zijn met eigen children.

HTML en CSS
Hieronder een voorbeeld van zeer basic code voor een flexbox. De CSS staat in de <head>, de HTML zet je in de <body>

<style>
#main {
  width: 350px;
  height: 100px;
  border: 1px solid #c3c3c3;
  display: flex;
}
</style>
 
<div id="main"> <!-- parent -->
  <div style="background-color:lightgreen;"></div> <!-- child -->
  <div style="background-color:lightblue;"></div> <!-- child -->
  <div style="background-color:lightgrey;"></div> <!-- child -->
</div>

Zowel de parent als de children hebben eigen CSS-eigenschappen. Op die manier kun je het gedrag van de website-lay-out heel precies sturen.

CSS-eigenschappen voor de parent-elementen

Eigenschap Beschrijving
display 
Waarden:flex of inline-flex
De children van dit element hebben "flex"-eigenschappen, box-element resp. als inline-element.
flex-direction 
Waarden:row of row-reverse, column of reverse-column.
row De children van dit flex-element worden in een rij gezet, van links naar rechts. Dit is de default-waarde.
row-reverse De children worden in een rij gezet, van rechts naar links.
column De children worden in een kolom gezet, van boven naar beneden.
column-reverse De children worden in een rij gezet, van beneden naar boven.
N.B.: De beschrijving van row en row-reverse gelden voor talen die van links naar rechts worden gelezen, zoals de westerse talen. Bij talen die van rechts naar links worden gelezen, zoals het Arabisch, is de richting waarin de rij wordt opgebouwd ook van rechts naar links bij row, en van links naar rechts bij row-reverse.
flex-wrap: 
De children worden per default achter elkaar gezet. Je gebruikt flex-wrap als je ze naar een nieuwe regel wilt sturen als er geen ruimte meer is in de parent. Daarvoor heb je drie mogelijkheden:
nowrap Dit is de default waarde. De flex-items staan in een lange, horizontale rij.
wrap De flex-items worden naar een nieuwe "regel" gestuurd als de huidige "regel" vol is, van boven naar beneden.
wrap-reverse Als wrap, maar dan van beneden naar boven.
flex-flow: 
Dit is een verkorte schrijfwijze voor flex-direction en flex-wrap. Je geeft eerst de richting op, daarna de wrapping. Bijvoorbeeld:
flex-flow:column wrap. Default is flex-flow:row nowrap.
justify-content: 
Hiermee leg je de ruimte-verdeling vast tussen de opeenvolgende children. Dit is in horizontale richting. Mogelijke instellingen zijn:
flex-start Dit is default waarde. De children worden tegen de linker zijkant aangeschoven in de parent gezet.
flex-end De children worden rechter zijkant aangeschoven in de parent gezet.
center De children worden gecentreerd in de parent gezet.
space-between De children worden gelijkmatig over de breedte van parent verdeeld. Het eerste child wordt aangeschoven tegen de linkerkant, het laatste child wordt tegen de rechter zijkant aangeschoven. De vrije ruimte tussen de children wordt gelijkmatig verdeeld.
space-around Elk child heeft dezelfde 'marge' links en rechts. Daardoor lijkt de ruimte tussen het eerste en het laatste child kleiner dan de ruimte tussen de children onderling.
space-evenly Alle vrije ruimtes tussen de children en de linker en rechter zijkant zijn even groot.
align-items: 
Hiermee leg je de ruimte-verdeling vast tussen de opeenvolgende children. Dit is in verticale richting. De volgorde van plaatsing kan worden geregeld met justify-content. Mogelijke instellingen zijn:
flex-start De children worden tegen de bovenrand van de parent geplaatst.
flex-end De children worden tegen de onderrand van de parent geplaatst.
center De children worden verticaal gecentreerd in de parent geplaatst.
baseline De children worden zo uitgelijnd, dat de eerste regel tekst in de children even hoog staat.
stretch De children worden in verticale richting uitgerekt, zodat de de hele hoogte van de parent wordt gebruikt. Dit is de defaultwaarde.
align-content: 
Hiermee leg je de ruimte-verdeling vast tussen de opeenvolgende children. Dit is in verticale richting. De volgorde van plaatsing kan worden geregeld met justify-content. Mogelijke instellingen zijn:
flex-start De children worden tegen de bovenrand van de parent geplaatst.
flex-end De children worden tegen de onderrand van de parent geplaatst.
center De children worden verticaal gecentreerd in de parent geplaatst.
space-between De eerste 'regel' met children wordt tegen de bovenkant van de parent geplaatst. De laatste 'regel' wordt tegen de onderkant in de parent geplaatst. De rest wordt gelijkmatig verdeeld. De verticale tussenruimtes aan de boven- en onderkant zijn anders dan tussen de 'regel's onderling.
space-around Alle vrije ruimtes in verticale richting, tussen de children en de boven- en onderkant zijn even groot.
stretch De children worden in verticale richting uitgerekt, zodat de 'regel's even hoog zijn. Dit is de defaultwaarde.
 
align-content werkt niet als er maar één 'regel' met children is.

CSS-eigenschappen voor de child-elementen

Eigenschap Beschrijving
order: 
De flex-items worden per default in de container geplaatst in de volgorde waarin ze in de code staan. Dat komt overeen met order:0. Door order een andere waarde te geven kun je die volgorde veranderen.
• Als parameter geef je een geheel getal op.
• Negatieve getallen zijn mogelijk. order:-1 betekent dat het betreffende element vóór een element met een hogere waarde van order komt, maar ná een element met een lagere waarde.
flex-grow: 
Hiermee geef je aan dat een child-element meer of minder kan groeien (uitdijen in de breedte) dan andere child-elementen. De instelling flex-grow:2 laat het betreffende element twee zo groot worden als de andere child-elementen, mits daar ruimte voor is.
Default waarde is 1. De instelling flex-grow:0 maakt het betreffende element onzichtbaar doordat de breedte nul wordt.
Getallen kleiner dan nul zijn niet toegestaan.
flex-shrink: 
Dit is hetzelfde als flex-grow, maar dan de andere kant op: dit bepaalt voor een child-element de mogelijkheid om te krimpen, en in welke verhouding dat gebeurt ten opzichte van de andere child-elementen.
Default waarde is 1. Een waarde gelijk aan nul lijkt hetzelfde resultaat te geven als flex-grow:2. Negatieve getallen zijn niet toegestaan.
flex-basis: 
Hiermee bepaal je de breedte van een child-element vóórdat de vrije ruimte wordt herverdeeld. Het is een breedte (bijv. 20px, 30em, enz.) of het keyword auto:
auto Dit is de default waarde. Het betekent zoveel als: gebruik de eigenschap width of height of bepaal de afmetingen die volgen uit de content.
flex: 
Dit is een verkorte schrijfwijze voor flex-grow, flex-shrink en flex-basis, in deze volgorde. Default is flex:0 1 auto. De laatste twee waarden mogen worden weggelaten.
Een andere schrijfwijze is flex:none, wat hetzelfde is als flex:0.
 
Gebruik van flex wordt aanbevolen boven de drie losse componenten apart.
align-self: 
Als je in de parent box align-items hebt voorgeschreven, kun je dat voor een enkel child-element overschrijven. De mogelijke waarden zijn:
auto Dit is de default waarde. Het betekent dat er niets veranderd wordt. De child neemt de instelling van de parent over.
• Zie align-items voor de overige mogelijkheden.

Bekende problemen met Flexbox
• De eigenschappen float, clear, text-align en vertical-align hebben geen effect op een child binnen een flexbox parent.

Tenslotte
Soms hoor je wel eens wat over een grid-systeem zoals Bootstrap, maar dan in 'native' CSS. Iets dergelijks kan ook met CSS. Dat wordt door alle grote browsers ondersteund.

Opmerking:
 
De overige mogelijkheden van display: worden beschreven in het item Over CSS display.

 
terug

html-496; Laatste wijziging: 29 april 2020