In breve
- CSS @property registra una proprietà personalizzata con una sintassi, una regola di ereditarietà e un valore iniziale, che dicono al browser di che tipo è il valore.
- I browser non possono animare direttamente un gradiente, perché background-image non è interpolabile, ma possono animare una proprietà personalizzata tipizzata usata dentro il gradiente.
- Le proprietà tipizzate come <color>, <angle>, <percentage> e <length> si animano con fluidità; una proprietà con la sintassi universale * passa solo di colpo da un valore all’altro.
- La regola @property è supportata in Chrome, Edge, Safari e Firefox attuali, e i browser che la ignorano mostrano semplicemente il gradiente senza movimento.
- Animare una proprietà personalizzata dentro uno sfondo ridisegna l’elemento a ogni fotogramma, quindi tieni modesta l’area animata e rispetta prefers-reduced-motion.
In questa pagina
CSS @property registra una proprietà personalizzata con un tipo, così il browser sa che --angle contiene un angolo o che --tint contiene un colore. Una volta noto il tipo, può interpolare tra due valori, quindi puoi animare ciò che il CSS di solito si rifiuta di muovere: i colori di un gradiente, i suoi angoli e la posizione di uno stop. Senza registrazione, una proprietà personalizzata è solo una stringa, e una stringa può solo saltare da un valore al successivo.
Perché i gradienti non si animano da soli
Prova transition: background 0.4s su un pulsante il cui stato hover sostituisce un linear-gradient() con un altro: nulla scorre, il nuovo gradiente scatta. I gradienti sono immagini, e la specifica considera background-image non interpolabile, quindi il browser non ha modo di fondere un’immagine con un’altra.
L’espediente abituale è sovradimensionare lo sfondo e far scorrere background-position, ed è così che si costruiscono la maggior parte dei gradienti CSS animati. Funziona, ma sposta soltanto un gradiente fisso. Non puoi cambiare un colore, ruotare un angolo o spingere avanti uno stop. Le proprietà registrate cambiano le cose, perché ciò che si anima non è più l’immagine ma un numero o un colore tipizzato al suo interno. Il browser ricalcola il gradiente a ogni fotogramma dal valore corrente.
--tint non registrata
- Salvata come stringa di token
- Le transizioni saltano a metà
- Eredita per impostazione predefinita
- Un valore non valido rompe la dichiarazione al momento del calcolo
Registrata con @property
- Interpretata come un vero colore
- Le transizioni interpolano con fluidità
- L’ereditarietà è una tua scelta
- Un valore non valido ripiega sul valore iniziale
La sintassi di @property
Una regola @property ha tre descrittori. syntax dice che tipo di valore è ammesso, inherits dice se i figli ricevono il valore, e initial-value si usa quando nient’altro lo imposta. Sono tutti e tre obbligatori, tranne initial-value, che può mancare quando la sintassi è *. Se una parte richiesta manca o è sbagliata, il browser ignora l’intera regola, in silenzio.
@property --tint {
syntax: '<color>';
inherits: false;
initial-value: #7c3aed;
}
@property --angle {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
@property --stop {
syntax: '<percentage>';
inherits: false;
initial-value: 40%;
}Il valore iniziale deve essere computazionalmente indipendente, il che in pratica significa unità assolute: 0deg, 40%, 12px e i colori esadecimali vanno bene, mentre 2em o var(--x) no. Impostare inherits: false di solito è ciò che vuoi per l’animazione, e risparmia al browser di spingere il valore lungo l’albero.
<color>Si anima con fluidità
Adatta a
<angle>Si anima con fluidità
Adatta a
<percentage>Si anima con fluidità
Adatta a
<length>Si anima con fluidità
Adatta a
<number>Si anima con fluidità
Adatta a
<integer>Si anima con fluidità
Adatta a
*No, passa di colpoAdatta a
'<length> | <percentage>', o un elenco con +.Animare il colore di un gradiente all’hover
È l’esempio utile più piccolo. Il pulsante usa --tint come secondo colore e lo stato hover cambia solo --tint. Poiché la proprietà è registrata come colore, la transizione scorre tra viola e corallo invece di scattare.
@property --tint {
syntax: '<color>';
inherits: false;
initial-value: #7c3aed;
}
.button {
background: linear-gradient(120deg, #1e1b4b 0%, var(--tint) 100%);
transition: --tint 400ms ease;
}
.button:hover {
--tint: #fb7185;
}Per altri modi di trattare i pulsanti, vedi CSS per pulsanti a gradiente e effetti hover con gradiente CSS.
Ruotare un bordo a gradiente conico
Un uso molto amato di @property è un bordo che sembra girare intorno a una scheda. Un gradiente conico parte da un angolo, quindi registrare quell’angolo e animarlo da 0deg a 360deg fa girare i colori. Il lavoro lo fanno due sfondi: il colore della scheda ritagliato sul padding box e il gradiente conico ritagliato sul border box.
@property --angle {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.card {
border: 2px solid transparent;
border-radius: 16px;
background:
linear-gradient(#0f0b1e, #0f0b1e) padding-box,
conic-gradient(from var(--angle), #22d3ee, #7c3aed, #f472b6, #22d3ee) border-box;
animation: spin 6s linear infinite;
}
@keyframes spin {
to { --angle: 360deg; }
}
@media (prefers-reduced-motion: reduce) {
.card { animation: none; }
}conic-gradient(from 0deg, #22d3ee, #7c3aed, #f472b6, #22d3ee)Spostare uno stop di colore
Una percentuale registrata fa scivolare uno stop. Usala per il riempimento di un indicatore di avanzamento, per un’evidenziazione che attraversa un titolo o per un orizzonte che sale con lo scorrimento. Qui --stop sposta il punto in cui il gradiente passa dall’inchiostro al verde acqua.
@property --stop {
syntax: '<percentage>';
inherits: false;
initial-value: 20%;
}
.meter {
background: linear-gradient(90deg, #0d9488 0%, #0d9488 var(--stop), #0f172a var(--stop));
transition: --stop 600ms ease-out;
}
.meter[data-done] {
--stop: 100%;
}Registrare da JavaScript
CSS.registerProperty() fa lo stesso lavoro da uno script. È comodo quando un design system registra le sue proprietà a runtime, o quando un valore è noto solo dopo il caricamento. Registrare due volte lo stesso nome genera un errore, quindi proteggiti.
if ('registerProperty' in CSS) {
try {
CSS.registerProperty({
name: '--angle',
syntax: '<angle>',
inherits: false,
initialValue: '0deg',
})
} catch {
// Already registered, which is fine.
}
}Supporto dei browser, ripieghi e prestazioni
@property funziona in Chrome, Edge, Safari e Firefox attuali; Firefox è stato l’ultimo ad aggiungerlo, nella versione 128. Controlla caniuse se supporti dispositivi più vecchi. Un browser che non capisce la regola tratta --angle come una normale proprietà personalizzata, quindi il gradiente si disegna comunque al valore iniziale e semplicemente non si muove. È un buon ripiego, purché il fotogramma fermo sembri finito.
- 1
Registra prima di usare
Metti ogni regola
@propertyal livello principale, fuori dalle media query, così vale ovunque. - 2
Usa sintassi tipizzate
Scegli
<color>,<angle>o<percentage>. Evita*per tutto ciò che pensi di animare. - 3
Anima la proprietà
Scrivi
transition: --tint 400ms, nominando la proprietà personalizzata e nonbackground. - 4
Rispetta il movimento ridotto
Ferma le animazioni in loop con
prefers-reduced-motion: reduce, come descritto in prefers reduced motion. - 5
Controlla il fotogramma fermo
Spegni l’animazione e verifica che il gradiente a riposo sembri comunque voluto.
Se il movimento che vuoi vive nei post social o nei video e non in una pagina web, un Mark di Gradiently porta già la sua luce e un lento movimento, e Pro lo esporta in MP4, WebM o GIF dove il browser supporta la registrazione, senza scrivere keyframe. Per tutto ciò che sta sul web, @property è lo strumento più pulito che hai. Il riferimento MDN elenca ogni descrittore.
Le domande più frequenti
Che cosa fa CSS @property?
Registra una proprietà personalizzata con un tipo, una regola di ereditarietà e un valore iniziale. Conoscere il tipo permette al browser di validare il valore e interpolarlo in transizioni e animazioni.
Si può animare un gradiente CSS?
Non direttamente, perché background-image non è interpolabile. Registra i colori, l’angolo o le posizioni degli stop con @property, usali dentro il gradiente e anima quelle proprietà.
Perché la mia animazione con @property non funziona?
Di solito manca un descrittore, il valore iniziale usa un’unità relativa, la sintassi è *, oppure la transizione nomina background invece della proprietà personalizzata. Qualsiasi descrittore non valido fa ignorare l’intera regola al browser.
Firefox supporta @property?
Sì. Firefox ha aggiunto @property nella versione 128, quindi ora funziona in ogni browser principale attuale.
inherits deve essere true o false?
Usa false per la maggior parte dei valori animati. Tiene il valore sull’elemento dove lo imposti ed evita lavoro extra al browser.
Scritto da Gradiently
Il team dietro Gradiently, uno strumento di design costruito attorno ai Mark: gradienti vivi che fanno sembrare tuo tutto ciò che progetti.
Vedi il nostro profilo