# CSS @property: animer gradienter og egendefinerte egenskaper

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

Gradienter nekter å animeres fordi nettleseren ikke kan blande ett bilde over i et annet. Gi en egendefinert egenskap en type, så forsvinner den grensen. Her ser du hvordan @property virker, med kode du kan lime inn.

## The short version

- CSS @property registrerer en egendefinert egenskap med en syntaks, en arveregel og en startverdi, som forteller nettleseren hvilken type verdi den inneholder.
- Nettlesere kan ikke animere en gradient direkte, fordi background-image ikke kan interpoleres, men de kan animere en typet egendefinert egenskap som brukes inne i gradienten.
- Typede egenskaper som <color>, <angle>, <percentage> og <length> animeres jevnt; en egenskap med den universelle syntaksen * bare hopper mellom verdier.
- Regelen @property støttes i dagens Chrome, Edge, Safari og Firefox, og nettlesere som ignorerer den, viser bare gradienten uten bevegelse.
- Å animere en egendefinert egenskap i en bakgrunn maler elementet på nytt i hver bilderute, så hold det animerte området beskjedent og respekter prefers-reduced-motion.

**CSS @property** registrerer en egendefinert egenskap med en type, så nettleseren vet at `--angle` inneholder en vinkel eller at `--tint` inneholder en farge. Når den kjenner typen, kan den interpolere mellom to verdier, og da kan du animere ting CSS vanligvis nekter å flytte: gradientfarger, gradientvinkler og posisjonen til et fargestopp. Uten registrering er en egendefinert egenskap bare en tekststreng, og en streng kan bare hoppe fra én verdi til den neste.

## Hvorfor gradienter ikke animeres av seg selv

Prøv `transition: background 0.4s` på en knapp der hover-tilstanden bytter én `linear-gradient()` mot en annen, og ingenting glir: den nye gradienten hopper inn. Gradienter er bilder, og spesifikasjonen behandler `background-image` som ikke interpolerbar, så nettleseren har ingen måte å blande ett bilde over i et annet.

