Abschnitt 5 · Lektion 3
Rechnen im Stylesheet
Manche Werte kennst du beim Schreiben noch nicht. Wie breit der Viewport sein wird, wie groß der Nutzer die Schrift eingestellt hat, wie viel vom Elternteil übrig bleibt. Für diese Fälle rechnet CSS selbst.
calc mischt Einheiten
calc() ist die allgemeinste der vier Funktionen. Sie beherrscht Plus, Minus, Mal und Geteilt und darf dabei Einheiten mischen, die sonst nicht zusammenpassen.
<div class="huelle">
<div class="kasten">Volle Breite minus 2rem, was der Browser für mich ausrechnet.</div>
</div> .huelle {
background-color: #fef9c3;
}
/* Prozent und rem in einer Rechnung: das kann nur der
Browser, denn wie breit die Hülle gerade ist, weiß
beim Schreiben niemand.
Die Leerzeichen um das Minus sind Pflicht. */
.kasten {
width: calc(100% - 2rem);
padding: 12px;
background-color: #dbeafe;
} calc(100% - 2rem) heißt, von der vollen Breite zwei Schriftgrößen abzuziehen. Beim Schreiben kennst du keine der beiden Zahlen, beim Rendern kennt der Browser beide.
Um + und - gehören Leerzeichen. calc(100%-2rem) funktioniert nicht. -2rem ist nämlich eine gültige negative Länge. Der Browser sieht dann 100% und -2rem, zwei Werte ohne Rechenzeichen dazwischen, und damit keine Rechnung. Die Zeile fliegt raus, und zwar still, wie in Lektion 1.4 beschrieben.
<div class="huelle">
<div class="kasten mit">calc(100% - 2rem)</div>
<div class="kasten ohne">calc(100%-2rem)</div>
</div> .huelle {
background-color: #fef9c3;
}
.kasten {
padding: 12px;
margin-bottom: 8px;
background-color: #dbeafe;
}
.mit {
width: calc(100% - 2rem);
}
/* -2rem ist eine negative Länge und kein Rechenschritt.
Die Zeile fällt weg. */
.ohne {
width: calc(100%-2rem);
} Der untere Kasten ist deshalb so breit wie die Hülle, als stünde gar keine Breite da. Rechts bleibt kein Gelb übrig.
Bei * und / sind die Leerzeichen freiwillig. Ich schreibe sie trotzdem, dann muss ich mir die Ausnahme nicht merken.
min und max sind Grenzen
Die Namen führen in die Irre. min() ist eine Obergrenze, max() eine Untergrenze.
min(100%, 400px) nimmt den kleineren der beiden Werte. Ist der Elternteil breiter als 400px, gewinnt die feste Zahl, und das Element wird nie breiter. Ist er schmaler, gewinnt die Prozentangabe.
max(30%, 300px) nimmt den größeren, und damit fällt etwas nie unter eine bestimmte Größe.
<div class="kasten obergrenze">min: höchstens 400px, sonst die volle Breite</div>
<div class="kasten untergrenze">max: mindestens 300px, sonst 30 Prozent</div> .kasten {
padding: 12px;
margin-bottom: 8px;
background-color: #dbeafe;
}
/* min() nimmt den kleineren und ist damit eine Obergrenze. */
.obergrenze {
width: min(100%, 400px);
}
/* max() nimmt den größeren und ist eine Untergrenze. */
.untergrenze {
width: max(30%, 300px);
} Beide nehmen beliebig viele Argumente und dürfen Einheiten mischen wie calc(). Gegenüber max-width und min-width haben sie einen Vorteil. Sie stehen direkt in der Eigenschaft, und es braucht keine zweite Zeile. Damit funktionieren sie auch bei Eigenschaften, für die es gar keine Grenzen-Variante gibt, etwa bei padding oder font-size.
clamp ist beides in einem
clamp(minimum, wunsch, maximum) ist eine Untergrenze und eine Obergrenze in einer Angabe. Der mittlere Wert ist der, der mitwächst.
<h1>Eine Überschrift, die mitwächst</h1>
<p>Zieh die Trennlinie zwischen Editor und Browser hin und her. Die Überschrift wächst mit, bleibt aber zwischen 28 und 48 Pixeln.</p> /* Untergrenze, Wunschgröße, Obergrenze.
Die mittlere Angabe darf mitwachsen, die beiden
äußeren halten sie in Schach. */
h1 {
font-size: clamp(28px, 6vw, 48px);
}
p {
font-size: 16px;
} Damit baut man fließende Größen. Eine Überschrift zum Beispiel, die auf dem Telefon lesbar klein bleibt und auf dem großen Bildschirm groß wird, ohne eine einzige Media Query.
Für die Untergrenze nehme ich eine feste Einheit oder rem, nie eine reine Viewport-Einheit. Sonst kann der Nutzer die Schrift im Browser nicht mehr vergrößern, und das ist ein echtes Problem für Menschen, die schlecht sehen.
Verschachteln darfst du alle vier beliebig. clamp() ist selbst nichts anderes als max(minimum, min(wunsch, maximum)). Nur wird das schnell unleserlich. Zwei Ebenen sind meistens noch verständlich, drei fast nie.
Wo eine feste Zahl ehrlicher ist
Es geht, also wird gern alles ausgerechnet. Besser wird es dadurch nicht immer.
Ein Innenabstand von 16px ist ein Innenabstand von 16px. Wird daraus clamp(12px, 1.5vw, 20px), hast du eine Zahl gegen drei Zahlen getauscht und dafür bekommen, dass der Abstand zwischen einem Laptop und einem großen Bildschirm um ein paar Pixel wandert. Das sieht niemand.
Vor jeder Formel frage ich deshalb, ob man den Unterschied sieht. Bei Schriftgrößen und großen Layout-Maßen lautet die Antwort ja. Bei Rahmen, Radien und kleinen Abständen fast immer nein, und dort ist die feste Zahl die ehrlichere Angabe.
In Lektion 5.5 kommen clamp() und benannte Werte zusammen, und dann steht die Formel genau einmal an einer Stelle statt verstreut über die ganze Datei. Die Aufgabe hier hat vier Größen, bei denen sich das Rechnen lohnt.
Zum Mitnehmen
calc() rechnet mit gemischten Einheiten, min() setzt eine Obergrenze, max() eine Untergrenze, clamp() beides. Um Plus und Minus gehören Leerzeichen, sonst wirft der Browser die Zeile weg.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.