Responsive Designs und CSS Custom Properties: Variablen und Breakpoints definieren

Avatar of Mikolaj Dobrucki
Mikolaj Dobrucki am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

CSS Custom Properties (auch bekannt als CSS-Variablen) werden immer beliebter. Sie haben endlich eine ordentliche Browserunterstützung erreicht und finden langsam ihren Weg in verschiedene Produktionsumgebungen. Die Beliebtheit von Custom Properties ist keine Überraschung, da sie in zahlreichen Anwendungsfällen sehr hilfreich sein können, einschließlich der Verwaltung von Farbpaletten, der Anpassung von Komponenten und des Theming. Aber CSS-Variablen können auch im responsiven Design sehr nützlich sein.

Artikelserie

  1. Variablen und Breakpoints definieren (Dieser Beitrag)
  2. Ein flexibles Grid-System erstellen

Betrachten wir ein <article>-Element mit einer Überschrift und einem Absatz darin

<article class="post">
	<h2 class="heading">Post's heading</h2>
	<p class="paragraph">
		Lorem ipsum dolor sit amet, consectetur adipisicing elit.
		Laudantium numquam adipisci recusandae officiis dolore tenetur,
		nisi, beatae praesentium, soluta ullam suscipit quas?
	</p>
</article>

In solchen Fällen ist es üblich, einige Größen und Abmessungen je nach Viewport-Breite zu ändern. Eine Möglichkeit, dies zu erreichen, ist die Verwendung von Media Queries

.post {
	padding: 0.5rem 1rem;
	margin: 0.5rem auto 1rem;
}

.heading {
	font-size: 2rem;
}

@media (min-width: 576px) {
	.post {
		padding: 1rem 2rem;
		margin: 1rem auto 2rem;
	}
	
	.heading {
		font-size: 3rem;
	}
}

Siehe den Pen
#1 Responsive Features mit CSS Custom Properties erstellen
von Mikołaj (@mikolajdobrucki)
auf CodePen.

Ein solcher Ansatz bietet uns eine einfache Möglichkeit, CSS-Eigenschaften auf verschiedenen Bildschirmgrößen zu steuern. Es kann jedoch schwierig zu warten sein, wenn die Komplexität eines Projekts wächst. Bei der Verwendung von Media Queries ist es oft eine Herausforderung, den Code gleichzeitig lesbar und DRY zu halten.

Die häufigsten Herausforderungen bei der Skalierung dieses Musters umfassen

  • Wiederholte Selektoren: Abgesehen davon, dass der Code mit mehreren Deklarationen aufgebläht wird, erschwert dies auch zukünftige Refactorings, z. B. jedes Mal, wenn ein Klassename geändert wird, muss daran gedacht werden, ihn an mehreren Stellen zu aktualisieren.
  • Wiederholte Eigenschaften: Beachten Sie, dass beim Überschreiben von CSS-Regeln innerhalb von Media Queries die gesamte Deklaration wiederholt werden muss (z. B. font-size: 3rem;), obwohl nur der Wert (3rem) tatsächlich geändert wird.
  • Wiederholte Media Queries: Um responsive Stile kontextbezogen zu halten, ist es üblich, dieselben Media Queries an mehreren Stellen einzufügen, nahe den Stilen, die sie überschreiben. Dies macht den Code leider nicht nur schwerer, sondern kann auch die Wartung von Breakpoints erheblich erschweren. Andererseits kann es sehr verwirrend sein, alle responsiven Stile an einem Ort zu belassen, entfernt von ihren ursprünglichen Deklarationen: Wir enden mit mehreren Referenzen auf dieselben Elemente, die sich an völlig unterschiedlichen Stellen befinden.

Man kann argumentieren, dass wiederholte Deklarationen und Abfragen mit aktivierter Komprimierung keine große Rolle spielen sollten, zumindest solange wir uns auf die Leistung beziehen. Wir können auch mehrere Abfragen zusammenführen und Ihren Code mit Postprocessing-Tools optimieren. Aber wäre es nicht einfacher, diese Probleme von vornherein zu vermeiden?

Es gibt viele Möglichkeiten, die oben genannten Probleme zu vermeiden. Eine davon, die wir in diesem Artikel untersuchen werden, ist die Verwendung von CSS Custom Properties.

