CSS Switch-Case-Bedingungen

Avatar of Yair Even Or
Yair Even Or am

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

CSS hat noch keine switch-Regel oder bedingte if-Anweisung, abgesehen von der spezifischen Natur von @media-Abfragen und einigen tiefen Tricksereien mit CSS Custom Properties. Werfen wir einen Blick darauf, warum dies nützlich wäre, und betrachten wir einen Trick, der heute anwendbar ist, um es zu ermöglichen.

Aktuelle Diskussionen über die Möglichkeit

Obwohl nichts davon heute verwendbar ist, gab es im letzten Jahr eine gute Menge an Diskussionen über das Konzept von generischen bedingten CSS.

Also, ja. Die Nachfrage nach bedingtem CSS ist vorhanden.

Stellen Sie sich vor, warum bedingtes CSS nützlich wäre

Vielleicht eine visuelle Änderung nach einer bestimmten Scroll-Menge. Eine visuelle Änderung, nachdem eine numerische Eingabe innerhalb eines bestimmten Bereichs liegt. Eine Komponente mit einer Handvoll Zuständen.

Es gibt ein ganzes Genre extrem beliebter JavaScript-Bibliotheken für Benutzeroberflächen (z. B. React, Vue usw.), die im Wesentlichen zum Erstellen von Benutzeroberflächen basierend auf Zuständen dienen. Dies ist eindeutig ein Bedarf der Entwickler. Wenn wir diese zustandsbasierte Formatierung nach CSS verschieben könnten, bräuchten wir weniger JavaScript – und vielleicht eine bessere Trennung der Zuständigkeiten.

Ein gemeinsames Thema

Wir haben bereits Custom Properties in CSS und könnten zustandsänderungslogik auf ihnen basieren lassen, wodurch ein Block von Stilen als Nebenwirkung der Änderung der Custom Property auf bestimmte Werte geändert wird.

Es stimmt, dass wir bereits Mechanismen zur Änderung von Stilblöcken haben. Wir können class über JavaScript ändern, und diese class kann alles anwenden, was wir in CSS möchten. Aber das bedeutet nicht, dass zustandsbasierte Formatierung in CSS nicht nützlich wäre. Wir haben nicht immer die Möglichkeit oder möchten vielleicht kein JavaScript dafür schreiben und stattdessen Custom Properties auf andere Weise ändern (z. B. durch Media Queries, HTML-Änderungen usw.). Dies in CSS zu tun, hilft bei der Trennung von Geschäftslogik und visueller Stil-Logik.

Ein Trick! @keyframes für den Zustand verwenden

CSS @keyframes kann verwendet werden, um spezifische Änderungen zu wechseln. Durch die Macht der animation-Eigenschaft eröffnet sich die Möglichkeit, genau auszuwählen, welcher Frame angezeigt werden soll, und ihn *genau* auf diesem Frame zu pausieren, wodurch effektiv eine Switch-Case-Anweisung oder zustandsbasierte Stile nachgeahmt werden.

Schauen wir uns das in Aktion an, indem wir mit der Eigenschaft animation-delay spielen.

Hier ist, was in diesem Pen passiert.

  • animation-delay: Negative Verzögerungswerte zwingen einen spezifischen Frame (oder dazwischen) zur Wirkung (positive Werte funktionieren nicht so). Wir werden diesen Trick verwenden, um Zustände zu erzwingen.
  • animation-play-state: paused: Wir animieren eigentlich nichts, daher bleibt die Animation pausiert.
  • animation-duration: Die tatsächliche Dauer spielt keine Rolle, sie benötigt nur eine, damit ein Zeitrahmen für die verschiedenen Keyframes vorhanden ist. Wir machen sie zu einem Wert wie 100.001s, damit auch bei einer Verzögerung von 100s der letzte Keyframe noch funktioniert. Die Dauer muss länger sein als der Verzögerungswert.

Das erste Range-Input modifiziert die animation-delay zwischen einem Bereich von -100s und 0s.

Ein Anwendungsfall aus der Praxis

Bevor wir direkt zum funktionierenden Beispiel übergehen, lohnt es sich, diesen Trick genauer zu besprechen, da es einige Nuancen gibt, die Sie beachten sollten.

