Von der Schriftgröße bis hin zur Spaltenbreite, für die optimale Optik einer Webseite ist es entscheidend, die passende Maßeinheit zu wählen. Und CSS bietet eine Vielzahl an Möglichkeiten: von px über em/rem bis vw und vh, und dazu kommt noch eine Reihe von neueren wie lh, ch oder dvh.
Dieser Artikel vermittelt einen Überblick über die verfügbaren CSS-Einheiten und stellt neben klassischen wichtigen Einheiten neuere und weniger bekannte Einheiten vor – und wofür sie sich am besten eignen.
Eine Übersicht aller verfügbaren CSS-Einheiten
Es gibt verschiedene Arten von Einheiten:
- Da sind erst einmal die sogenannten absoluten Längeneinheiten wie z.B. cm, mm, Q (Viertel mm), in (Inches), pt (Punkt) oder px (Pixel). Sie sind immer dann empfehlenswert, wenn die Ausmaße des Ausgabemediums genau bekannt sind. Wenn Sie ein Printstylesheet definieren, können Sie einen Abstand in cm angeben. Bei Webseiten hingegen verwendet man lediglich px als einzige absolute Einheit.
Neben den absoluten existieren relative Einheiten. Sie heißen relativ, weil sie eine Bezugsgröße haben. Hier kann man unterscheiden, auf was sie sich beziehen.
- em, ex, cap und ch haben als Bezugsgröße die aktuelle Schrift – sei es die aktuelle Schriftgröße (em), die Höhe des Buchstabens x in der aktuellen Schrift (ex), die Größe der Großbuchstaben (cap) oder die Breite der Ziffer 0 in der aktuellen Schrift.
- Weitere relative Einheiten beziehen sich auf die Schrift des Wurzelelements (englisch root). Das Wurzelelement ist bei HTML immer das html-Element. Diese Einheiten beginnen mit r. Beispiele dafür sind rem, aber auch rch oder rcap.
- Die Einheit lh bezieht sich auf die Höhe der Zeile des aktuellen Elements, wohingegen rlh die Zeilenhöhe des Wurzelelements als Bezugsgröße heranzieht.
- Relativ zum Viewport sind die Viewporteinheiten wie vh und vw, aber auch die neueren wie svh, dvh, lvh etc. Zudem kann man hier auch logische Einheiten wie vb statt vh und vw statt vi nutzen.
- Relativ zum Container, in dem sie stehen, sind die Container-Units wie cqw oder cqh.
- Außerdem existieren Einheiten, die nur in ausgewählten Kontexten verwendet werden wie fr, das nur bei CSS-Grid bei der Definition von Rasterspalten und -zeilen zum Einsatz kommt.
Warum aber so kompliziert?
Zu Beginn stellt sich eine grundlegende Frage. Kann man nicht einfach auf Pixel setzen und all die anderen Einheiten ignorieren?
Gegen Pixel spricht, dass Pixel unflexibel sind und in den meisten Fällen nicht zu modernen Webseiten passen, die ja auf die unterschiedlichsten Situationen (Ausgabegerät und Nutzereinstellungen) reagieren müssen. Ein einfaches Beispiel zeigt, warum etwa die Einheit rem praktischer ist als px.
Nehmen wir folgenden Code, bei dem für h1 eine Schriftgröße von 3rem definiert wird, für h2 die Schriftgröße 1.5rem:
h1 {
font-size: 3rem;
}
h2 {
font-size: 1.5rem;
}
Sofern es keine weiteren Änderungen bei der Schriftgröße gibt, entspricht 1rem dem Wert 16px. h1 ist damit 3*16px groß (48px), das Element h2 1.5 * 16px (24px), und h1 ist doppelt so groß wie h2.
Wenn ich nun in einer Media Query die Bezugsgröße verändere:
@media (min-width: 600px) {
html {
font-size: 120%;
}
}
… dann wird die Schrift bei h1 und h2 ab einer Viewport-Breite von 600px größer, aber das Verhältnis von h1 zu h2 bleibt gleich: h1 ist weiterhin doppelt so groß. Das genau ist der Vorteil: Es lassen sich über eine einzige Definition alle rem-Angaben der Webseite steuern. Wenn man mit Pixelwerten arbeitet, muss man hingegen überall Anpassungen vornehmen.
Bei Verwendung der flexiblen Einheiten ist es manchmal hilfreich, herauszufinden, was der Browser in der aktuellen Situation daraus gemacht hat. Der Browser rechnet nämlich z. B. Angaben in rem in Pixel um. Diese vom Browser berechneten Werte finden Sie in den Entwicklertools, die Sie sowohl in Chrome/Firefox öffnen, wenn Sie mit der rechten Maustaste in das Dokument klicken und „Untersuchen“ wählen. Dann sehen Sie im rechten Bereich den Tab „Berechnet“, der den berechneten Wert des gerade ausgewählten Elements ausgibt. Der Screenshot zeigt, dass der Browser die Angabe 3rem in 48px umgerechnet hat.
Em oder rem?
Im Beispiel habe ich rem verwendet, was sich auf die Größe der Schrift des Wurzelelements bezieht. In den meisten Fällen ist rem besser zu handhaben als em – weil em sich auf die Schriftgröße des Elements bezieht, bei dem es angewendet wird. Das kann Probleme bei Verschachtelungen machen. Ein Beispiel mit einer verschachtelten Liste zeigt das:
li {
font-size: 0.8em;
}
Als Ergebnis ist die Schrift der inneren Liste kleiner als die Schrift der äußeren Liste.
Das liegt daran, dass eben der Bezugspunkt für li immer die aktuelle Schriftgröße ist. Das äußere li ist 0.8 * 16px (12.8px) groß, aber die innere Liste 0.8 * 12.8px, also nur 10.24px.
Genau solche Probleme verhindert man mit rem:
li {
font-size: 0.8rem;
}
Denn rem bezieht sich auf die Schriftgröße des Wurzelelements, weswegen der Wert von rem innerhalb des Dokuments konstant ist.
rem – normalerweise das Mittel der Wahl
Im Normalfall ist es deswegen einfacher, rem statt em zu nutzen. Die Einheit em empfiehlt sich hingegen dann, wenn man möchte, dass sich ein Abstand beispielsweise immer an der aktuellen Schriftgröße orientiert: Die Browser verwenden in ihrem internen Stylesheet die Einheit em z.B. bei den Außenabständen (margin) von Überschriften oder Absätzen.
Ein guter Einsatzbereich für die Einheit em ist auch letter-spacing. Über diese Eigenschaft können Sie den Abstand zwischen Buchstaben verändern, und diese Veränderung sollte üblicherweise im Verhältnis zur gewählten Schriftgröße erfolgen, was also für em spricht.
Wo wir gerade bei Einheiten sind: Im Beispiel mit der Media Query habe ich min-width: 600px angegeben. Wenn Sie so die Viewportgröße abfragen, können Sie px verwenden – diese sind in dieser Situation weniger verpönt als sonst. Sie dürfen aber auch gerne em benutzen, die nicht die Probleme machen, die einem sonst bei em begegnen können, da sie sich in diesem Fall immer auf den Ausgangswert von font-size beziehen.
lh – die Größe der Zeilenhöhe
Sie kennen wahrscheinlich die CSS-Eigenschaft line-height für die Zeilenhöhe. Üblicherweise setzt man die Zeilenhöhe etwas höher, um für eine bessere Lesbarkeit zu sorgen, z.B. so:
body {
line-height: 1.5;
}
Hier sei angemerkt, dass Sie in diesem Fall zwar auch line-height: 1.5em schreiben könnten, aber die Variante ohne Einheit ist empfohlen, weil sie sich bei Vererbung besser verhält.
Passend zur Zeilenhöhe existiert die Einheit lh, die sich auf die Größe der aktuellen Zeile bezieht. 1lh ist so hoch wie die beim aktuellen Element verwendete Zeilenhöhe.
Man kann lh beispielsweise nutzen, wenn man Linien unter die Zeilen zeichnen möchte. Im folgenden Beispiel haben die Absätze unterschiedlich hohe Zeilen, die Definition der Linie darunter passt sich dank lh aber immer an.
Sehen wir uns den Code an. Es gibt drei Absätze mit unterschiedlichen Zeilenhöhen:
p:nth-child(1) {
line-height: 1.4;
}
p:nth-child(2) {
line-height: 1.6;
}
p:nth-child(3) {
line-height: 1.9;
}
Nun kommt der Code für die Linie, die sich immer unterhalb der Zeilen befinden soll.
p {
background-image: repeating-linear-gradient(to top, lightblue 0 1px,transparent 1px 1lh);
}
Benutzt wird zur Erzeugung der Zeilenlinien ein sich wiederholender linearer Farbverlauf (repeating-linear-gradient). Der Farbverlauf ist von unten nach oben ausgerichtet (to top). Der Verlauf besteht aus zwei Farben: lightblue und transparent. Die Farbe lightblue wird von der Position 0 bis zur Position 1px angewendet. Danach wird die Farbe transparent von der Position 1px bis zur Position 1lh verwendet.
Der Farbverlauf beginnt mit der Farbe lightblue am unteren Rand des Elements und wechselt dann zu transparent an der Position 1px. Da es sich um einen sich wiederholenden Farbverlauf handelt, wird dieses Muster über die gesamte Höhe des Elements wiederholt – und wir haben die Linien unter den Zeilen.
Außerdem könnte man natürlich lh nutzen, um die Größe von Icons passend zu bestimmen.
Die Einheit lh wird von Chrome ab 109, Safari 16.4 und Firefox ab Version 120 unterstützt.
ch für Zeilenlängenbegrenzung
Neben den Einheiten, die auf der Schriftgröße basieren, können Sie auch auf Einheiten zurückgreifen, die auf einzelnen Glyphen einer Schrift basieren. Schriften haben verschiedene Metriken, d.h. je nach gewählter Schriftfamilie ist beispielsweise die Ziffer 0 breiter oder schmaler, auch kann variieren, wie groß das x im Verhältnis zur gesamten Schriftgröße ist. Die Einheit ch bezieht sich auf die Breite der Ziffer 0 (Null) in dieser Schrift – sofern die Schreibrichtung horizontal ist, sonst auf die Höhe.
Die Einheit ch eignet sich damit sehr gut, um die Zeilenlänge zu begrenzen. Damit Text gut lesbar ist, ist es wichtig, dass die Zeilen nicht zu lang sind. Optimal für eine gute Lesbarkeit ist eine Zeilenlänge von 45 bis 65 Zeichen. Und das können Sie ganz bequem über ch realisieren. Der folgende Code sorgt dafür, dass die Absätze in dem Element mit der Klasse .article nie breiter werden als 55ch, also ungefähr 55 Zeichen haben:
.article p {
max-width: 55ch;
}
Auch kann ch sinnvoll sein, um die Größe von Formularfeldern festzulegen.
Nicht ohne meinen Viewport
Die Viewporteinheiten sind inzwischen gut etabliert – wir nutzen vw, vh, vmin und vmax. Kurze Erinnerung:
- vw gilt für die Breite des Viewports. 100vw entspricht der Gesamtbreite.
- vh ist die Einheit für die Höhe des Viewports. 100vh entspricht der Gesamthöhe.
- vmin wählt die kleinere Seite des Viewports aus, es entspricht also im Landscape-Modus der Höhe und im Porträt-Modus der Breite.
- vmax bezieht sich auf die größere Seite des Viewports, es entspricht also im Landscape-Modus der Breite und im Porträt-Modus der Höhe.
Ein klassischer Einsatz ist das Folgende:
.header {
min-height: 100vh;
}
Damit nimmt .header mindestens die gesamte Viewporthöhe ein, was allerdings nicht ganz optimal ist …
Viewport-Einheiten next level
Eine Angabe wie 100vh macht nämlich oft Probleme auf Smartphones. Denn der verfügbare Platz in der Höhe ist nicht immer gleich, da die Adresszeile und weitere Bedienelemente vorhanden oder ausgeblendet sein können. Gerade auf iOS Safari führt das zu Problemen, weil die Höhe der Adresszeile zu den 100vh addiert wird, so dass ein Bereich von 100vh höher ist als der gesamte Viewport. Wenn unten auf der Seite eine wichtige Nachricht steht, wird diese abgeschnitten und die Nutzenden müssen scrollen, um diese lesen zu können – wie im folgenden Screenshot zu sehen ist.
Zur Lösung dieses Problems hat man früher mit dem proprietären Wert -webkit-fill-available getrickst. Besser sind die neuen Viewporteinheiten; hier sind Einheiten für große, kleine und dynamische Viewports vorgesehen:
- Large Viewport: Dabei geht man davon aus, dass alle Elemente der Benutzeroberfläche reduziert sind. Die Einheiten werden mit l am Anfang geschrieben, d.h. lvw, lvh, lvmin, lvmax.
- Small Viewport: Dabei geht man davon aus, dass alle Elemente der Benutzeroberfläche ausgeklappt sind. Bei diesen Einheiten steht ein s am Anfang, d.h. svw, svh, svmin, svmax.
- Dynamic Viewport: Hierbei findet eine Anpassung statt, je nachdem, ob Schnittstellenelemente angezeigt werden oder nicht: Der Wert liegt innerhalb der Grenzen von 100lvh (Maximum) und 100svh (Minimum). Die Einheiten beginnen mit einem d, d.h. dvw, dvh, dvmin, dvmax.
Die dynamische Viewport-Einheit ist damit sehr praktisch, wenn man will, dass ein Element immer den Viewport in der Höhe ausfüllt – unabhängig davon, ob die Adresszeile da ist oder nicht:
.header {
min-height: 100dvh;
}
Der Screenshot zeigt, dass der untere Bereich nun vollständig zu sehen ist.
Zusätzlich zu den Viewporteinheiten lassen sich auch die Container-Units nutzen. Sie beziehen sich nicht auf den Viewport des aktuellen Dokuments, sondern auf den Container, in dem sich das Element befindet (dynamisch, small, large ist damit nicht notwendig). Weitere Informationen zu den Container Queries finden Sie unter www.hosteurope.de/blog/exx-css-container-queries/.
Noch mehr Optionen
Obwohl CSS so viele Einheiten bietet, reicht das nicht immer aus. Angenommen, ich möchte, dass sich die Größe einer Überschrift am Viewport orientiert, so könnte ich vw nehmen:
h1 {
font-size: 4vw;
}
Das funktioniert aber nicht gut – denn damit wird die Schrift bei großem Viewport zu groß und bei kleinem Viewport ist sie viel zu klein. Besser wäre, die Anpassungen würden nur in Maßen stattfinden und es gäbe eine Unter- und Obergrenze. Genau das lässt sich mit der CSS-Funktion clamp() definieren.
h1 {
font-size: clamp(1rem, 4vw, 2rem);
}
Bei clamp() geben Sie drei Werte an: den Mindestwert, den optimalen Wert und den Maximalwert. Im Beispiel ist die Schrift also mindestens 1rem groß und maximal 2rem, dazwischen passt sie sich am Viewport an. Solche Angaben richtig zu machen, kann kompliziert werden – und dann hilft der Fluid Type Scale Calculator.
Neben clamp() lässt sich Finetuning auch mit den Funktionen min(), max() oder auch calc() durchführen.
Fehlende Browserunterstützung
Wie geht man vor, wenn ein Browser eine Einheit noch nicht versteht? Dann wird er die Angabe ignorieren – oft ist das akzeptabel, wenn die Nutzbarkeit dadurch nicht eingeschränkt ist und wenn es nur einen kleineren Teil der Nutzenden betrifft. Bei Bedarf kann man aber natürlich die Angabe für ältere Browser zusätzlich zuerst schreiben:
.header {
min-height: 100vh;
min-height: 100dvh;
}
Für komplexere Situationen lässt sich mit @supports prüfen, ob ein Browser eine Einheit versteht, indem man sie bei einem beliebigen Ausdruck in Klammern bei @supports() schreibt.
/* Fallback-Lösung */
@supports(font-size: 1lh) {
/* wenn lh unterstützt wird */
}
Fazit: neue und weniger bekannte CSS-Einheiten
- rem eignet sich gut für die Schriftgröße, aber auch für Abstände und Ausmaße; im Allgemeinen ist es besser zu handhaben als em.
- em wiederum ist die richtige Wahl, wenn sich etwas auf die Schriftgröße des aktuellen Elements beziehen soll, z.B. bei letter-spacing.
- Die Einheit ch ist praktisch, um die Zeilenlänge zu beschränken.
- lh können Sie nutzen, wenn sich etwas auf die Zeilenhöhe beziehen soll.
- Die Viewporteinheiten sind für responsive Webseiten sehr nützlich. Statt 100vh sollten Sie aber heute für ein besseres Verhalten auf Smartphones 100dvh oder auch 100svh schreiben.
- Noch mehr Möglichkeiten ergeben sich durch die Kombination verschiedener Werte innerhalb von clamp() oder anderen Funktionen.
Titelmotiv: Bild von Pexels auf Pixabay
- Mehr Variation – neue und weniger bekannte Einheiten in CSS - 17. September 2024
- Bilder mit CSS manipulieren: die besten Techniken für attraktivere Webseiten - 14. Mai 2024