# CSS @property: animare gradienti e proprietà personalizzate

[Canonical HTML page](https://gradiently.design/it/guide/css-property-animation)

I gradienti non si lasciano animare perché il browser non sa fondere un’immagine in un’altra. Dai un tipo a una proprietà personalizzata e il limite sparisce. Ecco come funziona @property, con codice da incollare.

## The short version

- 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.

**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](https://gradiently.design/it/guide/css-animated-gradient). 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.

```css
@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%;
}
```

Tre proprietà registrate: un colore, un angolo e la posizione di uno stop. Registrale una volta sola, al livello principale di un foglio di stile.

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.

| Sintassi | Si anima con fluidità | Adatta a |
| --- | --- | --- |
| `<color>` | Sì | Colori dei gradienti, cambi di tema |
| `<angle>` | Sì | Angoli lineari, rotazione conica |
| `<percentage>` | Sì | Posizioni degli stop, dimensioni |
| `<length>` | Sì | Dimensioni radiali, scostamenti |
| `<number>` | Sì | Valori tipo opacità, moltiplicatori |
| `<integer>` | Sì, a passi interi | Contatori, effetti a scatti |
| `*` | No, passa di colpo | Tutto ciò che non animi mai |

Le sintassi che contano per i gradienti. Puoi anche accettarne più di una, come `'<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.

```css
@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;
}
```

La transizione nomina la proprietà personalizzata stessa. Scrivere transition: background qui non farebbe nulla.

- A riposo: --tint è viola: `linear-gradient(120deg, #1e1b4b 0%, #7c3aed 100%)`
- A metà della transizione: `linear-gradient(120deg, #1e1b4b 0%, #bb56b9 100%)`
- Hover: --tint è corallo: `linear-gradient(120deg, #1e1b4b 0%, #fb7185 100%)`

Tre fotogrammi dello stesso pulsante. Il colore di mezzo esiste solo perché il browser sa interpolare un colore registrato.

Per altri modi di trattare i pulsanti, vedi [CSS per pulsanti a gradiente](https://gradiently.design/it/guide/css-gradient-button) e [effetti hover con gradiente CSS](https://gradiently.design/it/guide/css-hover-gradient).

## Ruotare un bordo a gradiente conico

Un uso molto amato di `@property` è un bordo che sembra girare intorno a una scheda. Un [gradiente conico](https://gradiently.design/it/guide/css-conic-gradient) 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.

```css
@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; }
}
```

Ripeti il primo colore alla fine così la giunzione dove 360deg incontra 0deg sparisce.

L’anello conico a 0deg: `conic-gradient(from 0deg, #22d3ee, #7c3aed, #f472b6, #22d3ee)`

Lo stesso gradiente usato dal bordo. Man mano che --angle cresce, questo anello gira, e la sottile striscia che vedi intorno alla scheda viaggia con lui. [Bordi a gradiente in CSS](https://gradiently.design/it/guide/css-gradient-border) tratta la versione statica.

## 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.

```css
@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%;
}
```

Due stop nella stessa posizione creano un bordo netto, e il bordo si sposta quando --stop cambia.

## 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.

```js
if ('registerProperty' in CSS) {
  try {
    CSS.registerProperty({
      name: '--angle',
      syntax: '<angle>',
      inherits: false,
      initialValue: '0deg',
    })
  } catch {
    // Already registered, which is fine.
  }
}
```

La forma JavaScript usa initialValue in camel case. Tutto il resto coincide con la regola CSS.

## 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](https://caniuse.com/mdn-css_at-rules_property) 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.

> **Attenzione al ridisegno** Animare una proprietà usata in `background` fa ridisegnare quell’elemento a ogni fotogramma. Un piccolo bordo o un pulsante costano poco; un hero a schermo intero animato per sempre consuma batteria. Le [prestazioni dei gradienti CSS](https://gradiently.design/it/guide/css-gradient-performance) hanno le misure da tenere d’occhio.

1. **Registra prima di usare** Metti ogni regola `@property` al 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 non `background`.
4. **Rispetta il movimento ridotto** Ferma le animazioni in loop con `prefers-reduced-motion: reduce`, come descritto in [prefers reduced motion](https://gradiently.design/it/guide/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](https://developer.mozilla.org/en-US/docs/Web/CSS/@property) elenca ogni descrittore.

## FAQ

### 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.
