Wir können Variablen in CSS ziemlich einfach erstellen
:root {
--scale: 1;
}
Und wir können sie auf jedem Element deklarieren
.thing {
transform: scale(var(--scale));
}
Noch besser für ein Beispiel wie dieses ist, die Variable bei einer Benutzerinteraktion anzuwenden, z. B. :hover
:root {
--scale: 1;
}
.thing {
height: 100px;
transform: scale(var(--scale));
width: 100px;
}
.thing:hover {
--scale: 3;
}
Aber wenn wir diese Variable in einer Animation verwenden wollten... nada.
:root {
--scale: 1;
}
@keyframes scale {
from { --scale: 0; }
to { --scale: 3; }
}
/* Nope! */
.thing {
animation: scale .25s ease-in;
height: 100px;
width: 100px;
}
Das liegt daran, dass die Variable als Zeichenkette erkannt wird und wir eine Zahl benötigen, die zwischen zwei numerischen Werten interpoliert werden kann. Hier können wir @property aufrufen, um die Variable nicht nur als benutzerdefinierte Eigenschaft zu registrieren, sondern ihre Syntax als Zahl zu definieren
@property --scale {
syntax: "<number>";
initial-value: 1;
inherits: true;
}
Jetzt bekommen wir die Animation!
Sie werden die Browserunterstützung überprüfen wollen, da @property zum Zeitpunkt der Erstellung dieses Textes nur in Chrome (ab Version 85) eingeführt wurde. Und wenn Sie hoffen, sie mit @supports zu erkennen, haben wir derzeit Pech, da sie keine At-Rules als Werte akzeptiert... noch nicht. Das wird sich ändern, sobald at-rule() zu etwas Echtem wird.
Die Verwendung von
@supports not (inherits: true)bewirkt nichts, da `inherits` keine gültige CSS-Eigenschaft in irgendeinem Browser ist, sodass die Benachrichtigung angezeigt wird, auch wenn der Browser@propertyunterstützt.`inherits` ist ein Deskriptor, der nur innerhalb von
@propertygültig ist.Um die Unterstützung zu testen, müssen wir
at-rule()verwenden, aber es ist eine neue Funktion, die noch nicht implementiert ist (https://www.bram.us/2022/01/20/detect-at-rule-support-with-the-at-rule-function/)Huh! Ich dachte, ich hätte das getestet, aber offensichtlich lag ich falsch!
Faszinierend!
Was ist der Vorteil der Verwendung dieser Methode anstelle der reinen Verwendung von Zahlen? Wenn mir das jemand erklären könnte, würde ich mich wirklich freuen!
Ich denke, das ist der Punkt: Benutzerdefinierte Eigenschaften können aktualisiert und interpoliert werden, aber wir müssen sie zuerst als Zahl definieren; andernfalls sind es Zeichenketten, anstatt als Ganzzahlen behandelt zu werden.
--my-var: 7;Wenn man JS
getComputedStyle().getProperty('--myvar')verwendet, erhält man" 7"– eine Zeichenkette mit einem führenden Leerzeichen. Mit Zeichenketten kann man keine Berechnungen durchführen.Sie können Komponenten eines Eigenschaftswerts unabhängig voneinander animieren, mit unterschiedlichen Animationsdauern, Verzögerungen, Timing-Funktionen usw.
Betrachten Sie beispielsweise eine einfache
transform-Kette mit einer Drehung und dann einer Translation – dies ist die grundlegende Technik zur Positionierung von Elementen auf einem Kreis.Eine gleichmäßige Drehung eines Elements auf einem Kreis mit einem Radius von
5emwird erreicht mitAber nehmen wir an, wir wollen auch den Radius dieses Kreises unabhängig von der Drehung variieren. Nun... bevor wir benutzerdefinierte Eigenschaften animieren konnten, ging das nicht ohne ein zusätzliches Kindelement oder Pseudoelement. Das liegt daran, dass CSS gesamte Eigenschaftswerte mit CSS-Animationen animiert, nicht Teile davon, sodass wir den
transform-Wert aufbrechen müssten, um die Drehung auf unserem Element und die Translation auf einem Kindelement oder Pseudoelement zu haben.Hier kommen benutzerdefinierte Eigenschaften ins Spiel! Sie sind Eigenschaften, daher können ihre Werte animiert werden, wenn wir sie registrieren.
Dies habe ich mit vielen weiteren Beispielen in diesem Artikel detailliert beschrieben.
Auf ähnliche Weise können wir den Winkel und die Stoppposition eines
linear-gradient()unterschiedlich animierenBeachten Sie, dass Farbverläufe derzeit in keinem der Browser auf irgendeine andere Weise animiert werden können (obwohl IE10+ und das Pre-Chromium Edge sie animieren konnten).
Oder Komponenten eines
clip-path-WertsOder Komponenten eines
filter-WertsUnd was den JS-Teil betrifft: Sie machen es viel einfacher, nur Teile eines Werts über JS zu ändern. Nehmen wir zum Beispiel an, wir haben einen Scheinwerfer, der dem Cursor folgt und mit einem
radial-gradient()erstellt wurdeWenn sich der Cursor bewegt, aktualisieren wir nur die Werte
--xund--yüber JS... anstatt einen ganzen Wurst wie diesen zu schreiben
Ehrlich gesagt, es ist einfach ein bisschen lächerlich, dass CSS bisher nicht offiziell in eine Skriptsprache umgewandelt wurde.
Ich meine, seine Selektorsyntax und seine Engine haben die DOM-Methoden verdrängt! Es hat also bereits Arrays (von auf CSS-Klassen basierenden Knoten) verarbeitet.
Es hat eindeutig bedingte Tests mit @-Regeln, die sogar über eine Pseudofunktion für 'else if' und 'else' verfügen, indem Regelsätze in Abfragen für verschiedene Geräteparameter eingeschlossen werden und dann, denke ich, ein 'auch' anstelle eines 'sonst' ermöglicht wird, da alle anderen Regeln ebenfalls ausgeführt werden.
Variablen ... für die jetzt strenge Typdefinierungsunterstützung eingeführt wird?
Das ist mehr als JS selbst standardmäßig hat, oder? Daher die Existenz von TypeScript.
In der Zwischenzeit haben wir SASS, wann wäre es nicht besser, CSS auf SASS-ähnliche Fähigkeiten zu verbessern, damit es unter dem Schirm der W3C bleibt?
Hmmmm.
Ja, ich weiß, was Sie alle denken: eine klare Trennung von Stil, Markup und Verhalten klingt sinnvoll. Aber existiert das im Moment wirklich? Vielleicht viel weniger, als wir denken.
Wir können Code für
@property-Unterstützung ohne@supportstesten und anpassen.Das mache ich, um Dinge unterschiedlich zu stylen
Registrieren Sie zuerst eine benutzerdefinierte Eigenschaft
--houdiniund setzen Sie ihren Anfangswert auf1.Setzen Sie dann ein Support-Flag als benutzerdefinierte Eigenschaft
--sauf die Variable--houdinimit einem Fallback von0. Wenn die Registrierung benutzerdefinierter Eigenschaften nicht unterstützt wird, hat--sden Fallback-Wert von--houdini(0). Wenn wir die Registrierung benutzerdefinierter Eigenschaften unterstützen, nimmt--sden Anfangswert an, den wir für Houdini festgelegt haben (1).--sist also im Grunde ein Flag, das im Fall ohne Unterstützung0und andernfalls1ist. Dieses Flag kann verwendet werden, um je nach Fall unterschiedliche numerische Werte festzulegen.Live-Test.
Wir können auch einige Elemente nur im
@property-Supportfall anzeigen lassenWir können auch die Negation von
--sin anderen Fällen verwendenSolche Techniken habe ich in den Artikeln DRY Switching with CSS Variables detailliert beschrieben.