Verwendung von CSS-Variablen für Eigenschaftswerte

Es gibt viele erstaunliche Artikel im Web, die das Konzept von CSS Custom Properties erklären. Wenn Sie noch keine Gelegenheit hatten, sich damit vertraut zu machen, empfehle ich Ihnen, mit einem der Einsteigerartikel zu diesem Thema zu beginnen, wie z. B. diesem großartigen Beitrag von Serg Hospodarets, da wir uns in diesem Artikel nicht mit den Details der grundlegenden Verwendung beschäftigen werden.

Die gebräuchlichste Art, CSS Custom Properties im responsiven Design zu nutzen, ist die Verwendung von Variablen zur Speicherung von Werten, die sich innerhalb von Media Queries ändern. Um dies zu erreichen, deklarieren Sie eine Variable, die einen Wert enthält, der sich ändern soll, und weisen Sie ihn dann innerhalb einer Media Query neu zu.

:root {
  --responsive-padding: 1rem;
}

@media (min-width: 576px) {                             
  :root {
    --responsive-padding: 2rem;
  }
}

.foo {
	padding: var(--responsive-padding);
}

Die Zuweisung von Variablen zum :root-Selektor ist nicht immer eine gute Idee. Ähnlich wie in JavaScript gelten viele globale Variablen als schlechte Praxis. Versuchen Sie im wirklichen Leben, die Custom Properties in dem Geltungsbereich zu deklarieren, in dem sie tatsächlich verwendet werden.

Auf diese Weise vermeiden wir mehrere Regeln für die .foo-Klasse. Wir trennen auch die Logik (Änderung von Werten) vom eigentlichen Design (CSS-Deklarationen). Wenn wir diesen Ansatz auf unser obiges Beispiel anwenden, erhalten wir das folgende CSS

.post {
	--post-vertical-padding: 0.5rem;
	--post-horizontal-padding: 1rem;
	--post-top-margin: 0.5rem;
	--post-bottom-margin: 1rem;
	--heading-font-size: 2rem;
}

@media (min-width: 576px) {
	.post {
		--post-vertical-padding: 1rem;
		--post-horizontal-padding: 2rem;
		--post-top-margin: 1rem;
		--post-bottom-margin: 2rem;
		--heading-font-size: 3rem;
	}
}

.post {
	padding: var(--post-vertical-padding) var(--post-horizontal-padding);
	margin: var(--post-top-margin) auto  var(--post-bottom-margin);
}

.heading {
	font-size: var(--heading-font-size);
}

Siehe den Pen
#2 Responsive Features mit CSS Custom Properties erstellen
von Mikołaj (@mikolajdobrucki)
auf CodePen.

Beachten Sie, dass die Verwendung von Variablen in Kurzschrifteigenschaften (z. B. padding, margin oder font) einige sehr interessante Auswirkungen hat. Da Custom Properties fast jeden Wert (mehr dazu später) enthalten können, sogar einen leeren String, ist unklar, wie der Wert einer Kurzschrifteigenschaft in Longhand-Eigenschaften aufgeteilt wird, die später in der Kaskade verwendet werden. Beispielsweise kann auto, das in der margin-Eigenschaft oben verwendet wird, zu einem oberen und unteren Rand, einem linken und rechten Rand, einem oberen Rand, einem rechten Rand, einem unteren Rand oder einem linken Rand werden – es hängt alles von den Werten der umgebenden Custom Properties ab.

Es ist fraglich, ob der Code sauberer aussieht als der aus dem vorherigen Beispiel, aber im größeren Maßstab ist er definitiv wartungsfreundlicher. Versuchen wir nun, diesen Code etwas zu vereinfachen.

Beachten Sie, dass hier einige Werte wiederholt werden. Was wäre, wenn wir versuchen, doppelte Variablen zusammenzuführen? Betrachten wir die folgende Änderung

:root {
	--small-spacing: 0.5rem;
	--large-spacing: 1rem;
	--large-font-size: 2rem;
}

@media (min-width: 576px) {
	:root {
		--small-spacing: 1rem;
		--large-spacing: 2rem;
		--large-font-size: 3rem;
	}
}

.post {
	padding: var(--small-spacing) var(--large-spacing);
	margin: var(--small-spacing) auto  var(--large-spacing);
}

.heading {
	font-size: var(--large-font-size);
}

