Let's talk!

Bekijk project Lees Insight
5 mei 2021 Development

CSS eenheden: px, em en rem. Gebruik niet alleen maar px!

In CSS kan je kiezen uit een flinke lijst met eenheden die je kunt gebruiken om het formaat van iets te bepalen. De meest bekende en meest gebruikte eenheid is pixels (px) en deze kan je bijvoorbeeld gebruiken voor CSS eigenschappen zoals width, height, font-size, line-height, margin en padding. Naast px zijn er nog veel meer eenheden, zoals: cm, mm, pt, em, rem, vh en wh. Wist je dat het in veel gevallen beter is om een andere eenheid te gebruiken dan px? Laten we eerst wat dieper in de verschillende eenheden duiken!

Absolute en relatieve eenheden

CSS eenheden kan je onderverdelen in 2 groepen, eenheden met een vast (absoluut) formaat en eenheden met een relatief formaat. Voorbeelden van eenheden met een vast formaat zijn: cm (centimeter), in (inch) en px (pixel). De grootte van deze eenheden zijn namelijk altijd hetzelfde. Zo is 1cm altijd 1 centimeter groot en is 1in altijd 1 inch groot. En per definitie is 1px gelijk aan 1 pixel van het beeldscherm (al bepaald de pixeldichtheid van jouw scherm ook hoe groot 1 pixel in werkelijkheid is). Maar laten we voor het gemak zeggen dat 1px altijd gelijk is aan 1 stip/pixel is van het beeldscherm.

Naast absolute eenheden zijn er ook relatieve eenheden. Dat zijn eenheden waarvan het formaat gebaseerd wordt op een ander formaat. Voorbeelden van relatieve eenheden zijn em, rem, vw en vh. Zo is 1rem even groot als de font-size van het root element van jouw website. Het root element van een website is de <html> tag. Is er op de <html> tag een font-size van 16px ingesteld? Dan is 1rem in dit geval 16px groot.

De em eenheid is vergelijkbaar met de rem eenheid. Maar em wordt gebaseerd op de font-size van het element waar je de em regel op toepast. Heb je bijvoorbeeld een <h1> met een font-size van 32px? Dan is 1em gelijk aan 32px. Heeft het element waar jij em gebruikt geen font-size? Dan wordt er naar het parent element (het omliggende/bovenliggende element) gekeken.

TLDR;

1rem is gelijk aan de font-size van de <html> tag.

1em is gelijk aan de font-size van het element waar je de em regel op toepast.

Andere veelgebruikte relative eenheden zijn vw (viewport width) en vh (viewport height). De grootte van vw en vh wordt gebaseerd op het formaat van de viewport. De viewport is alles wat zichtbaar is op het scherm of binnen het browservenster. Zo is 1vw altijd 1% van de breedte van de viewport en is 1vh altijd 1% van de hoogte van de viewport. Hoe groot 1vw of 1vh in werkelijkheid is ligt dus aan de grootte van de viewport.

Het nadeel van px

Waarschijnlijk zijn de meeste developers (net zoals ik) ooit begonnen met px voor vrijwel alles. Pixels zijn namelijk erg makkelijk omdat je exact het formaat op je scherm krijgt wat je opgeeft in de CSS. Een width van 800px geeft altijd in een breedte van 800 pixels op het scherm. En design app’s zoals Figma of Sketch werken meestal ook met pixels. Met het gebruik van px in CSS kan je deze designs 1-op-1 en pixel-perfect omzetten naar een werkende website. Dat klinkt ideaal, maar het absolute formaat van px is ook het nadeel van px. Het kan namelijk in meerdere situaties wenselijk zijn dat het formaat van een element zich aanpast als een ander formaat veranderd.

