
In HTML-documenten kun je delen van een pagina tonen, verbergen of herschikken op basis van de eigenschappen van de viewport. Is het browservenster 480 pixels breed, dan verander je je navigatie bijvoorbeeld van een horizontale lijst in een verticale, inklapbare lijst. Met SVG en media queries kun je iets vergelijkbaars doen.
Dit artikel is een fragment uit CSS Master, 3rd Edition van Tiffany. Neem het door als je andere geavanceerde CSS3-features zoals Flexbox en Grid onder de knie wilt krijgen.
Behalve met HTML kun je CSS ook met SVG gebruiken, oftewel Scalable Vector Graphics. SVG is een opmaakformaat om platte, tweedimensionale afbeeldingen te beschrijven. Omdat het een opmaaktaal is, heeft het een document object model en kun je het met CSS aansturen.
Met CSS pas je het uiterlijk van een SVG aan op interactie van de gebruiker. Je kunt hetzelfde SVG-document ook op meerdere plekken gebruiken en er delen van tonen of verbergen, afhankelijk van de breedte van de viewport.
Alle grote browserengines ondersteunen SVG 1.1 al jaren. De ondersteuning voor de features van SVG 2 is daarentegen nog volop in ontwikkeling. Op het moment van schrijven is de browserondersteuning voor een deel van de onderwerpen hier beperkt, en dat kan intussen veranderd zijn. Houd het Chromium-meta-issue Implement SVG2 features in de gaten om het werk in Chromium-browsers te volgen. Voor Firefox volg je het meta-issue Support SVG 2 features, en voor Safari het WebKit-meta-issue Implement SVG 2. Door issuetrackers bladeren is geen pretje, maar voorlopig is het de beste manier om de stand van SVG 2 te volgen.
Voordat we verdergaan: wat is SVG precies, en waarom zou je het gebruiken?
Vectorafbeeldingen en rasterafbeeldingen
De meeste afbeeldingen op het web zijn rasterafbeeldingen, ook wel bitmaps genoemd. Rasterafbeeldingen bestaan uit pixels op een vast raster, met een vastgelegd aantal pixels per inch. JPEG, WebP, GIF en PNG zijn allemaal voorbeelden van rasterafbeeldingen.
Rasterafbeeldingen zijn resolutieafhankelijk. Een PNG van 144 PPI (pixels per inch) ziet er prima uit op een scherm van 144 PPI. Op een scherm met een hogere resolutie (400 PPI) kan diezelfde afbeelding wazig ogen. Rasterafbeeldingen hebben bovendien vaste afmetingen en zien er op hun oorspronkelijke formaat het best uit. Een afbeelding van 150 bij 150 pixels opschalen naar 300 bij 300 pixels vervormt hem.
Vectorformaten werken niet met pixels op een raster, maar beschrijven de primitieve vormen, cirkels, rechthoeken, lijnen of paden, waaruit een afbeelding bestaat, plus hun plek in het coördinatenstelsel van het document. Vectorafbeeldingen zijn daardoor resolutieonafhankelijk en houden hun kwaliteit, ongeacht de resolutie of de afmetingen van het scherm.
Die resolutieonafhankelijkheid is het grootste voordeel van SVG. Je schaalt afbeeldingen op en neer zonder kwaliteitsverlies, en dezelfde afbeelding ziet er goed uit op apparaten met een hoge en met een lage PPI. SVG is wel slecht geschikt voor de hoeveelheid kleurinformatie die een foto nodig heeft. Voor tekeningen en vormen is het veel beter op zijn plek. Gebruik het in plaats van PNG en GIF, en als flexibeler vervanger van iconfonts.
Een ander voordeel is dat SVG ontworpen is om samen te werken met de andere webtalen. Je maakt, bewerkt en manipuleert SVG-afbeeldingen met JavaScript. Of je stylet en animeert ze met CSS, zoals we hierna zien.
CSS koppelen aan SVG-documenten
CSS gebruiken met SVG werkt vrijwel hetzelfde als CSS gebruiken met HTML. Je past CSS toe via het style-attribuut van een SVG-element, je groepeert de CSS van een document in een <style>-element, of je linkt naar een externe stylesheet. De voor- en nadelen van elke methode zijn dezelfde als bij HTML.
Het style-attribuut gebruiken
Hier een eenvoudig SVG-document waarvan de code een zwarte cirkel tekent:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"
➥enable-background="new 0 0 200 200">
<circle cx="101.3" cy="96.8" r="79.6" />
</svg>
De afbeelding hieronder laat zien hoe die code in een browser wordt weergegeven.