Siehe den Pen
#3 Responsive Features mit CSS Custom Properties erstellen
von Mikołaj (@mikolajdobrucki)
auf CodePen.

Das sieht sauberer aus, aber ist es wirklich besser? Nicht unbedingt. Zum Zweck der Flexibilität und Lesbarkeit ist dies möglicherweise nicht in jedem Fall die richtige Lösung. Wir sollten Variablen auf keinen Fall zusammenführen, nur weil sie zufällig dieselben Werte ergeben. Manchmal, solange wir dies als Teil eines gut durchdachten Systems tun, kann es uns helfen, Dinge zu vereinfachen und die Konsistenz im gesamten Projekt zu wahren. In anderen Fällen kann sich eine solche Vorgehensweise jedoch schnell als verwirrend und problematisch erweisen. Nun schauen wir uns eine weitere Möglichkeit an, diesen Code anzugehen.

Verwendung von CSS-Variablen als Multiplikatoren

CSS Custom Properties sind eine relativ neue Funktion im modernen Web. Eine weitere großartige Funktion, die in den letzten Jahren eingeführt wurde, ist die calc()-Funktion. Sie ermöglicht uns, echte mathematische Operationen in live CSS durchzuführen. Was die Browserunterstützung angeht, so wird sie in allen Browsern unterstützt, die CSS Custom Properties unterstützen.

calc() spielt sehr gut mit CSS-Variablen zusammen und macht sie noch leistungsfähiger. Das bedeutet, wir können sowohl calc() innerhalb von Custom Properties als auch Custom Properties innerhalb von calc() verwenden!

Zum Beispiel ist das folgende CSS perfekt gültig

:root {
	--size: 2;
}
	
.foo {
	--padding: calc(var(--size) * 1rem); /* 2 × 1rem = 2rem */
	padding: calc(var(--padding) * 2);   /* 2rem × 2 = 4rem */
}

Warum ist das für uns und unser responsives Design wichtig? Es bedeutet, dass wir eine calc()-Funktion verwenden können, um CSS Custom Properties innerhalb von Media Queries zu ändern. Sagen wir, wir haben einen Abstand, der auf dem Handy einen Wert von 5px und auf dem Desktop 10px haben soll. Anstatt diese Eigenschaft zweimal zu deklarieren, können wir ihr eine Variable zuweisen und sie auf größeren Bildschirmen verdoppeln.

:root {
	--padding: 1rem;
	--foo-padding: var(--padding);
}

@media (min-width: 576px) {                             
	:root {
		--foo-padding: calc(var(--padding) * 2);
	}
}

.foo {
	padding: var(--foo-padding);
}

Sieht gut aus, aber alle Werte (--padding, calc(--padding * 2)) sind von ihrer Deklaration (padding) entfernt. Die Syntax kann auch ziemlich verwirrend sein mit zwei verschiedenen Padding-Variablen (--padding und --foo-padding) und einer unklaren Beziehung zwischen ihnen.

Um die Dinge etwas klarer zu machen, versuchen wir, es andersherum zu codieren

:root {
	--multiplier: 1;
}

@media (min-width: 576px) {                             
	:root {
		--multiplier: 2;
	}
}

.foo {
	padding: calc(1rem * var(--multiplier));
}

Auf diese Weise haben wir das gleiche berechnete Ergebnis mit wesentlich saubererem Code erzielt! Anstatt also eine Variable für den Anfangswert der Eigenschaft (1rem) zu verwenden, wurde eine Variable verwendet, um einen Multiplikator zu speichern (1 auf kleinen Bildschirmen und 2 auf größeren Bildschirmen). Es ermöglicht uns auch, die --multiplier-Variable in anderen Deklarationen zu verwenden. Wenden wir diese Technik auf Padding und Margins in unserem vorherigen Schnipsel an.

:root {
	--multiplier: 1;
}

@media (min-width: 576px) {
	:root {
		--multiplier: 2;
	}
}

.post {
	padding: calc(.5rem * var(--multiplier))
						calc(1rem  * var(--multiplier));
	margin:  calc(.5rem * var(--multiplier))
						auto
						calc(1rem  * var(--multiplier));
}

Versuchen wir nun, denselben Ansatz mit Typografie umzusetzen. Zuerst fügen wir unserer Gestaltung eine weitere Überschrift hinzu.