Een belangrijk voorbeeld van een situatie waarbij het gebruik van px problemen op kan leveren is wanneer iemand de standaard font-size van de browser wijzigt. In iedere browser kan je een standaard font-size instellen. In vrijwel alle browsers staat de standaard font-size ingesteld op 16px. Als jij een tekst op jouw website plaatst zonder deze een font-size mee te geven dan krijgt deze tekst dus een font-size van 16px. Maar stel dat iemand de standaard font-size veranderd (en dat gebeurd ook echt), dan worden alle teksten op jouw website (waar geen font-size op is ingesteld) ook groter. Maar als je op de rest van de website pixelafmetingen hebt gebruikt dan worden alle teksten groter, maar de rest van de website niet. De breedte, rijen en kolommen van de website blijven gelijk terwijl de tekst groter wordt. Dit kan grote gevolgen hebben voor de layout van jouw website. De teksten passen bijvoorbeeld niet meer in de vlakken waar ze in staan. Het gebruik van px is daarmee ook nadelig voor de toegankelijkheid van jouw website. Iemand heeft de voorkeur voor een andere font-size, maar jouw website past zich daar niet op aan. Bij het gebruik van px wordt er dus geen rekening gehouden met deze gebruikers.

Natuurlijk kan een bezoeker de website ook een beetje inzoomen in de browser om de tekst te vergroten. Maar laten we ervoor zorgen dat de website in alle situaties goed toont!

Het voordeel van em en rem

Het formaat van em en rem wordt gebaseerd op de font-size van een ander element. Dat klinkt misschien onhandig, maar het heeft meerdere voordelen!

REM

De rem eenheid is dé oplossing voor de problemen die optreden wanneer iemand de standaard font-size van de browser aanpast. Want rem wordt gebaseerd op de font-size van de <html> tag van jouw website, en de standaard font-size van de browser wordt op de <html> tag toegepast. Zet je zelf geen font-size op de <html> tag? Dan wordt de standaard font-size van de browser gebruikt. Als je gebruik maakt van rem voor alle formaten en afmetingen op jouw website dan schalen deze allemaal mee zodra de font-size van de <html> veranderd (door jou of door de standaard font-size van de browser).

REM omrekenen naar PX

Laten we er vanuit gaan dat de font-size van de <html> tag op 16px staat. Stel je hebt een element wat 800px breed moet worden. Het rem formaat van dit element bereken je door het pixelformaat te delen door de root font-size. In dit geval wordt het dan 800 / 16 = 50. 800px is dus gelijk aan 50rem. Als de root font-size veranderd dan veranderd de breedte van dit element dus ook. Verklein je de root font-size naar 14px, dan wordt de breedte van het element 50 (rem) x 14 (px) = 700 (px). Het element schaalt nu mee met de verandering van de font-size.

Pixels omreken naar rem? Deel de pixels door de root font-size!
Rem = pixels / 16 (in de meeste gevallen)

Nog een voordeel van het gebruik van rem is dat je zelf ook de complete website kunt in- of uitzoomen aan de hand van de root font-size. Dit kan bijvoorbeeld wenselijk zijn in responsive styling. Zo kan je voor mobiel de root font-size iets verkleinen waardoor de gehele website wat uitgezoomd wordt. En je kan voor hele grote schermen de website wat inzoomen zodat je beter gebruik maakt van de grootte van het scherm. Uiteraard kan je dit niet doen door zelf een font-size in pixels mee te geven aan de <html> tag van jouw website. Daarmee overschrijf je alsnog de browser font-size wat we juist proberen te voorkomen. De root font-size dien je in dit geval aan te passen in procenten. Wil je bijvoorbeeld de root font-size verhogen van 16px naar 18px dan dien je een font-size van ((18 / 16) x 100 =) 112.5% toe te passen op de <html> tag. Hiermee kunnen bezoekers nog steeds de font-size van de browser aanpassen en kan jij jouw website schalen waar dat wenselijk is.

html {
    font-size: 100%;
}
p {
    font-size: 1rem; /* 16px */
}
html {
    font-size: 112.5%;
}
p {
    font-size: 1rem; /* 18px */
}

Uitzonderingen

Voor vrijwel alle formaten kan je gebruik maken van rem. Uiteraard voor alle font-sizes, maar ook voor paddings, margins, widths en heights. Door overal gebruik te maken van rem zorg je ervoor dat de layout en de verhoudingen van de website altijd kloppen. Er zijn enkele situaties waarin je beter geen rem kunt gebruiken of waar het niet zinvol is om rem te gebruiken.