Geven we onze cirkel een roze vulling met CSS, via het style-attribuut:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"
➥enable-background="new 0 0 200 200">
<circle cx="101.3" cy="96.8" r="79.6" style="fill: #f9f" />
</svg>
Het resultaat zie je hieronder.

Hier zit meteen een verschil tussen CSS met HTML en CSS met SVG: de namen van de properties. Veel CSS-properties die je in HTML-documenten gebruikt werken niet met SVG, en andersom. Verderop in dit hoofdstuk komen we daarop terug.
Het style-attribuut is natuurlijk niet de beste manier om met CSS te werken. Het beperkt hoe ver je die stijlen over meerdere elementen of documenten kunt hergebruiken. Ingesloten of gelinkte CSS is een betere optie.
CSS insluiten in SVG-documenten
In plaats van het style-attribuut kun je het <style>-element gebruiken:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0
➥ 200 200" enable-background="new 0 0 200 200">
<style type="text/css">
circle {
fill: #0c0;
}
</style>
<circle cx="101.3" cy="96.8" r="79.6" />
</svg>
CSS insluiten in een SVG-document laat je die stijlen hergebruiken voor meerdere elementen in hetzelfde document, maar je kunt de CSS niet delen tussen documenten. Voor logo’s en iconen is dat prima. Bouw je zoiets als een bibliotheek met grafiekstijlen, dan is een extern CSS-bestand de betere keuze.
Met een gewone teksteditor voeg je ook CSS toe aan SVG-afbeeldingen die met software als Sketch, Inkscape of Illustrator zijn gemaakt. Dat verandert niets aan de mogelijkheid om de afbeelding in het tekenprogramma te blijven bewerken, maar bewerk je het bestand met een beeldbewerker, dan kan die je CSS herschrijven of weggooien.
Een SVG-document aan een extern CSS-bestand koppelen
Net als bij HTML kun je met een extern CSS-bestand stijlen delen tussen meerdere SVG-documenten. Zet <? xml-stylesheet ?> bovenaan je SVG-bestand om zo’n bestand te koppelen:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://www.gekkode.com/nl/style.css" type="text/css"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0
➥ 200 200" enable-background="new 0 0 200 200">
<circle cx="101.3" cy="96.8" r="79.6" />
</svg>
Het <link>-element gebruiken
Je kunt ook het HTML-element <link> gebruiken. Bij deze methode moet je het attribuut xmlns meegeven, zoals hieronder:
<link href="style.css" type="text/css" rel="stylesheet"
➥ xmlns="http://www.w3.org/1999/xhtml" />
Let op: sommige oudere browsers verwachten dat het <link>-element in <defs>– of <g>-tags staat.
<link> is geen SVG-element. Het hoort bij HTML en XHTML. XHTML is een variant van HTML die volgens de regels van XML-opmaak wordt geparsed. Onder die regels mag je elementen en hun gedrag lenen uit andere XML-dialecten, zoals XHTML. Daarvoor moet je de browser wel met het attribuut xmlns vertellen bij welke namespace het element hoort.
@import gebruiken
Je kunt ook naar een externe stylesheet linken met @import, tussen de tags <style> en </style>:
<style type="text/css">
@import("https://www.gekkode.com/style.css");
</style>
Dat werkt vrijwel hetzelfde als de methode met <link>.
SVG en het <img>-element: de grenzen
Een SVG-bestand koppelen aan externe resources, CSS-bestanden inbegrepen, werkt niet met het <img>-element. Dat is een beveiligingsbeperking die in browsers is ingebouwd.
Wil je gelinkte CSS bij je SVG-afbeeldingen gebruiken, dan heb je twee mogelijkheden:
- gebruik een
<style>-element in je SVG-document en zet je CSS inline, - gebruik een
<iframe>– of een<object>-element (zie de opmerking hieronder).
Kies in het algemeen <iframe> boven <object>. Het <object>-element mag wel het kind zijn van een <a>-element, en <iframe> niet. Met <iframe> of <object> komt de documentboom van de SVG bovendien beschikbaar voor de documentboom van de pagina. Je kunt er dus met JavaScript mee werken, bijvoorbeeld via document.querySelector('iframe').contentDocument.
Inline SVG en externe assets
Voeg je SVG toe aan HTML, dan laadt de browser de externe assets waarnaar het SVG-document verwijst niet. Wel kun je vanuit de <head> van je HTML-document naar de CSS voor je SVG linken:
<head>
⋮
<link href="svg.css" type="text/css" rel="stylesheet" />
</head>
SVG-elementen in HTML-documenten maken ook deel uit van de HTML-documentboom. Bij inline SVG is het prima om de stijlregels voor HTML en SVG in één stylesheet te combineren.
Verschillen tussen SVG en HTML
SVG en HTML zijn allebei opmaaktalen, maar twee belangrijke verschillen bepalen hoe ze met CSS omgaan:
- SVG volgt het CSS-boxmodel niet.
- SVG kent geen positioneringsschema.
SVG volgt het CSS-boxmodel niet
Bij HTML volgt de CSS-layout de regels van het CSS-boxmodel. SVG gebruikt daarentegen coördinaten voor de layout. Je kunt dat het best opvatten als een ‘vormmodel’.
SVG-vormen zijn niet beperkt tot rechthoekige boxen. Daardoor gelden de meeste properties uit het boxmodel niet voor SVG-elementen. Je kunt bijvoorbeeld de padding of de margin van een SVG-element niet aanpassen. De properties box-sizing, box-shadow, outline en border-* werken evenmin. Grid layout, floats en Flexbox doen het ook niet.
Wel kun je met CSS een reeks SVG-properties en attribuutwaarden instellen of wijzigen. De volledige lijst staat in de specificatie van SVG 2, al is de ondersteuning in de meeste engines onvolledig. Sommige CSS-properties, zoals filter, werken met zowel SVG als HTML. Een paar daarvan komen verderop aan bod, als onderdeel van concrete technieken.
SVG kent geen positioneringsschema
Wordt CSS met HTML gebruikt, dan kunnen de boxen van elementen:
- in de normale flow staan,
- met de property
floatuit de normale flow worden gehaald, - met de property
positionuit de normale flow worden gehaald.
De CSS-specificatie noemt dat positioneringsschema’s. In SVG bestaan ze niet: de property position heeft geen effect op SVG-elementen. Properties als top, left en bottom, die van positionering afhangen, evenmin. Elementen laten zweven in een SVG-document kan ook niet.
SVG plaatst elementen met een coördinatenstelsel. Voor een <circle> stel je bijvoorbeeld de coördinaten van het middelpunt in met de attributen cx en cy, en de lengte van de straal met het attribuut r. Een polygoon is een reeks puntcoördinaten met lijnstukken ertussen. Je bepaalt dus waar een element op het SVG-canvas getekend wordt, maar je kunt het niet ‘positioneren’ in de CSS-betekenis van het woord.
In het verlengde daarvan kent SVG geen z-index en geen stapelcontexten.
Let op: de specificatie van SVG 2 beschrijft wel gedrag voor z-index en stapelcontexten in SVG-documenten, maar de meeste browsers ondersteunen dat nog niet.
SVG-elementen worden gestapeld op volgorde van de broncode: wat later in het document staat, ligt hoger op de stapel. Wil je die stapelvolgorde veranderen, dan verplaats je de elementen in de bron of herschik je ze met JavaScript in de DOM-boom.
In de praktijk gelden de meeste CSS 2.1-properties niet voor SVG-documenten. De uitzonderingen zijn animaties en transforms, display, overflow, visibility, filter en een handvol properties voor lettertype en tekst. In plaats daarvan gebruik je de SVG-specifieke stijlproperties voor SVG-documenten. De meeste daarvan kun je ook als attribuut op SVG-elementen schrijven.
SVG-elementen stylen
Hier een eenvoudig voorbeeld van SVG-elementen stylen met CSS. We beginnen met ons SVG-document, een losstaand bestand:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://www.gekkode.com/nl/styles.css" type="text/css" ?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink=
➥"http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 497
➥ 184" enable-background="new 0 0 497 184" xml:space="preserve">
<polygon id="star" points="77,23.7 98.2,66.6 145.5,66.5 111.2,
➥106.9,119.3,154 77,131.8 34.7,154 42.8,106.9 8.5,67.5 55.8,
➥66.6 "/>
<circle id="circle" cx="245" cy="88.9" r="67.5"/>
</svg>
Deze opmaak levert de afbeelding hieronder op.

