css flex schets van mijn site

Kijk Ma, geen media queries

Praatje 09

Responsive design zonder @media queries

Eerst een correctie op de titel. Ik gebruik wél media queries maar alleen voor margin en width aanpassingen. Niet voor responsive layout. Zo, dat is maar gezegd.

Dit is geen ingewikkelde site. Ik heb al eerder gezegd in praatje 8 dat je nooit een ingewikkelde site zou moeten maken. Ingewikkeld staat vrijwel gelijk aan niet toegankelijk. Dat hoef ik toch niet uit te leggen? En toegankelijkheid is mijn hoogste streven. Dat is ook de reden dat ik geen Wordpress gebruik maar schone en toegankelijke code kan schrijven in Textpattern.

Ik geloof dat het altijd mogelijk is om een eenvoudige website te bouwen. Hoe complex de organisatie / opdrachtgever waarvoor je het maakt ook is. Eenvoudig wil ook niet zeggen dat het niet mooi kan zijn. Natuurlijk niet. Over smaak valt te praten. Ik vind deze site mooi. Rustig, overzichtelijk, veel witruimte, goed leesbaar. Maar daar wil ik nu niet over praten.

Responsive design

Het is de laatste jaren niet meer zo moeilijk om een responsive design te maken. Css technieken als grid en flex zijn volledig omarmt door alle moderne browsers. (caniuse) flex pas je toe op 1-dimensionale layouts, een rij of een kolom en grid op 2-dimensionale layouts, meerdere rijen én kolommen.
Voor de responsive layout van een pagina in een website pas ik dus flex toe.

Wie het mobile-first principe toepast bij het maken van een ontwerp zal meestal grijpen naar de mogelijkheid van media queries om de layout van een pagina responsive te maken. De media min-width maakt het mogelijk om naarmate de viewport groter wordt de layout aan te passen. Maar daar zit een groot nadeel aan. De viewport is namelijk waar media queries naar kijken. En dat is lang niet altijd handig. In mijn site zie je op de homepage 3 recente artikelen. Deze staan onder elkaar op een viewport smaller dan 480px. Dan op dezelfde positie naast elkaar tot 900px. Tot zover niets aan de hand want je gebruikt de hele viewport. Vanaf 900px echter staan ze naast elkaar maar dan op de rechterhelft van de pagina en dan is de beschikbare ruimte minimaal 450px. Met media queries die werken vanaf 480px en 900px en door gebruik te maken van min-width op de items zou je het werkend kunnen krijgen. Maar het kan veel eenvoudiger én met minder css.

Flex-wrap

Om items in een flexcontainer automatisch responsive te laten zijn dwz dat ze naar een nieuwe rij schieten wanneer de ruimte beperkt wordt gebruik je ten eerste flex-wrap: wrap. Aan de hand van observeren bepaal je wanneer items het beste onder elkaar of naast elkaar wil tonen. Staan ze naast elkaar maar veel te klein om te zien, dan rek je de viewport op. Staan ze onder elkaar maar zijn ze de items veel te groot dan maak je het breekpunt kleiner. Toch? Kwestie van goed kijken en toegankelijkheid issues vermijden. Voor mij zijn de breekpunten 480px en 900px (en nog eentje vanaf 1280px maar niet voor de layout). Om geen @media queries te hoeven gebruiken zou je een breekpunt willen gebruiken in de flexcontainer zelf. Het schijnt een voorstel te zijn voor het css consortium maar zover lijkt het nog lang niet. Gelukkig is er een soort van flex hack die je kan toepassen op de items met Flex-basis.

Flex-basis

Ik geloof dat heydonworks dit bedacht heeft maar ik weet niet of hij de eerste was. Door css calculaties toe te passen op de flex items kun je het wat vreemde gedrag van flex-basis (en ook flex-grow trouwens) beïnvloeden. Vreemd gedrag want de waardes die je hier gebruikt zijn sowieso zeer relatief en geheel afhankelijk van de inhoud, padding en/of margins in die items. Wie het css box-model begrijpt snapt dit. Enige zekerheid kun je krijgen door belachelijk lage of hoge nummer te gebruiken. Aangezien negatieve nummer niet toegestaan zijn is 0 altijd het minimum. Flex-basis: 0 wil zeggen: bij voorkeur is de breedte 0. De inhoud bepaalt dan de breedte. Wanneer in mijn voorbeeld 3 items deze waarde hebben zullen ze zo klein mogelijk blijven en naast elkaar staan in één rij. Flex-grow bepaalt dan of je de ruimte in de rij wilt opvullen (=>1) of niet (0) Een heel hoge waarde van flex-basis garandeert dat de volledige breedte van de ruimte door ieder item wordt ingenomen en deze dus onder elkaar worden geplaatst. Dit kun je dus gebruiken om op het gewenste breekpunt de layout te wijzigen. Ander voordeel: omdat flex-basis waarden op items van de flex parent staan is deze parent je uitgangspunt en niet de gehele viewport! Ik zal later een voorbeeld geven.

De berekening

Css calc() is de oplossing. Door een gewenst breekpunt te gebruiken kun je precies bepalen wanneer flex-items onder elkaar of naast elkaar zullen komen. Flex-basis: calc((480px – 100%) * 999); Zo wordt de waarde 0 of een hele hoge waarde berekent. De 100% van de flexcontainer is het uitgangspunt. Is de flexcontainer 479px breed dan is de waarde 1px * 999 (999px) en nemen de items de volledige breedte in. Is de flexcontainer 481px dan is de waarde -1 * 999 en dan krijg je een negatief getal dus 0. De flex-items proberen naast elkaar te staan want nemen geen ruimte in behalve die van hun content.
Eigenlijk heel simpel dus. En het mooie is dat de breedte van de viewport dus niet meespeelt. Op deze site staan vanaf 900px de drie Recent items op de rechterhelft van de pagina. Ik heb er voor gekozen om ze meteen naast elkaar te tonen maar wanneer ik ze eerst onder elkaar zou willen zou dat geen probleem zijn. De uitgangswaarde voor de flex-items zou in dat geval niet 900px zijn maar de helft = 450px. Stel ik wil vanaf 900px tot 1200px de items onder elkaar en vanaf daar naast elkaar dan hoef ik niets anders te doen dan het verschil tussen 900px en 1200px = 300px op te tellen bij de 450 en dit als mijn breekpunt te noemen in de flex-basis. Dat zou er zo uitzien: flex-basis: calc((750px – 100%) * 999);
Wanneer er margins en paddings op de buitenste containers zitten wordt de berekening wat ingewikkelder maar met calc() ook goed te handelen.

Conclusie

Het is heel goed mogelijk om een goede responsive layout voor je website te maken zonder gebruik te maken van @media queries. Door gebruik te maken van css berekeningen en te profiteren van het (vreemde?) gedrag van waarden in flex-basis (en flex-grow maar hier niet behandeld) kun je meest complexe layouts creëeren. Maar je weet het: maak het gewoon niet zo complex. Hou het eenvoudig en toegankelijk!

Afbeeldingen

  1. Schetsen van flex ontwerp deze site
  2. Schetsen van flex ontwerp deze site

Praatje #09 is op 2 september geplaatst