CSS hat jetzt Custom Properties. Wir haben in letzter Zeit viel darüber geschrieben. Die Browserunterstützung ist gut, aber natürlich haben alte, nicht-evergreen Browser wie der Internet Explorer sie nicht und werden sie nie haben. Ich kann die Anziehungskraft erkennen, mit "zukünftigem CSS" zu authoring und es von einem Präprozessor für ältere Browser zurückportieren zu lassen. Babel für CSS! Warum nicht?!
Das macht mir jedoch Sorgen – weil nur *einige* Anwendungsfälle von Custom Properties vorverarbeitet werden können. Es gibt viele Situationen, in denen das, was Sie mit einer Custom Property tun, einfach *nicht* vorverarbeitet werden kann. Wenn Sie es also tun, bringen Sie sich in eine ziemlich seltsame Situation.
Wenn Sie sich in einer Situation befinden, in der Sie sie vorverarbeiten *können* und das gewünschte Ergebnis erzielen, hätten Sie wahrscheinlich einfach Präprozessor-Variablen verwenden sollen.
Präprozessoren können die DOM-Struktur nicht verstehen
Erst zur "Laufzeit", wenn ein vollständiges DOM aufgebaut ist, werden die CSS angewendet. Ganz zu schweigen von dem wahrscheinlichen Szenario, dass jede gegebene CSS-Datei eine von vielen ist, die die Seite beeinflussen.
postcss-custom-properties ist vielleicht der beliebteste Custom Property-Präprozessor (er ist in cssnext gebündelt) und erlaubt es Ihnen nur, Variablen im :root zu setzen, wie
:root {
--backgroundColor: white;
}
.header {
background-color: var(--backgroundColor);
}
Aber vielleicht ist eine der nützlichsten Eigenschaften von CSS Custom Properties, dass sie in der Kaskade verwendet werden können. Dies ist ein konstruiertes Beispiel, aber Sie werden den Punkt verstehen
:root {
--backgroundColor: white;
}
.header {
background-color: var(--backgroundColor);
}
.header.is-about-page {
--backgroundColor: yellow;
}
Mit postcss-custom-properties wird die Root-Variable verarbeitet, aber nicht die Zustandsvariation, was zu ziemlich nutzlosem CSS führt
.header {
background-color: white;
}
.header.is-about-page {
--backgroundColor: yellow;
}
Sie sind sich dessen bewusst
Die Transformation *ist nicht vollständig* und *kann nicht sein* (dynamische *kaskadierende* Variablen basierend auf Custom Properties sind vom DOM-Baum abhängig). Sie zielt derzeit nur darauf ab, eine zukunftssichere Methode zur Verwendung einer *begrenzten Teilmenge (auf den :root-Selektor)* der Funktionen nativer CSS Custom Properties zu bieten. *Da wir das DOM im Kontext dieses Plugins nicht kennen, können wir keine sichere Ausgabe erzeugen*.
Sie können interessante Diskussionen über all das lesen, wie diese hier.
Es gibt einen weiteren Custom Properties-Prozessor namens postcss-css-variables, der versucht, mehr zu tun. Zum Beispiel
.header {
background-color: var(--backgroundColor, white);
}
.header:hover {
--backgroundColor: orange;
}
.header.is-about-page {
--backgroundColor: yellow;
}
Was ausgibt
.header {
background-color: white;
}
.header:hover {
background-color: orange;
}
Es könnte den Hover richtig behandeln, aber hat sich immer noch am genannten Selektor aufgegeben.
Beide Plugins stimmen überein: *Es gibt einfach keine Möglichkeit, das, was CSS Custom Properties können, perfekt in einem CSS-Präprozessor zu replizieren.*
Wenn Sie es also tun, müssen Sie sich entweder bei der Verwendung einschränken oder falsche Ergebnisse erzielen.
Sie verlieren die Möglichkeit, sie mit JavaScript zu ändern
Neben der Kaskade ist das andere Killer-Feature von CSS Custom Properties die Möglichkeit, sie mit JavaScript zu ändern. Anstatt also mit JavaScript die X Dinge abzufragen, die Sie ändern müssen, und sie alle einzeln zu ändern, können Sie einfach eine Custom Property ändern, die sich dann wie erwartet durchsetzt.
Indem Sie CSS Custom Properties wegvorverarbeiten, existieren sie nicht im verarbeiteten CSS, und dadurch verlieren Sie diese Möglichkeit.
Wann schaltet man es ab?
Vielleicht denken Sie über diese Vorverarbeitung nur als Übergangslösung nach. Irgendwann werden Sie sie abschalten und dann Custom Properties nativ ausliefern. Sie müssen einige Arbeit leisten, um sicherzustellen, dass
- Die native Verarbeitung ist genau wie die Präprozessor-Verarbeitung
- Kein anderer Teil des Vorverarbeitungsprozesses wird dadurch verwirrt
- Ihre Fallback-Situation ist solide, wenn Sie in Browsern, die sie nicht unterstützen, immer noch eine funktionierende Erfahrung benötigen
🙃
Entschuldigung, ich weiß, dass es sich anfühlt, als würde ich hier jemandes Sache schlechtmachen. Tatsächlich halte ich solche Erkundungen für supercool und lohnenswert, sie durchzuführen und zu teilen. Die Leute, die sie machen, sind unbestreitbar intelligenter als ich.
Manche Leute sind begeistert davon. Mike Street
Ich arbeite für eine Agentur, bei der die Cross-Browser-Unterstützung ein Muss ist, und das schließt leider auch IE11 ein. Obwohl wir CSS-Variablen noch nicht ganz in der Produktion einsetzen können, bieten sie viele Vorteile für die Entwicklung und die Nachbearbeitung zu ihren ursprünglichen Eigenschaften.
Unser Gulp-Prozess beinhaltet postcss-css-variables, das jede CSS-Variable in Ihren Stylesheets in die von Ihnen festgelegten Werte umwandelt. Ähnlich wie SCSS-Variablen (auf die gleiche Weise, wie sie verarbeitet werden), aber es ermöglicht Ihnen, kleinere SCSS zu schreiben und, wenn die Zeit reif ist, die Verarbeitung zu entfernen und Ihre Stylesheets mit bereits vorhandenen Custom Properties bereitzustellen.
Ich finde einfach, dass es sich lohnt, ein wenig Vorsicht walten zu lassen. Auf der Website von cssnext gibt es ein großes Banner mit der Aufschrift "Use tomorrow’s CSS syntax, today." und ich befürchte, dass diese Art von Marketing etwas so Einfaches verkauft, das leider kompliziert und nuanciert ist.
Wenn Sie Custom Properties vorverarbeiten, können Sie genauso gut tatsächliche Präprozessor-Variablen verwenden
Das erscheint mir jedenfalls eine kluge Entscheidung zu sein.
Sass, Less und Stylus haben alle Variablen, die gut funktionieren. Sie haben sogar ein gewisses Maß an Geltungsbereich, wenn auch nicht so mächtig wie die echte Kaskade.
Wenn Sie auf das PostCSS-Ding stehen, gibt es Plugins, die Variablen zulassen, die eine Syntax verwenden, die die native CSS-Syntax nicht überlappt.
Mike Street hatte einen ziemlich coolen Anwendungsfall, bei dem er die Richtung eines Gradienten an einer Media Query umkehrte, indem er eine kleine Änderung an einer CSS Custom Property vornahm (was eine super nützliche Sache ist, die sie tun können).
div {
--direction: to bottom;
background: linear-gradient(
var(--direction),
rgba(0, 0, 0, 1) 0,
rgba(0, 0, 0, 0.1) 100%);
@media (max-width: 1000px) {
--direction: to right;
}
}
Nur postcss-css-variables (glaube ich) versucht, dies zu verarbeiten. Es ist schön prägnant, aber es ist möglich, fast das gleiche schöne Abstraktionsniveau mit SCSS zu erreichen.
@mixin specificGradient($direction) {
background: linear-gradient(
$direction,
rgba(0, 0, 0, 1) 0,
rgba(0, 0, 0, 0.1) 100%
);
}
div {
@include specificGradient(to bottom);
@media (max-width: 1000px) {
@include specificGradient(to right);
}
}
Verwenden Sie beide / behandeln Sie Fallbacks jetzt
Sie können definitiv jeden Präprozessor *und* CSS Custom Properties verwenden.
Sie können sogar einige Dinge, wie Ihre $brandColor oder etwas Ähnliches, als Präprozessor-Variable belassen. Nutzen Sie dann gleichzeitig CSS Custom Properties für Dinge, bei denen Sie sich vorstellen können, dass sie eines Tages dynamisch sein werden. Sie können sogar sofort Fallbacks behandeln, sodass Sie sich mit der Cross-Browser-Unterstützung auseinandersetzen, anstatt dies als etwas zu betrachten, das Sie wegvorverarbeiten.
$brandColor: #f06d06;
html {
background: $brandColor;
--base-font-size: 100%;
font-size: 100%;
font-size: var(--base-font-size);
}
Ja, tatsächlich habe ich immer SCSS-ähnliche Variablen verwendet, wenn ich Werte vorverarbeiten musste, aus genau diesen Gründen. Gute Zusammenfassung.
Sie funktionieren unterschiedlich, sie werden tatsächlich unterschiedlich verwendet, also verwenden Sie einfach unterschiedliche Werkzeuge, um sie zu manipulieren (SCSS vs. CSS/JavaScript).
Guter Punkt, Chris. Als SCSS-Nutzer kämpfe ich auch mit dieser Frage. Und zwar: "Wo kann ich Custom Properties anstelle von SCSS-Variablen verwenden?" und, was noch wichtiger ist: "Wann kann ich anfangen, sie zu benutzen?".
Wie Sie richtig bemerkt haben, sind Custom Properties am mächtigsten, wenn sie die Kaskade nutzen. Ich würde das so zusammenfassen: "Custom Properties eignen sich am besten für jeden Wert, der sich ändern kann."
Ich freue mich besonders darauf, Custom Properties für Spaltengratter, Überschriften-Schriftgrößen und andere responsive Variablen zu verwenden. Die Möglichkeiten, unser CSS viel prägnanter und effizienter zu gestalten, sind für mich wirklich spannend.
Ich verwende sie in der Produktion mit SCSS mit Hilfe des css-vars Sass-Mixins oder alternativ können Sie einen einfachen Sass-Fallback durchführen.
https://vgpena.github.io/winning-with-css-variables/
Ich bezweifle, dass IE sie unterstützen wird
Ich denke, ein relevanter Aspekt, der im Artikel nicht erwähnt wurde, ist, was Präprozessor-Variablen können, was Custom Properties nicht können. Ich kann an Property-Namen-Interpolation denken, aber was gibt es sonst noch?
Wenn eine Seite keine dieser zusätzlichen Funktionen verwendet, gibt es dann einen Grund, nicht zu Custom Properties zu wechseln? Die
var()-Syntax ist etwas mühsam, aber das ist ein kleiner Preis für das "Standardisieren".Mit anderen Worten, wenn die Browserunterstützung Ihnen nicht erlaubt, die speziellen Funktionen von Custom Properties zu nutzen, und Sie die speziellen Funktionen von Präprozessor-Variablen *nicht* benötigen, dann ist die Wahl zwischen beiden wirklich nur eine Frage der persönlichen Präferenz, oder?
Eine weitere esoterische Sache ist die Möglichkeit, Einheiten von Präprozessor-Variablen zu entfernen.
Aber wichtiger ist, dass die beiden genannten Custom Properties-Präprozessoren unterschiedliche Wege haben, mit Dingen umzugehen, die Sie tun und die sie nicht unterstützen. Selbst in meinen einfachen Tests hinterließ einer einige Custom Properties-Code, der nichts mehr tun würde (da er andere Teile vorverarbeitete), und der andere entfernte ihn komplett. Sie müssen also sehr aufmerksam darauf achten, wie er mit perfekt gültiger Browsernutzung von CSS Custom Properties umgeht, sonst landen Sie mit verarbeitetem Code, der ihn herausgerissen oder kaputt gemacht hat.
Ich habe mich nur gefragt, ob es möglich wäre, eine main.css zu haben, die Custom Properties verwendet, und mehrere andere Dateien, von denen nur eine pro Seite/Kategorie/was auch immer geladen wird und in diesen Dateien die Custom Properties ihre Werte erhalten.
z.B.
main.css
home.css
contact.css
main.css würde für jede Seite verwendet und die Dateien home.css und contact.css nur auf den entsprechenden Seiten.
Ich verwende Custom Properties seit über einem Jahr mit cssnext und hatte nie das Gefühl, dass es ein großes Problem ist. Sie verlieren nur die Flexibilität, Variablen innerhalb von Media Queries zu definieren, was Sie dazu zwingt, Overrides zu schreiben, anstatt nur eine Variable zu ändern. Aber das ist nichts, was Sie verlangsamt. Ich habe das Gefühl, dass ich damit leben kann, einen Schritt zurückzugehen, näher an CSS heranzukommen und dafür nachhaltigen Code zu gewinnen.