De meeste CSS-properties werken niet met SVG-documenten, maar de kleur van een element aanpassen kan wel. We maken onze ster geel:
#star {
fill: hsl( 44, 100%, 50% );
}
Je ziet fill vaak op SVG-tags staan, bijvoorbeeld <circle fill="rgb( 255, 185, 0 )" cx="3" cy="10" r="100">, maar het is ook een property die je in CSS kunt gebruiken.
Met CSS pas je ook de stroke van een element aan, de omtrek van een SVG-vorm. Die omtrek bestaat ook als er geen stroke is ingesteld. We geven onze cirkel een streepjesrand van tien pixels breed in donkerblauw, en zetten zijn fill op cornflowerblue:
circle {
fill: cornflowerblue;
stroke: darkblue;
stroke-width: 10;
stroke-dasharray: 10, 15;
stroke-linecap: round;
}
Alles bij elkaar levert dat het resultaat hieronder op.

SVG-attributen als CSS-properties gebruiken
Met CSS kun je ook de coördinaatwaarden van een aantal vormelementen instellen: <rect>, <circle> en <ellipse>. Normaal gesproken gebruik je daarvoor SVG-attributen:
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="200" width="300" height="300" fill="#f60" />
</svg>
SVG 2 heeft een aantal van die attributen echter opnieuw gedefinieerd als geometry properties. Je kunt hun waarden dus in CSS zetten:
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<style type="text/css">
rect {
x: 20px;
y: 50px;
width: 300px;
height: 300px;
fill: #f60;
}
</style>
<rect />
</svg>
Coördinaatproperties (x en y), de properties voor het middelpunt (cx en cy) en de straalproperties (rx, ry en r) kun je allemaal in CSS zetten, net als width en height. Bij SVG-attributen zijn eenheden optioneel, CSS-waarden vereisen ze juist. Lengtes en percentages zijn allebei geldig voor de genoemde properties, maar let op: lengtes werken in SVG-documenten net iets anders. Onthoud dat de S in SVG voor scalable staat. De berekende grootte van een SVG-element hangt ook af van:
- de berekende
widthenheightvan het root-SVG-element - de waarde van het attribuut
viewBoxop het root-element - elke schaaltransformatie op het element of op zijn voorouders.
Met andere woorden: de hoeken van ons <rect>-element liggen op (20, 50), (20, 320), (350, 320) en (20, 350) in het SVG-coördinatenstelsel. De werkelijke afmetingen kunnen groter of kleiner uitvallen, afhankelijk van de factoren hierboven.
Niet elk SVG-attribuut is via CSS beschikbaar, in elk geval niet in elke browser. Chrome en Edge ondersteunen bijvoorbeeld de CSS-functie path() om padgegevens in te stellen, via de property d:
path {
d: path("M 454.45223,559.21474 -304.96705,163.45948 417.4767,-296.33928 Z");
}
Voorlopig zijn zij de enige browsers die dat doen. Aan ondersteuning in Firefox en WebKit wordt nog niet gewerkt.
Voor de overige vormelementen is de specificatie van SVG 2 ronduit inconsistent. Op dit moment moet je element-attributen gebruiken om de properties van de elementen <line>, <polyline> en <polygon> in te stellen.
Je bent daarbij niet beperkt tot type- of elementselectors. Je kunt bijvoorbeeld kleine, middelgrote en grote cirkels met classselectors definiëren:
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<style type="text/css">
.small {
cx: 20px;
cy: 20px;
r: 20px;
fill: #0c0;
}
.medium {
cx: 80px;
cy: 80px;
r: 60px;
fill: #fc0;
}
.large {
cx: 220px;
cy: 220px;
r: 120px;
fill: #00f;
}
</style>
<circle class="small" />
<circle class="medium" />
<circle class="large" />
</svg>
Welke selector je ook kiest, door deze properties in CSS-syntaxis te schrijven worden ze meteen makkelijk te animeren. Hoe dat gaat, zie je in het volgende deel.
SVG-properties animeren en laten overgaan
CSS met SVG wordt interessanter zodra je transities en animaties toevoegt. Dat gaat net als het animeren van HTML-elementen met CSS, maar dan met SVG-specifieke properties. We bouwen een fonkelende ster met het SVG-document hieronder:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px"
➥ y="0px" viewBox="0 0 497 184" xml:space="preserve">
<defs>
<link href="twinkle.css" type="text/css" rel="stylesheet"
➥ xmlns="http://www.w3.org/1999/xhtml"/>
</defs>
<polygon class="star" points="77,23.7 98.2,66.6 145.5,66.5 111.2
➥,106.9 119.3,154 77,131.8 34.7,154 42.8,106.9 8.5,67.5
➥ 55.8,66.6 "/>
<polygon class="star twinkle" points="77,23.7 98.2,66.6 145.5,
➥66.5 111.2,106.9 119.3,154 77,131.8 34.7,154 42.8,106.9
➥ 8.5,67.5 55.8,66.6 "/>
</svg>
Ons document bevat twee stervormige polygoonelementen, allebei met de classnaam star. Voor het fonkeleffect animeren we het eerste. Dit is onze CSS:
@keyframes twinkle {
from {
fill-opacity: .4;
}
to {
fill-opacity: 0;
transform: scale( 2 );
}
}
.star {
fill: rgb( 255,195,0 );
transform-origin: 50% 50%;
}
.twinkle {
animation: twinkle 1.5s infinite forwards ease-in;
}
Hier gebruiken we de SVG-specifieke property fill-opacity. Net als in CSS in het algemeen geldt: kun je de waarde van een SVG-stijlproperty interpoleren, dan kun je hem animeren of laten overgaan. In de afbeelding hieronder zie je twee momenten uit de animatie.

