Responsive Design

Menu

Pixels

De maat van een pixel

De hardware pixel is de fysieke pixel van het beeldscherm

De CSS pixel is de referentie voor de beeldschermpresentatie

Die CSS pixel heeft verschillende maten afhankelijk van de schermresolutie

De CSS pixel ziet er in alle presentaties optisch hetzelfde uit

Pixel dichtheid

De CSS pixel is gelijk aan een hardware pixel op:

De CSS pixel bevat meer hardware pixels op:

Lijst met schermresoluties van smartphones

Bijvoorbeeld

De iPhone 3 heeft 320x480 hardware/referentie pixels

De iPhone 4 heeft 640x960 hardware pixels...

...maar 320x480 CSS referentie pixels

Objecten zullen optisch dezelfde afmetingen hebben op beide apparaten

Maar op de iPhone 4 zullen ze scherper zijn en betere zoom kwaliteit hebben

De Viewport

De viewport van mobiele apparaten

De standaard viewportbreedte van mobieltjes staat los van de schermresolutie

De viewport van een smartphone zoomt standaard uit om de website in het geheel weer te geven

De viewport van de iPhone schaalt naar 980 x 1024px

De viewport declaratie voorkomt dit schalen van de viewport

De viewport declaratie

Met de viewport declaratie kan je het volgende instellen:

van de viewport op een mobiel apparaat. En uitsluitend op een mobiel apparaat

De viewport declaratie heeft geen enkel nut op desktop screens

De viewport meta tag

<meta name="viewport" content="width=device-width,initial-scale=1">

Jaap Swart's viewportmeter Test 'm op je smartphone

De @viewport regel

@viewport {
    width: device-width;
}
@-ms-viewport {
    width: device-width;
}

Deze CSS-regel wordt ondersteund (en is onmisbaar voor) Windows Phone en IE10 en hoger

Artikel over @viewport

Media Queries

Viewport opties voor media queries

Server requests

Helaas worden alle stylesheets gedownload :-( ...zelfs als een stylesheet niet wordt toegepast omdat het criterium ervan niet van toepassing is

Goed idee dus om nodeloze server requests te vermijden en de CSS in één en dezelfde stylesheet te groeperen

CSS media queries

body {
background-color: #FFF;
}
@media all and (min-width: 37em) {
	body {
 		background-color: #DDD;
	}
}
@media all and (min-width: 50em) {
	body {
 		background-color: #CCC;
	}
}

Mind the indentations!

Let op dat media queries alleen effectief zijn op mobiele apparaten in combinatie with een viewport declaratie

Breakpoints

  1. Ontwerp in de (desktop) browser
  2. Schaal het browservenster om de layout in de verschillende breedtes van de viewport te zien
  3. En voeg een breakpoint toe als de layout hierom vraagt
    er zijn teveel resoluties van mobiele apparaten om rekening mee te houden

Responsive Layout

Content eerst

Denk niet aan design als je de structuur van de inhoud samenstelt

Richt je altijd eerst op de beste semantiek en logische volgorde van de inhoud in HTML

Bijvoorbeeld: een zoekveld, belangrijk genoeg om bovenaan op een beeldscherm te staan, zou ook in de HTML bovenin moeten staan

Mobiel eerst

De layout wordt opgebouwd met verschillende lagen in CSS

De eerste laag bevat de smalste layout - voor mobiel

Deze laag is de basis voor de bredere layout in de volgende laag

Die -op zijn beurt- de basis is voor de volgende, bredere layout

Enzovoort...

Gelaagde layout

De layout lagen worden gemaakt met hulp van media queries

Iedere laag voegt CSS toe bovenop de onderliggende laag en overschrijft mogelijk CSS

Maar er wordt géén CSS gedupliceerd van onderliggende lagen!

Lineaire layout

De eerste layout (voor de kleinste viewports) is lineair:

Breakpoints

Een goed uitgangspunt voor de 2-koloms layout is 600px breed:

@media all and (min-width: 37em)

En voor de 3-koloms layout is dat 800px breed:

@media all and (min-width: 50em)

Mobile-first werkt met min-width (en desktop-first met max-width)

Een super basaal grid

Kolommen

Bij een viewport breed genoeg voor kolommen heb je je eerste media query nodig!

Pas dan werk je in CSS met:

Liquid layout

Superbasic responsive voorbeeld

Stylesheet

body { ... }
@media all and (min-width: 37em) {
	body {...}
}
@media all and (min-width: 50em) {
	body { ... }
}

Grid Layout

Grid

Grid layout is een 2-dimensionaal basislijn grid voor het maken van webpagina layouts

Typische grid layout eigenschappen

Grid Container

Een element met display:grid wordt een grid container
De directe kinderen worden dan grid items
Deze worden standaard op afzonderlijke rijen geplaatst
Zodra er kolommen in het grid zijn gedefinieerd komen meerdere grid items op één rij te staan
Deze grid items kunnen vervolgens overal waar je maar wilt in het grid geplaatst worden

Het grid definiëren

Omdat rijen automatisch worden aangemaakt definiëren we alleen rijen voor de hoogte:

.gridcontainer {
	grid-template-rows: 4em 10em;
}

Kolommen definiëren:

grid-template-columns: 20% 50% 35%;

Tussenruimtes definiëren:

grid-row-gap: 1em; 
grid-column-gap: 2%;

All these properties should be used for the grid container only (and never for the grid items)

Grid items positioneren

Plaats grid tems waar je maar wilt in het grid:

.griditem-1 {
	grid-row: 2 / 5; 
	grid-column: 2 / 4;
}

De nummers staan voor automatisch genummerde gridlijnen - de items worden binnen de lijnnummers geplaatst

Of voeg cellen samen met span:

grid-row: 2 / span 4;
grid-column: 2 / span 2;

Deze eigenschappen worden gebruikt voor uitsluitend grid items (en nooit voor de grid container)

Alignment

The CSS Box Alignment Module wordt ontwikkeld voor de moderne CSS layout modules

Combineer het gebruik hiervan met testen in de browser om verassingen te voorkomen

Geavanceerde grid opties

En er is (nog veel) meer mogelijk

Browserondersteuning

Alle belangrijke moderne browsers ondersteunen grid layout

Gebruik float in een basis layout layer voor verouderde browsers

Plaats de grid layout in een extra CSS layer hier boven op

Dee float wordt gedecativeerd door de grid layout

Blijf caniuse.com checken voor specifieke informatie over browserondersteuning

Feature Queries

Gebruik feature queries om CSS te definiëren voor browsers die grid layout ondersteunen:

@supports (display:grid) {
	#main {
		width: auto;
	}
}

