Der CSS Custom Property Toggle Trick

Avatar of Chris Coyier
Chris Coyier am

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

Im Juli 2020 erhielt ich eine E-Mail von James0x57 (ich versuche immer, Leute mit ihrem Namen zu bezeichnen, aber ich glaube, ich habe das Gefühl, dass sie lieber unter ihrem Benutzernamen bekannt sind), in der steht:

Die gesamte Welt der verzweigten bedingten Logik und des Massen-Feature-Toggling für benutzerdefinierte CSS-Eigenschaften ist möglich und existiert nur wegen einer winzigen Fußnote in der CSS-Spezifikation, die unbemerkt geblieben ist.

Diese Zeile lautet:

Hinweis: Während <declaration-value> mindestens ein Token darstellen muss, kann dieses eine Token ein Leerzeichen sein.

Mit anderen Worten: --foo: ; ist gültig.

Wenn Sie so sind wie ich, liest sich das nicht wie eine massive Offenbarung, die riesige Türen öffnet, aber für klügere Leute, wie James0x57, tut es das! Wir begannen mit der Arbeit an einem Entwurf für einen Blogbeitrag, aber aus verschiedenen Gründen hat er es nicht ganz geschafft. Einer dieser Gründe ist, dass *ich es einfach nicht verstanden habe.* Nennen Sie mich beratungsresistent, Entschuldigung James0x57. Eine Demo, die sie mir schickten, als ich nach einem super vereinfachten Beispiel fragte, war jedoch hilfreich, und ich denke, es hat bei mir irgendwie Klick gemacht. Hier ist meine Interpretation.

Lassen Sie mich versuchen zu erklären

  • Der hier eingerichtete Breakpoint ist eine max-width Media Query bei 900px. Sie können sehen, dass die Variable --mq-sm von initial auf einen leeren Leerzeichenwert wechselt.
  • Wenn das Browserfenster breiter als 900px ist, ist der Wert von --mq-sm initial.
    • Das bewirkt, dass die Variable --padding-when-small zwei Werte enthält – initial und 2rem –, was, nehme ich an, ungültig ist.
    • Wenn wir also tatsächlich den Abstand festlegen und diese Variable aufrufen wie padding: var(--padding-when-small, var(--padding-when-large)), wird der **zweite** Wert (der "Fallback") verwendet, da der erste Wert ungültig ist.
  • Wenn das Browserfenster schmaler als 900px ist, ist der Wert von --mq-sm ein Leerzeichen.
    • Das bewirkt, dass der Wert der Variablen --padding-when-small "(Leerzeichen)2rem" ist, was, nehme ich an, gültig ist.
    • Das bedeutet, wenn wir tatsächlich den Abstand festlegen und diese Variable aufrufen wie padding: var(--padding-when-small, var(--padding-when-large)), wird der **erste** Wert verwendet.

Somit können wir nun den Abstand zwischen zwei Werten umschalten, indem wir eine Platzhaltervariable ändern.

Das ergibt für mich Sinn.

Wenn ich das einfach als Änderung eines einzelnen Wertes sehe, denke ich fast: *Äh, ok, du hast einen wirklich komplexen Weg gefunden, um etwas Abstand zu ändern, aber du hättest den Abstand auch einfach in der Media Query ändern können.* Aber der Trick ist, dass **wir jetzt diese Platzhaltervariable haben, die sich geändert hat, und wir können daran anknüpfen, um unbegrenzt viele andere Werte zu ändern**.

Wir könnten **eine einzige Media Query** (oder eine Reihe von Media Queries) in unserem CSS haben, die nur diese Platzhaltervariablen umschaltet, und wir verwenden sie anderswo, um Werte umzuschalten. Das kann schön und übersichtlich sein, verglichen mit dem Streuen von Media Queries über das gesamte CSS. Es ist ein richtiges Umschalten in CSS, wie eine Form von WENN/DANN-Logik, die wir bisher nicht ganz hatten.

James0x57 hat dieses Denken auf alle logischen Möglichkeiten ausgedehnt, wie UND, ODER, XOR, NAND, NOR und XNOR, aber das hat mich wieder verloren. Ich bin kein Informatiker. *Aber Sie können ihrer Arbeit folgen*, wenn Sie reale Anwendungsfälle dieser Dinge sehen möchten.

Diese Variablensache ist wild und wird sehr verwirrend. Ich habe in einem möglicherweise kürzlichen (aber die Autorenzeile besagt 2015?) *Artikel* von Patrick Brosset bemerkt, der einige knifflige CSS-Custom-Properties behandelt. Zum Beispiel können Fallbacks unendlich verschachtelt sein, wie

color: var(--foo, var(--bar, var(--baz, var(--are, var(--you, var(--crazy)))));

Außerdem können gültige Werte für CSS-Custom-Properties Kommas enthalten, wie dieser

content: var(--foo, one, two, three);

Ist das wirklich nur ein Fallback mit einem einzelnen Wert *one, two, three*? Das ist ziemlich verwirrend.

Nun, schnell einige Monate vorwärts, und die CSS-Trickmeisterin Lea Verou hat *sich dieser Sache angenommen*, nämlich dem Leerzeichen in benutzerdefinierten Eigenschaften

Was wäre, wenn ich Ihnen sagen würde, dass Sie einen einzigen Eigenschaftswert verwenden könnten, um mehrere verschiedene Werte über mehrere verschiedene Eigenschaften und sogar über mehrere CSS-Regeln hinweg ein- und auszuschalten?

Es ist derselbe Trick! In Leas Beispiel nutzt sie jedoch diese Fähigkeit, um

  • Variationen für einen Button festzulegen, und
  • vier verschiedene Eigenschaften statt einer festzulegen.

Dies verdeutlicht wirklich, warum dieses Konzept so cool ist.

Lea weist auf einige Nachteile hin

Es gibt keine Möglichkeit zu sagen: „Der Hintergrund soll rot sein, wenn --foo gesetzt ist, und ansonsten weiß.“ Einige solcher Bedingungen können durch geschickten Einsatz von Anhängen emuliert werden, aber die meisten nicht.

Und natürlich gibt es ein gewisses Lesbarkeitsproblem: --foo: ; sieht aus wie ein Fehler und --foo: initial sieht ziemlich seltsam aus, es sei denn, man ist sich dieser Technik bewusst.

Wir betreten definitiv die nächste Ära der Verwendung von benutzerdefinierten Eigenschaften. Zuerst haben wir sie wie Preprocessor-Variablen verwendet. Dann sahen wir mehr Kaskaden- und Fallback-Nutzung. Als Nächstes haben wir sie häufiger mit JavaScript verwendet. Jetzt das.

Es gibt noch mehr Artikel darüber, CSS-Preprocessor-Variablen beizubehalten, nicht so sehr für die Fälle, in denen man nur das braucht, was sie können, sondern für die Dinge, die nur sie können, wie die Manipulation ihrer Farbwerte.