Nog een voorbeeld. Deze keer maken we een tekeneffect door de property stroke-dasharray te laten overgaan. Dit is ons SVG-document:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
➥xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" enable-background="new 0 0 200 200">
<circle fill="transparent" stroke-width="16" cx="101.3"
➥ cy="96.8" r="79.6"/>
</svg>
stroke-dasharray accepteert een door komma’s gescheiden lijst met lengtes of percentages die samen een streepjespatroon vormen. Oneven waarden bepalen de lengte van het streepje, even waarden de lengte van de tussenruimte. Een stroke-dasharray van 5, 10 betekent dat de lijn 5px lang is met 10px ruimte tussen elk streepje. Een waarde van 5, 5, 10 wisselt streepjes van 5px en 10px af, met steeds 5px ruimte ertussen.
Met stroke-dasharray maak je een tekeneffect door te beginnen met een streepjeslengte van nul en een grote tussenruimte, en te eindigen met een lang streepje en helemaal geen ruimte. Daartussen laat je de overgang lopen. Zo ziet onze CSS eruit:
circle {
transition: stroke-dasharray 1s ease-in;
fill: transparent;
stroke-dasharray: 0, 500;
}
.animate {
stroke-dasharray: 500, 0;
}
Aan het begin van de transitie is onze lijn onzichtbaar, want de streepjeslengte is 0 en de tussenruimte 500. Zodra we de class animate aan onze cirkel toevoegen, gaat de streepjeslengte naar 500 en verdwijnt de ruimte. Het effect lijkt op een cirkel tekenen met een passer. Waarom 500? Dat is de kleinste waarde die precies dit effect opleverde.
Een toekomst met geanimeerde paden
Weet je ons voorbeeld nog waarin we een pad via CSS instelden? Ooit kunnen we paden misschien in elke browser met CSS animeren:
path {
d: path("M357.5 451L506.889 192.25H208.111L357.5 451Z");
transition: d 1s ease-in-out;
}
.straighten {
d: path("M357.5 8871L406 -10113.75H208.111L357.5 351Z");
}
Voorlopig ondersteunen alleen Chromium-browsers als Google Chrome en Microsoft Edge het animeren van paddefinities op deze manier. Gebruik in andere browsers een JavaScript-library als GreenSock met de MorphSVGPlugin. Los van de browsercompatibiliteit maken GreenSock en de MorphSVGPlugin het eenvoudig om twee vormen in elkaar te laten overlopen, hoeveel punten ze elk ook hebben.
SVG gebruiken met media queries
In HTML-documenten kun je delen van een pagina tonen, verbergen of herschikken op basis van de eigenschappen van de viewport. Is het browservenster 480 pixels breed, dan verander je je navigatie bijvoorbeeld van een horizontale lijst in een verticale, inklapbare lijst. Met media queries en SVG-documenten kun je iets vergelijkbaars doen. Neem een logo, zoals dat van het fictieve bedrijf Hexagon Web Design & Development hieronder.