Erstens funktioniert der Trick nur mit numerischen Werten. Also, Farbwerte oder Zeichenketten, da er streng mathematisch arbeitet.

Zweitens gibt es den booleschen Trick. Betrachten Sie eine Variable --value: 10, die jeden numerischen Wert zwischen 0 und 100 annehmen kann. Wir möchten eine Farbe anwenden, wenn der Wert größer als 5 ist. Woher wissen wir, ob der Wert größer oder kleiner als 5 ist? Und selbst wenn wir es wissen, wie hilft uns das wirklich?

--is-above-5: clamp(0, var(--value) - 5, 1)
--wert--ist-größer-als-5Ergebnis
000 – 5 = -5, clamp() erzwingt einen Wert, der nicht kleiner als 0 ist
202 – 5 = -3, clamp() erzwingt einen Wert, der nicht kleiner als 0 ist
505 – 5 = 0
717 – 5 = 2, clamp() erzwingt einen Wert, der nicht größer als 1 ist

clamp() ist wie ein intelligenteres calc(), da es uns erlaubt, einen berechneten Wert streng auf einen Bereich zu beschränken, während wir einen idealen Wert deklarieren. Dieser Bereich ist alles, was benötigt wird, um eine boolesche Variable zu erreichen.

Schreiben Sie jede Mathematik in den zweiten Parameter von clamp(), und dies gibt entweder 0 (oder kleiner) oder 1 (oder größer) aus. Achten Sie darauf, keine Mathematik zu schreiben, die zu einer Zahl zwischen 0 und 1 führen könnte.

So funktioniert das.

Das Range-Input-Feld hat nur die Aufgabe, seinen Wert zu „senden“, indem es Werte für --value, --min und --max definiert und dann --value mit einem oninput-Ereignis modifiziert. Das ist das Minimalste, was getan werden kann, um zustandsähnliches Verhalten in CSS zu erzielen. Kein JavaScript erforderlich.

Mit CSS-Mathematikfunktionen ist es möglich, den „abgeschlossenen“ Prozentsatz des Fortschrittsbalkens aus denselben Variablen abzuleiten.

--completed: calc((var(--value) - var(--min) ) / (var(--max) - var(--min)) * 100);

Jetzt wissen wir, ob der Wert über einem bestimmten Prozentsatz liegt, was uns eine weitere Möglichkeit gibt, Änderungen nach Zustand vorzunehmen.

--over-30: clamp(0, var(--completed) - 30, 1);
--over-70: clamp(0, var(--completed) - 70, 1);
/* ...and so on... */

Okay, großartig, aber wie können wir dies verwenden, um einen bestimmten Keyframe auszuwählen? Durch die Verwendung der max()-Funktion.

--frame: max( 
    calc(1 - var(--over-30)), 
    var(--over-30) * 2, 
    var(--over-70) * 3, 
    var(--is-100)  * 4 
);

Das Problem bei CSS-Booleans ist, dass es viele Wege gibt, sie zu verwenden, um ein bestimmtes Ziel zu erreichen, und man muss kreativ werden und eine Formel finden, die kurz und lesbar ist.

In der obigen Formel „schalten“ die Booleans eine Frame-Nummer um, wenn der Boolean den Wert 1 hat. Da wir eine max-Funktion verwenden, wird die größte umgeschaltete Frame-Nummer der berechnete Wert von --frame sein.

Beachten Sie, dass die Farbänderung eine leichte Übergangszeit hat. Wir hätten dies mit background: currentColor; auf dem Füllbereich tun können, der die Farbe vom Elternteil erbt, aber ich habe mich entschieden, CSS Houdini zu verwenden, um die Macht der Zuweisung von Übergängen zu CSS-Variablen zu veranschaulichen, indem sein type deklariert wird.

Ein Beispiel für einen intensiv genutzten **CSS-Booleschen Trick** kann im folgenden Pen gesehen werden, der eine rein CSS-basierte Komponente mit vielen Variablen ist, die eine breite Palette von Anpassungen ermöglichen.

Ich bin sicher, dass es viele weitere Anwendungsfälle für diesen kleinen Trick gibt und bin gespannt, was die Kreativität der Community noch erreichen kann.