HTML/CSS

“CSS gerootet”: Flexible Schriftgrößen mit REM

6. Februar 2013
von

Diskussionen über die beste Art und Weise, die Schriftgröße bzw. den Schriftgrad zu definieren sind wahrscheinlich so alt wie das Web. Neben den traditionellen Kandidaten wie px, em und % gibt es mit rem einen neuen Bewerber, der das Beste der anderen Einheiten in sich vereint.

Von der Wurzel her betrachtet

Früher mal Standard: Schriftgrad per em oder %

Bis etwa 2008 galt es als weitgehend als Best Practice, den Schriftgrad im CSS so flexibel wie möglich zu definieren. Dazu wurden die Einheiten em oder % eingesetzt, relativ zur Standardeinstellung im Browser, die normalerweise bei 16px liegt.

Diese flexible Mischung servierte den Nutzern damals das beste Lese-Erlebnis, denn viele Browser hatten noch keinen Seitenzoom und der IE6 konnte mit px definierten Text überhaupt nicht zoomen, jedenfalls nicht ohne einen Eingriff in die Systemeinstellungen.

Sowohl bei em als auch % gab es in der Praxis aber Probleme mit der Vererbung der Schriftgrößen. Eine Prozentangabe ist immer relativ zu irgendetwas, meist zum Eltern-Element, und bei em ist das nicht anders:

  • Bei einer Box-Modell-Eigenschaft wie margin-bottom orientiert sich em an der Schriftgröße des Elements selbst. Ändert sich die Schriftgröße, ändert sich der Abstand, was zum Beispiel im Fließtext häufig ein gewünschter Effekt ist.
  • Bei der Schriftgröße hingegen gilt als Basis für ein em die Schriftgröße des Eltern-Elements. Eine Angabe von zum Beispiel 0.875em wird also bei jeder Verschachtelung ein Stückchen kleiner.

Fast wie bei Alice im Wunderland. Mal zu groß, mal zu klein, aber so richtig passen tut’s dann doch nie.

Die vorübergehende Emanzipation des px

Im Februar 2009 hielt Jens Grochtdreis in seinem Blogartikel “Die leidige Sache mit der Schriftskalierung” ein kurzes Plädoyer für die Pixel. Moderne Browser hatten damals einen Seitenzoom und der IE6 wurde als Gegenargument immer weniger wichtig.

Ein Jahr später veröffentlichte Gerrit van Aaken einen Beitrag mit dem Titel “Warum ich Pixel für CSS-Schriftgrade verwende“. In der Diskussion unter Gerrits Bekenntnis zu px ging es hoch her, aber besonders bemerkenswert ist Kommentar #22 , in dem eine Einheit namens rem erwähnt wird, die den meisten Webdesignern bis dahin weitgehend unbekannt war.

Das “root em”: rem als neuer Stern am Schriftgrad-Himmel

Seit etwa 2011 wird das rem langsam aber sicher bekannter, denn es vereint die Vorteile von pxund em. Es ist genauso flexibel wie sein älterer Bruder em, umgeht aber dessen Nachteile bei der Vererbung, weil sich das “root em” immer auf das Stammelement <html> bezieht (nicht auf <body>).

Um den Wert für rem zu erhalten, teilt man einfach die gewünschte Pixelgröße durch den Ausgangswert 16. Im CSS könnte eine solche Schriftgrad-Definition wie folgt aussehen:

1
2
3
4
html { font-size: 100%; } /* Browserdefault, 16px  */   
h1 { font-size: 1.75rem; } /* 28/16 = 1.75 */  
h2 { font-size: 1.375rem; } /* 22/16 = 1.375 */   
p { font-size: 0.875rem; } /* 14/16 = 0.875 */

Auf diese Weise lässt sich ganz einfach eine Kaskade von Schriftgraden aufbauen. Um den Schriftgrad irgendwann einmal größer oder kleiner zu machen, muss man nur die Basis ändern. Das Verhältnis von Fließtext zu Überschrift bleibt dabei immer gleich.

Das Fallback für alte Browser mit px

Das klingt fast zu gut um wahr zu sein, aber tatsächlich hat die Geschichte nur einen einzigen Haken: Alte Browser, wie immer. Auf http://caniuse.com/rem kann man sich einen guten Überblick verschaffen, und der sieht gar nicht so schlecht aus:

Can I use Rem units?

Die eigentlichen Schwachpunkte liefern der IE vor Version 9 sowie Opera Mini. Für diese beiden und alle anderen alten Browserkollegen kann man in seinen Stylesheets ein Pixel-Fallback einbauen, dass für das obige Beispiel so aussehen könnte:

1
2
3
4
5
6
7
8
9
10
11
12
13
html { font-size: 100%; }   
h1 { 
font-size: 28px; 
font-size: 1.75rem; 
}   
h2 { 
font-size: 22px; 
font-size: 1.375rem; 
}    
p { 
font-size: 14px; 
font-size: 0.875rem; 
}

Moderne Browser lesen und überschreiben im Rahmen der Kaskade den px-Wert mit dem rem-Wert, ältere hingegen nehmen die px-Anweisung und ignorieren die zweite Zeile. Perfekt.

Links zum Beitrag:

(dpe)

Ich bin Autor, Dozent und Webworker. Meine Spezialität ist es, komplizierte und 'trockene' Sachverhalte auf einfache und unterhaltende Weise darzustellen. Sie kennen mich vielleicht durch meine Bücher wie "Websites erstellen mit Contao 3", "Flexible Boxes" oder "Einstieg in CSS" (aka "das neue Little Boxes").

Tags: , , , ,