Zonder media queries zou dit SVG-logo simpelweg uitrekken of krimpen om in de viewport of in zijn container te passen. Met media queries kan het slimmer.
Laten we onderscheid maken tussen de viewport van het HTML-document en die van het SVG-document. Staat de SVG inline, dan zijn beide viewports één en dezelfde: het SVG-document gedraagt zich als elk ander HTML-element. Is het SVG-document gelinkt, zoals bij de elementen <iframe>, <object> of <img>, dan heb je met de viewport van het SVG-document te maken.
Media queries werken in beide gevallen, maar bij een gelinkt SVG-document staat de viewport los van het HTML-document. De grootte van het browservenster bepaalt dan niet de grootte van de SVG-viewport: die komt uit de afmetingen van het <object>-, <iframe>– of <img>-element. Neem het volgende, ingekorte SVG-document:
<svg version="1.1" id="HexagonLogo" xmlns="http://www.w3.org/2000/
➥svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
➥ viewBox="0 0 555 174" xml:space="preserve">
<defs>
<style type="text/css">
/* CSS goes here */
</style>
</defs>
<g id="hex">
<polygon id="hexagonbg" points="55.2,162 10,86.5 55.2,11
➥ 145.5,11 190.7,86.5 145.5,162 "/>
<path id="letterH" fill="#FFFFFF" d="M58,35.5h33v35.2h18.
➥4V35.5 h33.2v103.4h-33.2v-38.3H91v38.3H58V35.5z M77.5,126.5V87.
➥3h45.6v39.2h4V47.9h-4v35.6H77.5V47.9h-4v78.6H77.5z"/>
</g>
<g id="word-mark">
<g id="hexagon-word">
...
</g>
<g id="web-design-and-dev">
...
</g>
</g>
</svg>
Let op: een volledige demo van deze techniek, inclusief de complete broncode van dit SVG-document, staat online.
Op kleinere viewports tonen we alleen de H in het zeshoekige symbool:
@media (max-width: 320px) {
[id=word-mark] {
display: none;
}
}
Vanaf nu is alleen het symbooldeel van ons logo zichtbaar zodra de container van de SVG 20em of smaller is.