Border widths

Zelf gebruik ik vaak nog px voor border-widths, want een border-width van 1px komt heel vaak voor. En een 1px border in rem wordt (1 / 16 =) 0.0625rem. Niet heel handig en duidelijk… En het is meestal ook niet wenselijk dat een border meeschaalt. Vaak moet een 1px border overal een 1px border blijven.

Line heights

Voor line-heights is het raadzaam om geen eenheid te gebruiken waardoor de line-height een vermenigvuldiging wordt van de font-size van het element. Het voordeel hiervan is dat de line-height altijd in verhouding is met de font-size. Vergroot je de font-size van het element? Dan schaalt de line-height mee. Em zoekt altijd naar het element waar een font-size op is toegepast, een line-height zonder eenheid kijkt altijd naar het huidige element, ook als er geen font-size op is toegepast. Neem bijvoorbeeld een titel in een design met een font-size van 24px en een line-height van 40px. De font-size zou je om kunnen zetten naar rem door 24px te delen door 16px. De font-size wordt dan 1.5rem. De line-height zonder eenheid bereken je door de font-size te delen door de line-height. In dit geval 40 / 24 = 1.667;

font-size: 1.5rem; /* 24px */
line-height: 1.667; /* 40px */

Als je de font-size nu vergroot dan wordt de line-height ook groter. De font-size en line-height zijn hierdoor altijd in de juiste verhouding!

CSS relative line height
Relative line height: een line-height zonder eenheid die meeschaald met de font-size

EM

Em is even groot als de font-size van het huidige element waar je CSS op toepast. Als het element geen font-size heeft dan wordt de font-size overgenomen van het eerste parent element wat wel een font-size heeft. Em kan daardoor heel handig zijn voor margins en paddings. Want soms is het wenselijk dat een margin of een padding meeschaalt met de font-size van een element. Een goed voorbeeld hiervan is een button. Door em te gebruiken voor de padding van een button zorg je ervoor dat bij het vergroten van de font-size de padding ook groter wordt. De button wordt dan in zijn geheel groter of kleiner. Hierdoor blijft de tekst altijd in verhouding met de achtergrond van de button zoals je kunt zien in het voorbeeld hieronder.

CSS em en rem toegepast op een button
Dankzij em schaalt de padding van de button mee met de font-size.

Het nadeel van em is dat het soms onduidelijk is op welke font-size de em is gebaseerd. Soms moet je op zoek in de code naar het element waar een font-size op is ingesteld om te kunnen achterhalen waar em het formaat vandaan haalt. En em overerft de em van parent elementen. Dit betekend dat em gebaseerd kan worden op de em waarde van het parent element. Dit kan nog meer verwarring met zich meebrengen zoals je in het voorbeeld hieronder kunt zien.

html {
    font-size: 16px;
}
div {
    font-size: 2em; /* 32px */
}
div p {
    font-size: 2em; /* 64px */
}
div p span {
    font-size: 1.5em; /* 96px */
}

Conclusie

Mijn advies is om voor alle afmetingen rem te gebruiken. Dit zorgt ervoor dat de volledige website schaalbaar wordt. De website past zicht dan aan naar de standaard font-size van de browser en het zorgt ervoor dat je zelf de website kunt schalen door alleen maar de root font-size aan te passen (in procenten). Naast rem kan je em gebruiken voor margins en paddings die mee moeten schalen met de font-size van het element zelf, bijvoorbeeld handig voor buttons. Voor line-heights kan je beter geen eenheid gebruiken zodat het altijd een vermenigvuldiging is van de font-size en daardoor de line-height altijd in verhouding is met de font-size.

Een voorbeeld van een website waar ik al deze regels in heb toegepast is de website van Laaken Asset Management. Wil jij ook zo’n website of heb je hulp nodig bij het toepassen van deze regels in jouw website? Neem dan contact op om de mogelijkheden te bespreken!