Overschrijf zo in uitsluitend moderne browsers de breedtes gedefinieerd voor #main in de float layout

Flexbox Layout

Flexbox

Flexbox is een 1-dimensionaal system om content boxen in een webpagina te plaatsen, onafhankelijk van de pagina layout

Typical flexbox characteristics are:

Flexbox Best Practice

Flexbox kan gebruikt worden met een progressive enhanced aanpak om oudere browsers te ondersteunen:

Flex Container

Een element met display: flex wordt een flex container
De directe kinderen worden flex items
Deze worden met gelijke hoogtes en flexible breedtes op één rij geplaatst

Flex Items

Je kunt de flexibele breedte van een flex item stoppen door een width in te geven

Maar dit kan conflicteren met de breedtes van de onderliggende basis layout met float

Gebruik in plaats daarvan flex-basis: 50%

Of flex: 0 1 50% wat steno is voor:

Deze eigenschap is bedoeld voor uitsluitend flex items (en nooit voor de flex container)

Flex Wrap

De width van een flex item wordt om te beginnen genegeerd in flexbox

Met flex-wrap:wrap zorg je dat deze gehonoreerd wordt

Bij ruimte tekort schuiven items op naar de volgende rij

Deze eigenschap is bedoeld voor uitsluitend de flex container (en nooit voor flex items)

Flexbox Order

Flex items hebben standaard order:0

order:1:

order:-1

Enzovoort voor 2, 3 en -2, -3 etc.

Deze eigenschap is bedoeld voor uitsluitend flex items (en nooit voor de flex container)

Flexbox pluspunten

Flexbox is vooral handig bij aanpassen van de volgorde en afmetingen van de flex items (volgens inhoud en viewport breedte) zoals bij:

Meer over flexbox op css-tricks.com. En doe de tutorial op flexboxfroggy.com

Responsive Images

Responsive voorgrond afbeeldingen

Sinds we media queries hebben zijn er responsive achtergrondafbeeldingen mogelijk

De voorgrondafbeeldingen bleven de uitdaging!

Responsive images ja of nee?

Responsive images kosten meer bandbreedte

Het aantal kBs van responsive images is meer in vergelijking met een statische afbeelding die exact op maat gemaakt is voor de beschikbare statische breedte:

Responsive images kosten minder bandbreedte

Het aantal kBs van responsive images is minder in vergelijking met één grote en verkleinde fluid image en de bijbehorende 100% CSS width voor alle viewport breedtes:

Use cases

De oplossing

Er zijn 2 attributen beschikbaar:

En 2 elementen:

Artikel van Yoav WeissArtikel van Jason Grigsby

Browsersupport

De lijst met ondersteunende browsers groeit...

Je kunt responsive images vandaag gebruiken!

Niet ondersteunende browsers presenteren de fallback image

Responsive attributen

srcset en sizes

De browser kiest -afhankelijk van de viewport breedte- welke afbeelding er gedownload moet worden, vanuit een serie van exact gelijke afbeeldingen maar in verschillende maten

<img sizes="(min-width: 50em) 50vw, 
            (min-width: 30em) 40vw,
    	    calc(100vw - 30px)" 
     srcset="image-200.jpg 200w, 
   	         image-600.jpg 600w, 
             image-800.jpg 800w, 
             image-1200.jpg 1200w, 
             image-1600.jpg 1600w"
     src="image-800.jpg" 
     alt="description of image">

De volgorde is belangrijk:

De werkelijke breedte van de afbeeldingen in het srcset attribuut komen exact overeen met het aantal pixels breedte ingesteld bij de w waarde

De width en height attributen van img worden niet gebruikt, het conflicteert in de praktijk met het sizes attribuut

Er is gekozen voor een mid-size fallback image voor IE gebruikers

Voorbeeld van een geschaalde afbeelding

Highres en retina images

This is no option in combination with sizes:

<img srcset=" 
   	         image-100.jpg 100w,
             image-200.jpg 2x,
             image-300.jpg 3x,
             image-200.jpg 200w,
             image-400.jpg 2x,
             [...]">

After all... how will the browser know the width of the 2x and 3x images, know which 2x or 3x image to choose?!

This should (and does) work instead:

<img srcset=" 
   	         image-100.jpg 100w,
             image-200.jpg 200w,
             image-300.jpg 300w,
             image-400.jpg 400w,
             image-500.jpg 500w,
             image-600.jpg 600w,
             image-700.jpg 700w,
             image-800.jpg 800w,
             [...]">

The browser knows its screen's pixel density and can choose the image that fits in best

Responsive element

picture

Dit element is bestemd als instructie aan de browser om precies die ene afbeelding weer te geven bij een bepaalde viewport breedte. De browser kiest dus niet zelf de optimale afbeelding uit.

Bestemd voor afbeeldingen die onderling verschillen:

<picture>
    <source media="(min-width: 45em)" srcset="large.jpg">
    <source media="(min-width: 18em)" srcset="med.jpg">
    <img src="small.jpg" alt="place description here"> 
</picture>

Sorteer de source elementen op de breedste viewport naar de smalste (dit is essentiëel voor het gewenste resultaat!)

Voorbeeld picture element Complete artikel Meer mogelijkheden met picture

Picturefill.js

Je kunt picturefill.js gebruiken zodat responsive images werken in alle browsers

Hoewel... in de HTML van responsive images is het img element nog steeds aanwezig als fallback:

Picturefill

Responsive images CSS

Voeg iedere CSS toe die je maar wilt

Maar verzeker je er wel van dat het in het verlengde werkt van je instellingen in HTML... ...voorkom contraproductiviteit en zorg dat de CSS goed samen gaat met de instelling in het sizes attribuut

Scalable Vector Graphics (SVG)

SVG afbeeldingen blijven altijd scherp, ongeacht op welke schaal ze worden gepresenteerd

SVG afbeeldingen worden beschreven in SVG markup language

De browser zal ze eerst berekenen en daarna het resultaat weergeven

Alle moderne browsers ondersteunen SVG, maar de weergave is helaas niet altijd gelijk

css-tricks.com/using-svg/css-tricks.com/scale-svg/w3.org/Graphics/SVG/

Slecht nieuws eerst

Rollovers werken niet op aanraakschermen: aanraken is activeren

Het enige dat we met CSS kunnen toevoegen:

a:link {
  -webkit-tap-highlight-color: #0AF;
}

Een super basaal ingeklapt menu

Bekijk de details

Responsive Typografie

Responsive font sizes

Smallere viewports » kleinere font sizes

Bredere viewports » grotere font sizes

Vloeiende font size in vw werkt niet

De font-size wordt met de maateenheid vw te klein in de smalste viewports en (veel) te groot in de breedste viewports.

We hebben een andere oplossing nodig...

Font basics

Wij weten niet hoe groot een pixel is op het mobiele apparaat van de gebruiker met zijn specifieke resoluties

Vertrouw daarom op de standaard font-size van de kleinste apparaten als de optimale van maat voor de viewport breedte van het apparaat

Gebruik daarom ALTIJD relatieve font-sizes