22 Kommentare zu „“CSS gerootet”: Flexible Schriftgrößen mit REM
  1. Johannes am 6. Februar 2013 um 10:41

    Sollte man für den Fallback wirklich die Einheit px verwenden oder doch lieber em?

    • Peter Müller am 6. Februar 2013 um 10:59

      Das Problem mit den “em” sind ja die Vererbungen bei Verschachtelungen. Da es ein Fallback für alte Browser ist, würde ich einfach px nehmen.

  2. Philipp am 6. Februar 2013 um 10:48

    Habe von rem noch nie was gehört, hört sich aber sehr interessant an. Ich werde das mal ausprobieren, danke für den Beitrag!

  3. Thomas am 6. Februar 2013 um 10:57

    Mit SASS/LESS mixins kann man das Fallback ja automatisch einfügen, ist also kein mehraufwand (und man spart sich sogar das umrechnen von Pixeln) z.B.

    @mixin font-size($px) {
    font-size: $px * 1px;
    font-size: 16 / $px * 1rem;
    }

    li {
    @include font-size(12);
    }

  4. Anonymous am 6. Februar 2013 um 14:40

    […] […]

  5. basti1350 am 6. Februar 2013 um 17:27

    Oh man, ich kann mich da noch an eine Diskussion mit einem Hardcore-Pixel-Verfechter auf einer anderen Seite erinnern… Gut das rem langsam aber sicher ankommt. Endlich kann man auf die Rechnerei mit em-Werten verzichten. Zum Fallback: hab auch eher zu em tendiert, aber wenn man sich schon die Rechnerei mit em macht für den Fallback, braucht man rem nicht mehr, also wie Herr Müller schon geschrieben hat ist px hierfür in Ordnung.

  6. Eugen Kraft am 6. Februar 2013 um 17:30

    Mir ist nicht ganz klar, warum die Vererbung hierbei als Problem gesehen wird.
    Sie ist ja durchaus so gedacht und wie alle Werte im CSS kann man auch diese falsch einsetzen.

    Wenn man dein Codebeispiel ansieht…

    html { font-size: 100%; } /* Browserdefault, 16px */
    h1 { font-size: 1.75rem; } /* 28/16 = 1.75 */
    h2 { font-size: 1.375rem; } /* 22/16 = 1.375 */
    p { font-size: 0.875rem; } /* 14/16 = 0.875 */

    …und es bliebe weitgehend bei diesen Definitionen, würde auch bei em als Maßeinheit keinerlei Probleme auftauchen und es würde sich auf die selbe Weise verhalten.
    Ein H2 kann nicht in einem H1 auftauchen, ein P nicht in einem H2. Auf Containerelemente ( ) gehörten em ja noch nie – außer man hat sich etwas dabei gedacht.

    Gleichzeitig beraumt man sich mit rem der Möglichkeit Bereiche spezifisch zu ändern, ohne jeden Wert auf “altmodische” Weise anzupassen – z.B.: Den Footer für Smartphone-Größen im Verhältnis deutlich zu vergrößern und leichter klickbar zu machen oder ausschließlich die Navigation auf Tablets zu verkleinern und die Content-Schrift größer zu belassen. Mit em ist beides durch einen einfachen Wert auf dem jeweiligen Strukturcontainer möglich, mit rem müsste wieder jeder Wert einzeln geändert werden. Wie siehst du das?

    • Peter Müller am 6. Februar 2013 um 22:08

      In dem simplen Beispiel könnte man auch einfach “em” setzen, aber in komplexeren kann das mit “em” schon mal komisch werden.

      Mir gefällt der konkrete Ausgangspunkt, den mir das Stammelement liefert, aber es spricht überhaupt nichts dagegen, dass du beim “em” bleibst, wenn es für dich besser passt.

  7. Ralph Segert am 6. Februar 2013 um 17:32

    Ich hatte es gestern noch mit rem versucht bei einer etwas komplizierten Skalierung einer zweizeiligen zentrierten Überschrift und einem Absatz, aber der Bezug zur Basis stellte sich nicht her. Jetzt weiss ich, warum. Nehmen Sie einfach HTML statt Body. ;)

    • Peter Müller am 6. Februar 2013 um 22:14

      Das ist wohl der häufigste Fehler beim “rem”, wohl weil die Schriftgröße früher ja fast immer im “body” definiert wurde.

      Selbst Ethan Marcotte höchstpersönlich schreibt in seinem ansonsten lesenswerten Artikel “Type study: Sizing the legible letter” tatsächlich “But the rem is sized relative to the root of your document—in other words, the value set on the body element.”

      Da kommt man schon einen Moment ins Zweifeln, wenn das so jemand schreibt, aber falsch bleibt falsch. Root ist “html” und nicht “body”.

      • Ralph Segert am 7. Februar 2013 um 15:33

        Ich singe grad en Lied davon, was es heißt, den verinnerlichten Workflow über den Haufen zu werfen, um responsive-like zu entwickeln. Von daher kann ich gut verstehen, wenn man öfter mal in der Sackgasse landet ;)

  8. Michael am 6. Februar 2013 um 17:52

    Hatte rem bislang noch nicht wirklich beachtet. Wird sich dank diesem Beitrag sicherlich ändern. Toll erklärt! Danke!

  9. Thomas Weitzel am 6. Februar 2013 um 18:42

    REMarkable Peter – Danke!

  10. Johannes am 8. Februar 2013 um 10:41

    Gibt es eigentlich ein Skript, damit auch die Internet Explorer 8 und 7 rem verstehen und korrekt wiedergeben?

    • Peter Müller am 10. Februar 2013 um 14:05

      Keine Ahnung. Aber unter anderem für die beiden ist doch das Pixel-Fallback. Das ist doch wesentlich einfacher und zuverlässiger als ein Polyfill ;-)

  11. Vielhuber David am 10. Februar 2013 um 09:37

    Interessant, man kann sich ja durchaus eine Vereinigung der beiden Welten vorstellen: Kritische Designelemente in der Navigation, die nicht in der Schriftgröße verändert werden sollten, werden pixelgenau gesetzt und Überschriften und Fließtext mit REM.

    • Lina am 21. Februar 2013 um 09:02

      Da freut sich der Nutzer aber, wenn er die Navigation nicht lesen kann.

  12. Yves Goergen am 12. Februar 2013 um 19:20

    Ich kenne diese Pixeldiskussion nicht, vllt. weil ich mich nie daran beteiligt habe. Ich verwende einmal px ganz oben, den Rest setze ich mal so, mal so.

    Früher hab ich die Größeneinstellung meines Browsers mal tatsächlich verwendet – das scheint außer mir aber niemand zu tun, wie es sich anhört. Die 16px waren mir für unstyled Text zu groß, da hab ich sie auf 12px gestellt. Wenn jetzt jemand mit 16px rechnet und 75% angibt, kann ich nix mehr erkennen. Was soll das ganze also? Darf ich die 16px-Einstellung nicht mehr verändern (wofür ist sie dann da?), oder darf ich keine px-Angabe für meine Webseite machen? Es ist so oder so Mist.

    Im Web gibt es nunmal keine 100%ige Sicherheit. Ich gestalte meine Seiten so, wie ich sie für die meisten am besten lesbar halte. Wer es anders braucht, muss sich mit seinem Browser einig werden. Sollte heute kein Problem mehr sein.

  13. Felix am 21. Mai 2013 um 04:42

    Ja, die Festlegung von 16px ist Mist. Wenn, dann sollte die Festlegung so sein, dass bei jedem Gerät abhängig von der Auflösung des Displays diese Grundeinstellung so gewählt ist, dass der Text eben so groß ist wie am Desktop ursprünglich 16px. Ich verwende Prozent resp. em, damit das eben leicht einstellbar ist. Die Vorteile der Vererbung finde ich wichtiger als deren Nachteile. Mit rem gibt es aber eine zusätzliche relative Bezugsgröße. So kann ich das so machen, dass sich mit einer Größeneinstellung über die Website nur die Schriftgröße für Fließtext ändert, aber nicht die für Titel oder andere Elemente, bei denen das eher das Layout unbrauchbar machen würde.

    Heute muss man ziemlich aufwendig erst das verwendete Display eruieren – inklusive, ob es ein Touch-Display oder ein Fernseher ist – und so die Größe für Fließtext, kleinsten Text und Schaltflächen speziell ausliefern.

    Für einen Unfug halte ich die Vorgangsweise bei den meisten Browsern, dass nicht nur Schrift, sondern der gesamte Inhalt skaliert wird und dabei sogar bei Liquid design auch die Breite über die Fensterbreite hinausgeht.

    Früher hielt ich das für einen Unfug, weil das eh die Browser anbieten, aber dadurch wird es sinnvoll, eine Schriftgrößen-Änderung auf der Website anzubieten. So kann man die Schriftgröße einstellen so groß wie man will und die Zeilenlänge bleibt innerhalb des Fensters. Die Qualität von Grafiken leidet sehr unter der Skalierung und bei diesen ist es zumeist auch nicht nötig, dass diese skaliert werden. Wichtig ist es nur für normal großen Fließtext und kleinen Fließtext (small).

    Wer die wichtigsten Elemente wie div, p, ul/li etc. mit einer anderen Schriftgröße als 1em vordefiniert, der hat freilich ein Problem mit em und Prozent bei der Verschachtelung. Etwaige verbleibende Fehler kann man ja abfangen. Beispielsweise: small small { font-size: 100% }

    • Christian Hanne am 24. Mai 2013 um 12:42

      Ist die Handhabung der Anfangsschriftgröße denn standardisiert? Dachte das läge in der Hand der Browserentwickler. Opera wählt zum Beispiel die vom User eingestellte Systemschriftgröße als Standardwert. Allerdings ist das derzeit glaube ich der einzige Browser der aus der Reihe tanzt.

  14. Daniel Riemer am 20. Oktober 2013 um 17:00

    Rätsle momentan auch, ob die Einheit „px“ als Fallback wirklich die bessere Lösung ist. Bei starren Layouts ist das sicherlich praktikabel, wenn es sich aber um ein responsives Layout handelt, bei dem beispielsweise die Schriftgröße für die Desktop-Variante global vergrößert werden soll, wird das schon schwieriger. Denn dann müssen im Grunde alle in „px“ angegebenen Werte noch einmal definiert werden, da sich ja nicht relativ vergrößern. Hier wäre dann wohl „em“ die sicherere Bank als Fallback. Da kommen dann aber die Probleme mit den Vererbungen bei Verschachtelungen wieder ins Spiel… Vom Regen in die Traufe.

  15. Johanna am 21. November 2014 um 00:57

    Wie ist das, wenn im Tablet der eine Browser die Schrift zu gross ausgibt und der andere zu klein? Gibt es da eine Lösung?

    Danke!

Ein Kommentar? Schön!

Wir freuen uns immer über Leser, die durch nützliche und konstruktive Beiträge zum Thema eine Diskussion anstoßen oder den Artikel mit weiteren Informationen anreichern. Alle Kommentare werden in diesem Sinne moderiert. Zum Kommentar-Fairplay gehört für uns auch der Einsatz von rel="nofollow". Bitte verwenden Sie zudem als Namen weder eine Domain noch ein spamverdächtiges Wort. Vielen Dank!