Stel de breedte van de SVG-container in om deze weergave vanuit het HTML-document te activeren:
<iframe src="hexlogo.svg" style="width: 320px; border:0"></iframe>
Zoals je in de afbeelding hierboven misschien al zag, houdt onze SVG-afbeelding haar intrinsieke afmetingen, ook al is een deel ervan verborgen. Dat is helaas een beperking van SVG. Om die te omzeilen moet je de viewBox van het SVG-document aanpassen, maar alleen als de viewport onder een bepaalde grootte komt. Een uitgelezen use case voor matchMedia.
De viewBox bepaalt, zoals de naam al zegt, het zichtbare gebied van een SVG-element. Door hem aan te passen beslis je welk deel van een SVG-afbeelding de viewport vult. Hier een voorbeeld met matchMedia en een media query die het attribuut viewBox bijwerkt:
<script type="text/javascript">
const svg = document.querySelector( 'svg' );
/* De oorspronkelijke waarde in een variabele opslaan */
const originalViewBox = svg.getAttribute( 'viewBox' );
/* Onze media query en het media query-object definiëren */
const mq = matchMedia( '( max-width: 320px )' );
/* De handler definiëren */
const updateViewBox = () {
if (mq.matches) {
/* De afmetingen van de viewBox aanpassen om de zeshoek te tonen */
svg.setAttribute( 'viewBox', '0 0 200 174' );
} else {
svg.setAttribute( 'viewBox', originalViewBox );
}
}
svg.addEventListener( 'SVGLoad', updateViewBox );
/* Wordt afgevuurd als de mediaconditie verandert */
mq.addEventListener( 'change', updateViewBox );
</script>
Is de SVG-container 320 pixels breed of smaller, dan is de waarde van het attribuut viewBox voortaan "0 0 200 174". Boven 320 pixels krijgt viewBox zijn oorspronkelijke waarde terug.

