H12 - Media queries en responsive layout
00 - De bestaande Holy Grail-site wordt responsive
Je gaat verder met dezelfde desktopsite uit H11. Op een smal scherm komen de hoofddelen onder elkaar en passen menu, footer, kaarten en tabel zich aan. De eindopdracht is het afronden en controleren van je bestaande werk.
01 - Waarom responsive design?
Een website wordt bekeken op grote schermen, laptops, tablets en telefoons. Een layout die op een breed scherm mooi werkt, kan op een smal scherm te krap worden.
Responsive design betekent dat de layout zich aanpast aan de beschikbare schermruimte. De HTML blijft meestal hetzelfde. De CSS verandert de plaatsing, breedtes en soms de volgorde.
- Op een desktop kun je meerdere kolommen naast elkaar zetten.
- Op een telefoon zet je onderdelen meestal onder elkaar.
- Media queries gebruik je om CSS-regels alleen bij bepaalde schermgroottes toe te passen.
- De inhoud blijft bereikbaar op elk scherm.
Actie — Alleen oefenen
- Open de bestaande H11-site eerst breed en daarna steeds smaller. Noteer waar navigatie, zijbalk, projectkaarten, afbeeldingen of tabel te krap worden.
- Maak nog geen andere site en wis geen inhoud. Dit is een observatieproef met de bestaande Holy Grail-indeling.
- Je lost de gevonden problemen in de volgende items op in dezelfde style.css.
02 - Wat is een media query?
Een media query stelt een voorwaarde. De CSS binnen de query geldt alleen wanneer die voorwaarde klopt. Deze tijdelijke proefrand maakt zichtbaar wanneer de query actief is, ook boven je achtergrondafbeelding.
@media (max-width: 900px) {
.site-header {
border: 4px solid var(--kleur-accent);
}
}
@mediastart de voorwaarde.max-width: 900pxgeldt tot en met 900 pixels vensterbreedte.- Boven 900 pixels doet deze proefregel niets.
- Je gewone externe CSS blijft op beide breedtes werken.
Actie — Alleen oefenen
- Voeg de tijdelijke randquery onderaan dezelfde style.css toe en bekijk Home boven en onder 900px.
- Controleer dat alleen op het smalle venster de extra proefrand verschijnt.
- Verwijder de hele proefquery daarna en herstel je gewone header-rand. De echte responsive layoutquery komt bij item 8.
03 - Desktop eerst of mobiel eerst?
Desktop eerst begint bij een brede layout en vereenvoudigt die met max-width. Mobiel eerst begint bij één kolom en breidt die met min-width uit. Voor jouw bestaande H11-site kiezen we desktop eerst; je hebt de brede indeling al.
Desktop eerst: onze aanpak
/* De bestaande drie-kolomsregels staan hierboven. */
@media (max-width: 900px) {
body {
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
}
Mobiel eerst: alleen ter vergelijking
body {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas: "header" "nav" "main" "aside" "footer";
}
@media (min-width: 901px) {
body {
grid-template-columns: 190px minmax(0, 1fr) 230px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
}
Verander bij named areas niet alleen het kolomaantal: ook de rijen en de tekening moeten bij de nieuwe indeling passen. Voeg de twee aanpakken niet allebei toe. In item 8 maken we onze desktop-eerstquery compleet.
Actie — Bouw verder
- Kies voor deze site desktop eerst: de bestaande Holy Grail-regels zijn de basis, de aanpassingen voor smal komen onderaan dezelfde style.css.
- De mobiel-eerstcode in de uitleg is alleen ter vergelijking; voeg die niet als tweede aanpak aan je stylesheet toe.
- Bewaar de bestaande body-template. Straks veranderen we kolommen, rijen én named areas samen bij dezelfde grens.
04 - De Holy Grail layout
De Holy Grail layout is een klassieke webdesign-layout. Hij bestaat uit een header bovenaan, een navigatiekolom links, hoofdinhoud in het midden, een zijbalk rechts en een footer onderaan.
+--------------------------------------+
| header |
+----------+----------------+----------+
| nav | main | aside |
+----------+----------------+----------+
| footer |
+--------------------------------------+
headerstaat bovenaan.navstaat links.mainis de belangrijkste inhoud.asideis extra informatie aan de rechterkant.footerstaat onderaan.
Vroeger was deze layout lastig te maken. Met CSS Grid en named grid areas is hij overzichtelijk.
Actie — Controleer en rond af
- Vergelijk je bestaande desktopsite met het Holy Grail-schema: header/footer over de breedte, nav links, main midden en aside rechts.
- Herstel alleen afwijkingen in de bestaande template. Deze indeling heb je in H11 al gebouwd; je bouwt hem hier niet opnieuw.
- Controleer dat menu en footer nog flexbox gebruiken en main de eerdere inhoud bevat.
05 - HTML voor de layout
De bestaande semantische body-structuur blijft gelijk. In de head hoort ook een viewport-instelling, zodat telefoons je media queries op hun werkelijke apparaatbreedte kunnen gebruiken. Geef de vier pagina’s ieder een eigen title en description.
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Mijn eigen projecten en interesses.">
<title>Home | Sam de Vries</title>
<link rel="stylesheet" href="style.css">
</head>
Alle pagina’s verwijzen naar dezelfde externe style.css. Inline CSS en style-blokken waren tijdelijke oefeningen en horen niet in deze eindversie.
Actie — Bouw verder
- Controleer in de head van alle vier de pagina's
<meta name="viewport" content="width=device-width, initial-scale=1">en voeg deze regel toe als hij ontbreekt. - Deze instelling laat een telefoon de layout op de echte apparaatbreedte weergeven. Behoud charset, title, description en de link naar dezelfde style.css.
- Controleer ook dat de vijf hoofdonderdelen direct in body staan. Je vervangt geen bestaande pagina door het HTML-schema.
06 - Grid-area namen geven
Elk onderdeel krijgt in CSS een grid-area naam. Die namen gebruiken we straks in
grid-template-areas.
.site-header { grid-area: header; }
.site-nav { grid-area: nav; }
.site-main { grid-area: main; min-width: 0; }
.site-aside { grid-area: aside; }
.site-footer { grid-area: footer; }
- De naam achter
grid-areakies je zelf. - Gebruik korte en duidelijke namen.
- Dezelfde namen moeten terugkomen in
grid-template-areas.
Actie — Controleer en rond af
- Controleer in dezelfde style.css dat de vijf hoofdclasses nog de namen header, nav, main, aside en footer als grid-area hebben.
- Vergelijk die namen met de bestaande template. Voeg geen tweede, tegenstrijdige set area-regels toe.
- Behoud de instellingen; dezelfde namen worden straks in de éénkolomsindeling gebruikt.
07 - Desktop layout met Grid
Dit is de brede Holy Grail-layout die je in H11 al hebt gemaakt. De header en footer lopen over drie kolommen. De middelste rij bestaat uit navigatie, hoofdinhoud en zijbalk.
body {
min-height: 100vh;
margin: 0;
padding: 24px;
display: grid;
grid-template-columns: 190px minmax(0, 1fr) 230px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 24px;
}
190pxis de linkerkolom voor de navigatie.minmax(0, 1fr)is de flexibele middenkolom voor de hoofdinhoud.frbetekent fractie van de beschikbare ruimte.230pxis de rechterkolom voor de zijbalk.auto 1fr automaakt drie rijen: boven, midden en onder.gapmaakt ruimte tussen de vakken.
Actie — Bouw verder
- Controleer je bestaande desktopregels met 190px, minmax(0,1fr) en 230px, drie rijen en de Holy Grail-template.
- Controleer min-width:0 op main en max-width:100% met height:auto op afbeeldingen.
- Leg een grens van 900px vast als startpunt voor je mobiele indeling. Controleer later of jouw inhoud iets eerder moet omschakelen; de inhoud bepaalt de bruikbare grens.
08 - De layout responsive maken
Op een smal scherm passen drie kolommen vaak niet goed. Daarom maken we met een media query één kolom. De onderdelen komen dan netjes onder elkaar.
@media (max-width: 900px) {
body {
padding: 16px;
gap: 16px;
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
.site-nav ul {
flex-direction: row;
flex-wrap: wrap;
}
.site-footer {
flex-direction: column;
align-items: flex-start;
}
}
- Er is nu maar één kolom:
1fr. - Elke rij heeft daarom ook maar één naam.
- De volgorde is duidelijk van boven naar beneden.
- De HTML hoeft hiervoor niet aangepast te worden.
Een gegevenstabel kan breder zijn dan een telefoon. Zet alleen die tabel in een technische wrapper binnen de bestaande projecttabel-section. De inhoud blijft intact; de wrapper mag horizontaal scrollen. Tabindex maakt hem met het toetsenbord bereikbaar.
<div class="tabel-wrapper" tabindex="0" role="region" aria-label="Projectoverzicht">
<!-- Hier blijft je bestaande volledige table met caption, thead en tbody staan. -->
</div>
.tabel-wrapper {
max-width: 100%;
overflow-x: auto;
}
table {
width: 100%;
min-width: 420px;
}
Actie — Bouw verder
- Voeg de media query uit dit item onderaan dezelfde style.css toe. Verander bij maximaal 900px kolommen naar één, reset de rijen en zet de vijf areas onder elkaar.
- Zet binnen dezelfde query .site-nav ul weer op flex-direction:row met flex-wrap:wrap, en .site-footer op column met align-items:flex-start.
- Controleer de projectkaarten en de bestaande tabel. Gebruik bij de tabel de horizontaal scrollbare tabel-wrapper uit het voorbeeld als de gegevens niet meer passen.
- Controleer breed én smal dat menu, footer, afbeeldingen en alle inhoud bereikbaar blijven. Behoud achtergrondafbeelding, cover en kleurvariabelen.
09 - Volledig voorbeeld
Hier zie je hoe de bestaande onderdelen samenkomen. Het HTML-voorbeeld is Home; Portfolio, Over en Contact houden dezelfde buitenstructuur en hebben elk hun eigen inhoud, title, description en huidige menulink. Gebruik je eigen teksten en bestanden; controleer afbeeldingsafmetingen tegen je eigen beelden.
De hoofdindeling is grid. De nav bevat een flexibele menulijst, de footer is zelf een flex-container en de projectkaarten op Portfolio gebruiken hun eigen flexbox. Alle vier de pagina’s verwijzen naar dezelfde externe style.css.
Home: index.html
<!doctype html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Ontdek de projecten van Sam de Vries, beginnend webmaker.">
<title>Home | Sam de Vries</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="site-header">
<p>Sam de Vries · Portfolio</p>
<h1>Ik maak ideeën zichtbaar.</h1>
</header>
<nav class="site-nav" aria-label="Hoofdnavigatie">
<ul>
<li><a href="index.html" class="huidig" aria-current="page">Home</a></li>
<li><a href="portfolio.html">Portfolio</a></li>
<li><a href="over.html">Over</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
<main class="site-main">
<div class="pagina-breedte">
<p class="intro">Ik ben Sam. Ik leer ontwerpen en websites bouwen met HTML en CSS.</p>
<p><a href="#projecten">Bekijk mijn uitgelichte werk</a></p>
<section id="projecten">
<h2>Uitgelicht werk</h2>
<article class="kaart uitgelicht">
<h3>Mijn eerste website</h3>
<a href="portfolio.html">
<img src="img/project-01.webp" alt="Bekijk het project Mijn eerste website" width="640" height="400">
</a>
<p>Een <strong>eigen portfolio</strong>, gemaakt door <em>stap voor stap</em> te leren.</p>
</article>
</section>
<section>
<h2>Over mij</h2>
<p>Ik ontdek graag hoe een idee een bruikbare website wordt.</p>
<a href="over.html">Lees meer over mij</a>
</section>
</div>
</main>
<aside class="site-aside">
<h2>Nu aan het leren</h2>
<p>Responsive websites die op elk scherm prettig werken.</p>
<a href="contact.html">Neem contact op</a>
</aside>
<footer class="site-footer">
<p>© Sam de Vries</p>
<p>Gemaakt met HTML en CSS</p>
<a href="mailto:sam@example.com">Stuur een e-mail</a>
</footer>
</body>
</html>
Gedeeld bestand: style.css
Vergelijk de regels per onderdeel met je eigen stylesheet en werk die bij; plak niet blind een tweede volledige set eronder. De variabelen, inhoud, afbeeldingen en kaartclasses uit eerdere hoofdstukken blijven behouden.
:root {
--kleur-tekst: #17233b;
--kleur-achtergrond: #e7eef6;
--kleur-vlak: #ffffff;
--kleur-accent: #2458d3;
--kleur-accent-donker: #183b91;
--kleur-rand: #d3ddec;
}
* {
box-sizing: border-box;
}
/* Basis en hoofdindeling */
body {
min-height: 100vh;
margin: 0;
padding: 24px;
font-family: system-ui, sans-serif;
line-height: 1.6;
color: var(--kleur-tekst);
background-color: var(--kleur-achtergrond);
background-image: url("img/achtergrond.webp");
background-size: cover;
background-position: center;
display: grid;
grid-template-columns: 190px minmax(0, 1fr) 230px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 24px;
}
.site-header { grid-area: header; }
.site-nav { grid-area: nav; }
.site-main { grid-area: main; min-width: 0; }
.site-aside { grid-area: aside; }
.site-footer { grid-area: footer; }
.site-header,
.site-nav,
.site-main,
.site-aside,
.site-footer {
padding: 24px;
border: 1px solid var(--kleur-rand);
border-radius: 16px;
background-color: var(--kleur-vlak);
/* Optionele afwerking: een zachte, donkere schaduw. */
box-shadow: 0 8px 28px rgb(23 35 59 / 8%);
}
.pagina-breedte {
width: 100%;
max-width: 1000px;
margin: 0 auto;
}
/* Tekst, beelden en links */
h1, h2, h3, p {
margin-top: 0;
margin-bottom: 16px;
}
h1 {
font-size: 40px;
line-height: 1.2;
}
.intro {
font-size: 20px;
}
section {
margin-bottom: 24px;
}
img {
display: block;
max-width: 100%;
height: auto;
border-radius: 12px;
}
a {
color: var(--kleur-accent);
}
a:hover {
color: var(--kleur-accent-donker);
}
a:focus-visible,
.tabel-wrapper:focus-visible {
outline: 3px solid var(--kleur-accent);
outline-offset: 4px;
}
/* Flexbox binnen de navigatie */
.site-nav ul {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: stretch;
gap: 16px;
list-style: none;
padding: 0;
margin: 0;
}
.site-nav a {
display: block;
padding: 10px;
border: 2px solid transparent;
border-radius: 10px;
color: var(--kleur-tekst);
text-decoration: none;
}
.site-nav a:hover,
.site-nav .huidig {
border-color: var(--kleur-accent);
color: var(--kleur-accent-donker);
font-weight: bold;
text-decoration: underline;
}
/* De bestaande projectkaarten op Portfolio */
.kaarten {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: stretch;
gap: 24px;
}
.kaart {
flex: 1 1 220px;
min-width: 0;
padding: 20px 24px;
border: 1px solid var(--kleur-rand);
border-radius: 16px;
background-color: var(--kleur-vlak);
}
.uitgelicht {
border-color: var(--kleur-accent);
}
/* Tabel op Portfolio */
.tabel-wrapper {
max-width: 100%;
overflow-x: auto;
}
table {
width: 100%;
min-width: 420px;
border-collapse: collapse;
}
th, td {
padding: 12px;
border: 1px solid var(--kleur-rand);
text-align: left;
}
th {
background-color: var(--kleur-achtergrond);
}
/* Flexbox binnen de footer */
.site-footer {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: 16px;
}
.site-footer p {
margin: 0;
}
/* Aanpassingen voor smalle schermen */
@media (max-width: 900px) {
body {
padding: 16px;
gap: 16px;
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
.site-nav ul {
flex-direction: row;
flex-wrap: wrap;
}
.site-footer {
flex-direction: column;
align-items: flex-start;
}
}
De afronding van hoeken ken je uit H6. Box-shadow is optioneel: de waarden betekenen horizontale verplaatsing, verticale verplaatsing, vervaging en schaduwkleur. Focus-visible tekent een duidelijke focusrand voor toetsenbordbediening; outline neemt geen plaats in de layout in. Je mag je eigen kleurkeuze behouden, zolang links en tekst goed leesbaar blijven.
Actie — Controleer en rond af
- Vergelijk het volledige voorbeeld met je eigen site. Neem alleen ontbrekende regels over en behoud je vier pagina's, eigen projecten, teksten en beelden.
- Controleer dezelfde variabelen, wrapper, actieve menuclasses, flexbox, grid en media query. Houd alle blijvende opmaak in de bestaande externe style.css.
- Optionele afwerking: pas de uitgelegde ronde hoeken en rustige schaduw uit het voorbeeld toe; behoud voldoende contrast en dezelfde afstanden op alle pagina's.
10 - Best practices
- Begin met een duidelijke HTML-structuur.
- Gebruik
grid-template-areasom de layout leesbaar te houden. - Gebruik duidelijke grid-area namen.
- Test je layout op een breed scherm en een smal scherm.
- Gebruik de browser-inspector om de grid-overlay te bekijken.
- Gebruik media queries om de layout eenvoudiger te maken op kleine schermen.
- Verander alleen wat nodig is in de media query.
Actie — Controleer en rond af
- Test alle vier de pagina's op ongeveer 360px, 768px en 1280px en net boven/onder je gekozen omschakelgrens.
- Controleer ook met toetsenbord: tab door links, zie waar de focus staat en open een link met Enter. De stijl voor focus-visible staat in het voorbeeld.
- Controleer dat niet de hele pagina horizontaal schuift; een brede tabel mag binnen haar eigen wrapper scrollen.
- Controleer de fallback met tijdelijk een verkeerd achtergrondpad en herstel dat direct. Controleer daarna op een telefoon of met mobiele browserweergave.
11 - Eindopdracht: rond je portfoliosite af
Je eindproduct is de site die je sinds H1 hebt opgebouwd. Je hoeft hem niet opnieuw te maken. Gebruik de actie hieronder als oplevercheck en vul alleen aan wat nog ontbreekt.
- Home: een persoonlijke introductie, uitgelicht project en duidelijke vervolglinks.
- Portfolio: drie eigen projectkaarten met tekst en beeld en de compacte projecttabel.
- Over: eigen achtergrond, vaardigheden en werkwijze.
- Contact: een duidelijke contactmogelijkheid met werkende e-maillink.
Een moderne uitstraling komt hier uit een samenhangend kleurenpalet, rustige typografie, voldoende ruimte, herkenbare navigatie en verzorgde inhoud. Je hoeft geen extra effecten toe te voegen om aan de opdracht te voldoen.
Actie — Controleer en rond af
- Rond dezelfde portfoliosite af; maak geen nieuwe HTML-pagina of stylesheet. Home, Portfolio, Over en Contact hebben eigen inhoud en werkende onderlinge links.
- Controleer overal één externe style.css, kleurvariabelen, een achtergrondafbeelding met cover en leesbare inhoudsvlakken.
- Controleer de Holy Grail-grid op desktop en één kolom op smal. Flexbox werkt binnen de nav en de footer; de drie bestaande projectkaarten blijven behouden.
- Controleer de juiste huidige menulink, alt-teksten, toetsenbordfocus, lijsten, projecttabel en contactlink. Verwijder niet gekozen proefonderdelen, inline CSS, style-blokken en !important.
- Valideer de HTML van alle vier de pagina's en de gedeelde CSS. Herstel fouten en doe daarna nog één ronde door de bestaande site op breed en smal scherm.
Quiz
-
Vraag 1. Waarvoor gebruik je een media query?
Goed. Een media query maakt CSS voorwaardelijk.Niet goed. Media queries gebruik je om CSS bij bepaalde schermgroottes toe te passen. -
Vraag 2. Wat betekent
max-width: 700px?
Goed.max-widthgeldt tot die maximale breedte.Niet goed.max-width: 700pxgeldt voor schermen tot en met 700 pixels breed. -
Vraag 3. Welke layout bouwen we in dit hoofdstuk?
Goed. De Holy Grail layout is de klassieke layout met header, nav, main, aside en footer.Niet goed. In dit hoofdstuk maken we een Holy Grail layout. -
Vraag 4. Welke CSS-property gebruik je om named areas te tekenen?
Goed. Daarmee teken je de grid-gebieden als tekst.Niet goed. Named areas teken je metgrid-template-areas. -
Vraag 5. Wat gebeurt er in de mobiele media query van dit hoofdstuk?
Goed. Op kleine schermen zetten we de onderdelen onder elkaar.Niet goed. De media query maakt de layout eenvoudiger: één kolom. -
Vraag 6. Moet de HTML veranderen voor de mobiele layout?
Goed. Responsive layout regel je meestal in CSS.Niet goed. De HTML kan hetzelfde blijven; de CSS past de layout aan. -
Vraag 7. Welke kolom is flexibel in
220px 1fr 260px?
Goed.1frgebruikt de beschikbare ruimte.Niet goed.1fris de flexibele kolom. -
Vraag 8. Waar hoort de belangrijkste inhoud van een pagina meestal in?
Goed. De belangrijkste inhoud staat in<main>.Niet goed. Gebruik<main>voor de hoofdinhoud. -
Vraag 9. Waarvoor gebruik je de grid-overlay in de browser?
Goed. De grid-overlay helpt bij controleren en begrijpen.Niet goed. De grid-overlay laat de grid-indeling zichtbaar zien. -
Vraag 10. Wat is een goede regel voor responsive layout?
Goed. Op kleine schermen is eenvoud meestal beter.Niet goed. Kleine schermen vragen meestal om een eenvoudigere layout.