<h1 class="heading-large">My Blog</h1>
<article class="post">
	<h2 class="heading-medium">Post's heading</h2>
	<p class="paragraph">
		Lorem ipsum dolor sit amet, consectetur adipisicing elit.
		Laudantium numquam adipisci recusandae officiis dolore tenetur,
		nisi, beatae praesentium, soluta ullam suscipit quas?
	</p>
</article>

Mit mehreren Textstilen können wir eine Variable verwenden, um auch deren Größen zu steuern.

:root {
	--headings-multiplier: 1;
}

@media (min-width: 576px) {
	:root {
		--headings-multiplier: 3 / 2;
	}
}

.heading-medium {
	font-size: calc(2rem * var(--headings-multiplier))
}

.heading-large {
	font-size: calc(3rem * var(--headings-multiplier))
}

Sie haben vielleicht bemerkt, dass 3 / 2 überhaupt kein gültiger CSS-Wert ist. Warum verursacht das dann keinen Fehler? Der Grund dafür ist, dass die Syntax für CSS-Variablen extrem nachgiebig ist, was bedeutet, dass fast alles einer Variablen zugewiesen werden kann, auch wenn es kein gültiger CSS-Wert für eine bestehende CSS-Eigenschaft ist. Deklarierte CSS Custom Properties bleiben fast vollständig unverarbeitet, bis sie von einem User Agent in bestimmten Deklarationen berechnet werden. Sobald eine Variable in einem Wert einer Eigenschaft verwendet wird, wird dieser Wert zur Berechnungszeit gültig oder ungültig.

Oh, und noch eine Anmerkung zu der letzten Anmerkung: Falls Sie sich fragen, ich habe den Wert 3 / 2 einfach zur Veranschaulichung verwendet. Im wirklichen Leben wäre es sinnvoller, 1.5 zu schreiben, um den Code lesbarer zu machen.

Nun werfen wir einen Blick auf das fertige Live-Beispiel, das alles kombiniert, was wir bisher besprochen haben.

Siehe den Pen
#4 Responsive Features mit CSS Custom Properties erstellen
von Mikołaj (@mikolajdobrucki)
auf CodePen.

Auch hier würde ich nicht pauschal dafür plädieren, calc() mit Custom Properties zu kombinieren, um den Code prägnanter zu gestalten. Aber ich kann mir definitiv Szenarien vorstellen, in denen es hilft, den Code besser zu organisieren und wartungsfreundlicher zu gestalten. Dieser Ansatz ermöglicht es auch, das Gewicht von CSS erheblich zu reduzieren, wenn er klug eingesetzt wird.

Was die Lesbarkeit betrifft, so kann man ihn als lesbarer betrachten, **sobald** die zugrunde liegende Regel verstanden wurde. Er hilft, die Logik und die Beziehungen zwischen den Werten zu erklären. Andererseits mag er für manche weniger lesbar sein, da es schwierig ist, sofort zu erkennen, welchen Wert eine Eigenschaft hat, ohne zuerst die Berechnung durchzuführen. Außerdem kann die übermäßige Verwendung von Variablen und calc()-Funktionen den Code unnötig verdecken und ihn schwerer verständlich machen, insbesondere für Junioren und Frontend-Entwickler, die sich nicht auf CSS spezialisieren.

Fazit

Zusammenfassend lässt sich sagen, dass es viele Möglichkeiten gibt, CSS Custom Properties im responsiven Design zu verwenden, die sich definitiv nicht auf die gezeigten Beispiele beschränken. CSS-Variablen können einfach verwendet werden, um Werte von Designs zu trennen. Sie können auch einen Schritt weiter gehen und mit einigen mathematischen Berechnungen kombiniert werden. Kein der vorgestellten Ansätze ist besser oder schlechter als die anderen. Die Sinnhaftigkeit ihrer Verwendung hängt vom Fall und Kontext ab.

Nachdem Sie nun wissen, wie CSS Custom Properties im responsiven Design verwendet werden können, hoffe ich, dass Sie einen Weg finden, sie in Ihren eigenen Workflow einzuführen. Als Nächstes werden wir uns Ansätze für deren Verwendung in wiederverwendbaren Komponenten und Modulen ansehen. Schauen wir uns das mal an.