Omdat deze techniek op het attribuut onload of op het event SVGLoad leunt, kun je je CSS en JavaScript het best in het SVG-bestand zelf zetten. Is de CSS extern, dan kan SVGLoad afgaan voordat de bijbehorende stylesheet klaar is met laden.
Media queries gebruiken met background-size
SVG-documenten en media queries zijn niet beperkt tot afbeeldingen op de voorgrond. Je kunt de SVG-viewport ook met de CSS-property background-size van formaat veranderen.
We beginnen met dit SVG-document:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
➥ xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
➥ viewBox="-20 -20 250 250" xml:space="preserve">
<style type="text/css">
circle {
stroke: #000;
stroke-width: 30;
fill: #009688;
}
@media ( width: 100px ) {
circle {
fill: #673ab7;
}
}
@media ( width: 300px ) {
circle {
fill: #ffc107;
}
}
</style>
</defs>
<circle cx="100" cy="100" r="100" />
<circle cx="100" cy="100" r="50" />
</svg>
Een eenvoudig geval. Onze <circle>-elementen krijgen bij bepaalde viewportbreedtes een andere fill. Standaard is de fill teal, bij 100 pixels breed wordt hij paars, en bij 300 pixels geel.
Daarvoor moet je de SVG-afbeelding als achtergrondafbeelding gebruiken en de background-size van de selector instellen. Hier gebruiken we onze afbeelding als achtergrond voor de <body> en voor de <li>-elementen:
body, li {
background: url(circles.svg);
}
body {
background-color: #9c27b0;
background-size: 300px auto;
}
li {
background-position: left center;
background-repeat: no-repeat;
background-size: 1em auto;
padding-left: 40px;
font-size: 24px;
margin: 1rem 0;
}
Het resultaat zie je hieronder.

Conclusie
SVG met CSS gebruiken geeft je meer ruimte voor flexibele, responsive documenten. Je weet nu hoe je:
- SVG-elementen stylet met CSS
- SVG-properties animeert
- met CSS-media queries en de
matchMedia-API delen van een SVG-document toont en verbergt.