Den vanlige omveien er å gjøre bakgrunnen overdimensjonert og skyve `background-position`, som er slik de fleste [animerte CSS-gradienter](https://gradiently.design/nb/guide/css-animated-gradient) bygges. Det virker, men det flytter bare en fast gradient rundt. Du kan ikke endre en farge, dreie en vinkel eller skyve et stopp. Registrerte egenskaper endrer det, fordi det som animeres ikke lenger er bildet, men et typet tall eller en farge inni det. Nettleseren regner ut gradienten på nytt i hver bilderute fra den gjeldende verdien.

### Uregistrert --tint

- Lagret som en streng av tegn
- Overganger hopper halvveis
- Arves som standard
- En ugyldig verdi ødelegger deklarasjonen ved beregning

### Registrert med @property

- Tolket som en ekte farge
- Overganger interpoleres jevnt
- Arv er ditt valg
- En ugyldig verdi faller tilbake til startverdien

## Syntaksen for @property

En `@property`-regel har tre deskriptorer. `syntax` sier hvilken type verdi som er tillatt, `inherits` sier om barna får verdien, og `initial-value` brukes når ingenting annet setter den. Alle tre er påkrevd, bortsett fra at `initial-value` kan utelates når syntaksen er `*`. Mangler en påkrevd del eller er den feil, ignorerer nettleseren hele regelen, i stillhet.

```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 registrerte egenskaper: en farge, en vinkel og en stopposisjon. Registrer dem én gang, på toppnivået i et stilark.

Startverdien må være beregningsmessig uavhengig, som i praksis betyr absolutte enheter: `0deg`, `40%`, `12px` og hex-farger er greit, mens `2em` eller `var(--x)` ikke er det. `inherits: false` er som regel det du vil ha for animasjon, og det sparer nettleseren for å sende verdien nedover treet.

| Syntaks | Animeres jevnt | Godt til |
| --- | --- | --- |
| `<color>` | Ja | Gradientfarger, temaskifter |
| `<angle>` | Ja | Lineære vinkler, konisk rotasjon |
| `<percentage>` | Ja | Posisjoner for fargestopp, størrelser |
| `<length>` | Ja | Radielle størrelser, forskyvninger |
| `<number>` | Ja | Opasitetslignende verdier, multiplikatorer |
| `<integer>` | Ja, i hele steg | Tellere, trinnvise effekter |
| `*` | Nei, den hopper | Alt du aldri animerer |

Syntaksene som betyr noe for gradientarbeid. Du kan også godta flere, som `'<length> | <percentage>'`, eller en liste med `+`.

## Animer en gradientfarge ved hover

Dette er det minste nyttige eksempelet. Knappen bruker `--tint` som andre farge, og hover-tilstanden endrer bare `--tint`. Fordi egenskapen er registrert som en farge, glir overgangen mellom fiolett og korall i stedet for å hoppe.

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

Overgangen navngir selve den egendefinerte egenskapen. Å skrive transition: background ville ikke gjort noe her.

- Hvile: --tint er fiolett: `linear-gradient(120deg, #1e1b4b 0%, #7c3aed 100%)`
- Halvveis i overgangen: `linear-gradient(120deg, #1e1b4b 0%, #bb56b9 100%)`
- Hover: --tint er korall: `linear-gradient(120deg, #1e1b4b 0%, #fb7185 100%)`

Tre bilderuter av samme knapp. Fargen i midten finnes bare fordi nettleseren kan interpolere en registrert farge.

Flere måter å behandle knapper på finner du i [gradientknapper i CSS](https://gradiently.design/nb/guide/css-gradient-button) og [hover-effekter med CSS-gradient](https://gradiently.design/nb/guide/css-hover-gradient).

## Roter en konisk gradientkant

En yndlingsbruk av `@property` er en kant som ser ut til å vandre rundt et kort. En [konisk gradient](https://gradiently.design/nb/guide/css-conic-gradient) starter fra en vinkel, så når du registrerer vinkelen og animerer den fra `0deg` til `360deg`, snurrer fargene. To bakgrunner gjør jobben: kortfargen klippet til padding-boksen og den koniske gradienten klippet til border-boksen.

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

Gjenta den første fargen til slutt, så forsvinner skjøten der 360deg møter 0deg.

Den koniske ringen på 0deg: `conic-gradient(from 0deg, #22d3ee, #7c3aed, #f472b6, #22d3ee)`

Den samme gradienten som kanten bruker. Når --angle vokser, dreier denne ringen, og den tynne stripen du ser rundt kortet, følger med. [Gradientkanter i CSS](https://gradiently.design/nb/guide/css-gradient-border) tar for seg den statiske versjonen.

## Flytt et fargestopp

En registrert prosentverdi lar et stopp gli. Bruk den til en fremdriftsfylling, en utheving som sveiper over en overskrift, eller en horisont som stiger når du ruller. Her flytter `--stop` punktet der gradienten skifter fra blekk til blågrønn.

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

To stopp på samme posisjon gir en skarp kant, og kanten flytter seg når --stop endres.

## Registrering fra JavaScript

`CSS.registerProperty()` gjør samme jobb fra et skript. Det er praktisk når et designsystem registrerer egenskapene sine under kjøring, eller når en verdi først blir kjent etter lasting. Å registrere samme navn to ganger kaster en feil, så beskytt kallet.

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

JavaScript-formen bruker initialValue i camelCase. Alt annet er som i CSS-regelen.

## Nettleserstøtte, reserveløsninger og ytelse

`@property` virker i dagens Chrome, Edge, Safari og Firefox; Firefox var sist ute og la det til i versjon 128. Sjekk [caniuse](https://caniuse.com/mdn-css_at-rules_property) hvis du støtter eldre enheter. En nettleser som ikke forstår regelen, behandler `--angle` som en vanlig egendefinert egenskap, så gradienten tegnes fortsatt med startverdien og står bare stille. Det er en fin reserveløsning, så lenge stillbildet ser ferdig ut.

> **Pass på ny maling** Å animere en egenskap som brukes i `background`, får nettleseren til å male elementet på nytt i hver bilderute. En liten kant eller knapp er billig; et toppfelt i full skjerm som animeres uendelig, koster batteri. [Ytelse for CSS-gradienter](https://gradiently.design/nb/guide/css-gradient-performance) har målingene du bør følge med på.

1. **Registrer før du bruker** Legg hver `@property`-regel på toppnivået, utenfor mediespørringer, så den gjelder overalt.
2. **Bruk typede syntakser** Velg `<color>`, `<angle>` eller `<percentage>`. Unngå `*` for alt du har tenkt å animere.
3. **Animer egenskapen** Skriv `transition: --tint 400ms` og navngi den egendefinerte egenskapen i stedet for `background`.
4. **Respekter redusert bevegelse** Stopp animasjoner som går i loop under `prefers-reduced-motion: reduce`, som beskrevet i [prefers reduced motion](https://gradiently.design/nb/guide/reduced-motion).
5. **Sjekk stillbildet** Slå av animasjonen og sørg for at gradienten i hvile fortsatt ser tilsiktet ut.

Hvis bevegelsen du ønsker, hører hjemme i innlegg i sosiale medier eller video og ikke på en nettside, har en Mark fra Gradiently allerede sitt eget lys og sin langsomme bevegelse, og Pro eksporterer den som MP4, WebM eller GIF der nettleseren støtter opptak, uten at du skriver keyframes. For alt på nettet er `@property` det ryddigste verktøyet du har. [MDN-referansen](https://developer.mozilla.org/en-US/docs/Web/CSS/@property) lister opp alle deskriptorene.

## FAQ

### Hva gjør CSS @property?

Den registrerer en egendefinert egenskap med en type, en arveregel og en startverdi. Når nettleseren kjenner typen, kan den validere verdien og interpolere den i overganger og animasjoner.

### Kan man animere en CSS-gradient?

Ikke direkte, fordi background-image ikke kan interpoleres. Registrer fargene, vinkelen eller stopposisjonene med @property, bruk dem inne i gradienten og animer de egenskapene i stedet.

### Hvorfor virker ikke @property-animasjonen min?

Som regel mangler en deskriptor, startverdien bruker en relativ enhet, syntaksen er `*`, eller overgangen navngir `background` i stedet for den egendefinerte egenskapen. En ugyldig deskriptor får nettleseren til å ignorere hele regelen.

### Støtter Firefox @property?

Ja. Firefox la til @property i versjon 128, så det virker nå i alle store nettlesere i dag.

### Skal inherits være true eller false?

Bruk false for de fleste animerte verdier. Da blir verdien værende på elementet der du satte den, og nettleseren slipper ekstra arbeid.