Met (als uitgangspunt) 100% als de meest gebruiksvriendelijke lettergrootte voor de broodtekst

Laat de gebruiker in controle!

Font-size in de smalste en breedste viewports

In viewport breedtes van 0-50em voldoet in de regel één en dezelfde font-size voor een tekstelement

In viewport breedtes van 75em en breder voldoet in de regel ook één en dezelfde (grotere) font-size voor een tekstelement:

p {
  font-size: 100%;
}
@media screen and (min-width: 75em) {
p {
  font-size: 125%;
}
}

Responsive font size

Bij voorkeur schaalt alle tekst proportioneel

Omdat de font-sizes van alle tekstelementen relatief zijn aan die van de body, beinvloedt dit ze allemaal:

body {
  font-size: 100%;
}
@media screen and (min-width: 75em) {
body {
  font-size: 125%;
}
}

Aanvullend kan je de font-sizes ingeven voor uitsluitend de basis (lineaire) layout van ieder tekstelement dat je wilt

De complete tekst wisselt nu proportioneel van lettergrootte tussen de smalste en breedste viewport

Rest nu nog de font-sizes in de viewport breedtes ertussenin...

Fluid font-size

Maak een vloeiende overgang voor the middelste layout, tussen de kleinere font-size in de smalste viewports en de grotere in de breedste viewports:

@media screen and (min-width: 50em) and (max-width: 75em) {
body { 
	font-size: calc( 1em + (20 - 16) * (100vw - 50em) / (1200 - 800) ); 
}
}

Met deze formule voor de body font-size zal alle text in viewportbreedtes van 50-75em:

Check de formule op smashingmagazine.com/2016/05/fluid-typography/

De formule bestuderen

body { 
	font-size: calc( 1em + (20 - 16) * (100vw - 50em) / (1200 - 800) ); 
}

In viewport breedtes van 0-50em de body font-size is 16px (=100%, gelijk aan de standaard font-size)

In viewports van 75em en breder is deze 20px (=125%)

Bestudeer een geavanceerde versie van deze techniek met CSS variabelen op http://responsive.waalweb.nl

Regelafstand

Regelafstand stel je bij voorkeur in met slechts een waarde, en zonder een eenheid zoals % en em

p {
  line-height: 1.4
}

Zo zal de regelhoogte zoch automatisch aanpassen aan de corresponderende (responsive) lettergrootte

Regellengte

Een comfortabel te lezen regellengte heeft 45-75 karakters per regels

  1. Begin met de responsive lettergrootte
  2. En pas vervolgens de breedte van de container (per breakpoint) aan om het gewenste aantal karakters per regel te krijgen

Tips voor het instellen van de regellengte

Responsive Formulieren

Formulier HTML basics

Plaats de label elementen altijd vóór de invulvelden of the tekstgebieden, goed voor de gebruiksvriendelijkheid

Voorbeelden voor gebruik van aria-labelledby

Het lineaire formulier

  1. Maak het formulier lineair met display:block voor het label element en de form controls
  2. En geef de form controls een volledige breedte:
    input, select, textarea {
      box-sizing: border-box;
      width: 100%;
    }
  3. Rond het formulier af met padding, margin, border etc.

Over box sizing

Het desktop formulier

Het label en de form controls kunnen voor de bredere layouts op één regel geplaatst worden:

* En uiteraard blijven we relatieve breedtes gebruiken in onze responsive forms

Meer CSS details in het basic responsive form sample

Responsive Tabellen

Tabelfeiten

Schaalbare tabel HTML

Bruikbare HTML voor layout:

Schaalbare tabel CSS

Voorbeelden van schaalbare tabellen

Bekijk de oplossingen die we hebben gebruikt:

Responsive Video

Video HTML - in de ideale wereld

Het principe van het HTML5 video element is eenvoud:

<video src="video.mp4" width="500" height="300" controls></video>

Video HTML - in de praktijk

Helaas ondersteunt iedere user agent een ander video formaat:

<video>
  <source src="video-small.m4v" type="video/mp4">
  <source src="video-small.webm" type="video/webm">
  <source src="video-small.ogg" type="video/ogg">
  <source src="video-small.mp4">
  <a href="video.mpg">Bekijk de film hier</a>
</video>

Applicaties zoals Easy HTML5 Video zijn een grote hulp. Desondanks kiezen veel ontwikkelaars voor JWPlayer

Responsive video CSS

Voor de schaalbaarheid is het beter om geen width en height attributen te gebruiken maar te kiezen voor CSS:

video {
  width: 100%;
  height: auto;
}

Aanpak voor YouTube video

Credits

Druk op M voor een overzicht van alle slides

Terug naar begin

/