Eine CSS-Variable wie --angle: 0deg sieht aus wie eine Zahl mit Einheit, ist für den Browser aber zunächst nichts weiter als eine Folge von Tokens. Das macht sich bemerkbar, sobald man versucht, sie über @keyframes zu animieren: Der Browser kann zwischen 0deg und 360deg keine Zwischenwerte berechnen und wechselt stattdessen abrupt bei der Hälfte der Animationsdauer. @property behebt das, indem es der Variable einen festen Typ gibt, zum Beispiel <angle>. Ein guter Anlass, das am Beispiel eines rotierenden Glow-Rands durchzuspielen.
Deklariert man eine Custom Property ohne @property, hat sie automatisch den Typ *, den CSS-Werkzeugkasten für „irgendein gültiges Token". Der Browser interpretiert den Wert erst dort, wo er tatsächlich gebraucht wird, etwa als Winkel innerhalb von conic-gradient(). Für eine Animation reicht das nicht: @keyframes muss zwischen Start- und Endwert interpolieren, also Zwischenwerte berechnen, und das setzt einen bekannten Werttyp voraus. Bei einer typlosen Zeichenkette fehlt dafür der Ansatzpunkt.
:root {
--angle: 0deg;
}
.glow {
background: conic-gradient(from var(--angle), #6366f1, #22d3ee, #6366f1);
animation: rotate 4s linear infinite;
}
@keyframes rotate {
to {
--angle: 360deg;
}
}
Der Farbverlauf steht zwar da, dreht sich aber nicht. Ohne Registrierung kann der Browser --angle nicht kontinuierlich interpolieren, der Wert wechselt lediglich abrupt zwischen 0deg und 360deg , zwei Winkeln, die bei einem vollen Kreis ohnehin dieselbe Darstellung ergeben. Der Sprung bleibt deshalb unsichtbar.
@property meldet eine Custom Property beim Browser an und legt drei Angaben fest: syntax bestimmt den erlaubten Werttyp, inherits legt fest, ob Kindelemente den Wert erben, initial-value definiert den Initialwert der registrierten Property. Unregistrierte Custom Properties werden standardmäßig vererbt, inherits gibt bei registrierten Properties die Möglichkeit, das für technische Zustandswerte wie --angle bewusst abzuschalten.
@property --angle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
syntax und inherits sind Pflichtangaben. initial-value wird zur Pflicht, sobald syntax etwas anderes ist als das universelle *. Fehlt in diesem Fall eine der drei Angaben, verwirft der Browser die gesamte Regel, und die Property bleibt untypisiert.
Mit registriertem --angle lässt sich der Farbverlauf jetzt tatsächlich drehen, kombiniert mit einer Maskierungstechnik, die aus der Fläche einen schmalen Rand macht:
@property --angle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
.card-glow {
position: relative;
padding: 1.5rem;
border-radius: 1rem;
background: #111827;
color: #f3f4f6;
}
.card-glow::before {
content: "";
position: absolute;
inset: -2px;
border-radius: inherit;
padding: 2px;
pointer-events: none;
background: conic-gradient(from var(--angle), #6366f1, #22d3ee, #6366f1);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor; /* ältere, nicht standardisierte WebKit-Variante */
mask-composite: exclude;
animation: rotate-glow 4s linear infinite;
}
@keyframes rotate-glow {
to {
--angle: 360deg;
}
}
@media (prefers-reduced-motion: reduce) {
.card-glow::before {
animation: none;
}
}
Das ::before-Element liegt zwei Pixel größer als die Karte selbst und bekommt denselben Farbverlauf als Hintergrund. Die Maske aus zwei überlagerten Verläufen, einmal auf den Innenbereich begrenzt (content-box), einmal auf die volle Fläche, schneidet zusammen mit mask-composite: exclude genau den mittleren Ring aus, der sichtbar bleibt. Übrig bleibt ein zwei Pixel breiter Verlauf, der sich dank registriertem --angle erkennbar um die Karte dreht. pointer-events: none verhindert, dass das rein dekorative Element Klicks oder Hover-Zustände auf darunterliegenden Links und Buttons abfängt. Die @media-Regel am Ende berücksichtigt prefers-reduced-motion: Wer reduzierte Bewegung im Betriebssystem eingestellt hat, sieht den Glow weiterhin, allerdings ohne die dauerhafte Rotation.
Live-Beispiel
Registriert mit @property, animiert mit @keyframes, ganz ohne JavaScript.
Registrierte Custom Properties lassen sich auch mit transition interpolieren, nicht nur mit @keyframes. Der Browser kennt nach der Registrierung den Datentyp und kann deshalb bei einem Hover-Übergang sauber zwischen zwei Werten überblenden, egal ob es sich um einen Winkel, eine Farbe oder eine Länge handelt.
@property --glow-color {
syntax: "<color>";
inherits: false;
initial-value: #6366f1;
}
.card {
--glow-color: #6366f1;
background:
linear-gradient(#111827, #111827) padding-box,
linear-gradient(135deg, var(--glow-color), transparent) border-box;
border: 2px solid transparent;
transition: --glow-color 400ms ease;
}
.card:hover {
--glow-color: #22d3ee;
}
Beim Hover wechselt --glow-color weich von Indigo zu Türkis, statt abrupt umzuspringen, genau die Interpolation, die ohne Registrierung fehlen würde. Auf dieselbe Art lassen sich auch Prozentwerte registrieren, etwa für einen animierten Fortschrittsring mit <percentage>.
Registrierte Custom Properties bringen neben der Animierbarkeit noch einen zweiten Vorteil mit: Type-Checking. Ein ungültiger Wert für --angle, etwa eine Farbe oder ein Text ohne Winkeleinheit, wird nicht einfach durchgereicht, sondern fällt auf den registrierten initial-value zurück. Unregistrierte Custom Properties akzeptieren dagegen jeden beliebigen Wert, auch offensichtlich falsche, ohne jede Prüfung.
| Technik | Zweck |
|---|---|
| syntax | Legt den erlaubten Werttyp der Custom Property fest |
| inherits | Bestimmt, ob Kindelemente den Wert erben, unregistrierte Properties werden standardmäßig vererbt |
| initial-value | Initialwert der registrierten Property, Pflicht bei jedem syntax außer dem universellen * |
| Animierbarkeit | Erst ein registrierter Typ erlaubt @keyframes-Interpolation zwischen zwei Werten |
| transition | Registrierte Properties lassen sich ebenso mit transition sauber überblenden |
| Type-Checking | Ungültige Werte fallen auf initial-value zurück, statt akzeptiert zu werden |
| prefers-reduced-motion | Kann dauerhafte dekorative Animationen bei entsprechender Systemeinstellung deaktivieren |
| Browser-Unterstützung | Chrome/Edge seit Version 85, Safari seit 16.4, Firefox seit 128, Baseline seit Juli 2024 |
CSS-At-Regel zur Registrierung von Custom Properties mit festem Typ, Vererbungsverhalten und Initialwert.
Eine mit -- beginnende, frei benannte CSS-Variable.
Die Berechnung von Zwischenwerten zwischen Start- und Endwert einer Animation oder eines Übergangs.
Animationsverhalten ohne Zwischenwerte: Der Wert wechselt erst bei der Hälfte der Laufzeit abrupt von Start- zu Zielwert.
Ein Farbverlauf, der um einen Mittelpunkt rotiert, statt linear von einer Seite zur anderen zu verlaufen.
Eigenschaft, die festlegt, wie mehrere Masken auf einem Element miteinander kombiniert werden.