# CSS @property: animera gradienter och anpassade egenskaper

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

Gradienter vägrar övergå eftersom webbläsaren inte kan blanda en bild med en annan. Ge en anpassad egenskap en typ så försvinner gränsen. Så fungerar @property, med kod du kan klistra in.

## The short version

- CSS @property registrerar en anpassad egenskap med en syntax, en ärftlighetsregel och ett startvärde, vilket talar om för webbläsaren vilken typ av värde den håller.
- Webbläsare kan inte låta en gradient övergå direkt, eftersom background-image inte går att interpolera, men de kan låta en typad anpassad egenskap inuti gradienten övergå.
- Typade egenskaper som <color>, <angle>, <percentage> och <length> animeras mjukt; en egenskap med den universella syntaxen * växlar bara mellan värden.
- Regeln @property stöds i aktuella Chrome, Edge, Safari och Firefox, och webbläsare som ignorerar den visar helt enkelt gradienten utan rörelse.
- Att animera en anpassad egenskap inuti en bakgrund målar om elementet vid varje bildruta, så håll den animerade ytan måttlig och respektera prefers-reduced-motion.

**CSS @property** registrerar en anpassad egenskap med en typ, så att webbläsaren vet att `--angle` håller en vinkel eller att `--tint` håller en färg. När den väl känner till typen kan den interpolera mellan två värden, vilket betyder att du kan låta saker övergå och animeras som CSS annars vägrar röra: gradientfärger, gradientvinklar och positionen för ett färgstopp. Utan registrering är en anpassad egenskap bara en sträng, och en sträng kan bara hoppa från ett värde till nästa.

## Varför gradienter inte övergår av sig själva

Prova `transition: background 0.4s` på en knapp vars hover-läge byter en `linear-gradient()` mot en annan, och ingenting mjukas av: den nya gradienten hoppar in. Gradienter är bilder, och specifikationen behandlar `background-image` som icke-interpolerbar, så webbläsaren har inget sätt att blanda en bild med en annan.

Den vanliga lösningen är att överdimensionera bakgrunden och glida `background-position`, vilket är hur de flesta [animerade CSS-gradienter](https://gradiently.design/sv/guide/css-animated-gradient) byggs. Det fungerar, men det flyttar bara en fast gradient. Du kan inte ändra en färg, rotera en vinkel eller skjuta ett stopp framåt. Registrerade egenskaper ändrar det, eftersom det som animeras inte längre är bilden utan ett typat tal eller en färg inuti den. Webbläsaren räknar om gradienten vid varje bildruta utifrån det aktuella värdet.

### Oregistrerad --tint

- Lagras som en sträng av tecken
- Övergångar hoppar halvvägs
- Ärvs som standard
- Ett ogiltigt värde bryter deklarationen vid beräkningstillfället

### Registrerad med @property

- Tolkas som en riktig färg
- Övergångar interpoleras mjukt
- Du väljer själv om den ärvs
- Ett ogiltigt värde faller tillbaka på startvärdet

## Syntaxen för @property

En `@property`-regel har tre deskriptorer. `syntax` anger vilken typ av värde som tillåts, `inherits` anger om barn får värdet, och `initial-value` används när inget annat sätter det. Alla tre krävs, förutom att `initial-value` får utelämnas när syntaxen är `*`. Om någon obligatorisk del saknas eller är fel ignorerar webbläsaren hela regeln, tyst.

```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 registrerade egenskaper: en färg, en vinkel och en stoppposition. Registrera dem en gång, på översta nivån i en formatmall.

Startvärdet måste vara beräkningsmässigt oberoende, vilket i praktiken betyder absoluta enheter: `0deg`, `40%`, `12px` och hex-färger går bra, medan `2em` eller `var(--x)` inte gör det. `inherits: false` är oftast vad du vill ha för animation, och det besparar webbläsaren att trycka ner värdet i trädet.

| Syntax | Animeras mjukt | Bra för |
| --- | --- | --- |
| `<color>` | Ja | Gradientfärger, temaskiften |
| `<angle>` | Ja | Linjära vinklar, konisk rotation |
| `<percentage>` | Ja | Placering av färgstopp, storlekar |
| `<length>` | Ja | Radiella storlekar, förskjutningar |
| `<number>` | Ja | Opacitetsliknande värden, multiplikatorer |
| `<integer>` | Ja, i hela steg | Räknare, stegade effekter |
| `*` | Nej, den växlar | Allt du aldrig animerar |

Syntaxerna som spelar roll för gradientarbete. Du kan också acceptera flera, som `'<length> | <percentage>'`, eller en lista med `+`.

## Animera en gradientfärg vid hover

Det här är det minsta användbara exemplet. Knappen använder `--tint` som sin andra färg, och hover-läget ändrar bara `--tint`. Eftersom egenskapen är registrerad som en färg mjukas övergången av mellan violett och korall i stället för att hoppa.

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

Transitionen nämner själva den anpassade egenskapen. Att skriva transition: background skulle inte göra något här.

- Vila: --tint är violett: `linear-gradient(120deg, #1e1b4b 0%, #7c3aed 100%)`
- Halvvägs genom övergången: `linear-gradient(120deg, #1e1b4b 0%, #bb56b9 100%)`
- Hover: --tint är korall: `linear-gradient(120deg, #1e1b4b 0%, #fb7185 100%)`

Tre bildrutor av samma knapp. Mellanfärgen finns bara för att webbläsaren kan interpolera en registrerad färg.

För fler sätt att behandla knappar, se [gradientknapp CSS](https://gradiently.design/sv/guide/css-gradient-button) och [CSS gradient hover-effekter](https://gradiently.design/sv/guide/css-hover-gradient).

## Rotera en konisk gradientram

Ett populärt bruk av `@property` är en ram som verkar färdas runt ett kort. En [konisk gradient](https://gradiently.design/sv/guide/css-conic-gradient) startar från en vinkel, så att registrera vinkeln och animera den från `0deg` till `360deg` snurrar färgerna. Två bakgrunder gör jobbet: kortfärgen klippt mot utfyllnadsrutan och den koniska gradienten klippt mot ramrutan.

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

Upprepa den första färgen i slutet så att skarven där 360deg möter 0deg försvinner.

Den koniska ringen vid 0deg: `conic-gradient(from 0deg, #22d3ee, #7c3aed, #f472b6, #22d3ee)`

Samma gradient som ramen använder. När --angle växer vrids ringen, och den tunna remsan du ser runt kortet färdas med den. [Gradientramar i CSS](https://gradiently.design/sv/guide/css-gradient-border) går igenom den statiska versionen.

## Flytta ett färgstopp

En registrerad procentenhet låter ett stopp glida. Använd den för en förloppsfyllning, en markering som sveper över en rubrik eller en horisont som stiger vid scroll. Här flyttar `--stop` punkten där gradienten går från bläck till blågrönt.

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

Två stopp på samma position ger en hård kant, och kanten flyttar sig när --stop ändras.

## Registrera från JavaScript

`CSS.registerProperty()` gör samma jobb från ett skript. Det är praktiskt när ett designsystem registrerar sina egenskaper under körning, eller när ett värde först blir känt efter inläsning. Att registrera samma namn två gånger ger ett fel, så skydda anropet.

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

JavaScript-formen använder initialValue i camelCase. Allt annat motsvarar CSS-regeln.

## Webbläsarstöd, reservlösningar och prestanda

`@property` fungerar i aktuella Chrome, Edge, Safari och Firefox; Firefox lade till det sist, i version 128. Kolla [caniuse](https://caniuse.com/mdn-css_at-rules_property) om du stöder äldre enheter. En webbläsare som inte förstår regeln behandlar `--angle` som en vanlig anpassad egenskap, så din gradient ritas fortfarande med sitt startvärde och rör sig helt enkelt inte. Det är en bra reservlösning, förutsatt att den statiska bilden ser färdig ut.

> **Tänk på omritningen** Att animera en egenskap som används i `background` får webbläsaren att måla om elementet vid varje bildruta. En liten ram eller knapp är billig; en helskärmshjälte som animeras för evigt kostar batteri. [CSS gradient prestanda](https://gradiently.design/sv/guide/css-gradient-performance) har mätvärdena att hålla koll på.

1. **Registrera före användning** Lägg varje `@property`-regel på översta nivån, utanför mediafrågor, så att den gäller överallt.
2. **Använd typade syntaxer** Välj `<color>`, `<angle>` eller `<percentage>`. Undvik `*` för allt du tänker animera.
3. **Låt egenskapen övergå** Skriv `transition: --tint 400ms`, och nämn den anpassade egenskapen i stället för `background`.
4. **Respektera reducerad rörelse** Stoppa loopande animationer under `prefers-reduced-motion: reduce`, som beskrivs i [prefers reduced motion](https://gradiently.design/sv/guide/reduced-motion).
5. **Kontrollera stillbilden** Stäng av animationen och se till att den vilande gradienten fortfarande ser avsiktlig ut.

Om rörelsen du vill ha hör hemma i sociala inlägg eller video snarare än på en webbsida bär en Gradiently-Mark redan sitt eget ljus och sin långsamma rörelse, och Pro exporterar den som MP4, WebM eller GIF där webbläsaren stöder inspelning, utan att du skriver keyframes. För allt på webben är `@property` det renaste verktyget du har. [MDN-referensen](https://developer.mozilla.org/en-US/docs/Web/CSS/@property) listar varje deskriptor.

## FAQ

### Vad gör CSS @property?

Den registrerar en anpassad egenskap med en typ, en ärftlighetsregel och ett startvärde. Genom att känna till typen kan webbläsaren validera värdet och interpolera det i övergångar och animationer.

### Kan man animera en CSS-gradient?

Inte direkt, eftersom background-image inte går att interpolera. Registrera färgerna, vinkeln eller stoppositionerna med @property, använd dem inuti gradienten och animera de egenskaperna i stället.

### Varför fungerar inte min @property-animation?

Oftast saknas en deskriptor, startvärdet använder en relativ enhet, syntaxen är `*`, eller så nämner transitionen `background` i stället för den anpassade egenskapen. Varje ogiltig deskriptor får webbläsaren att ignorera hela regeln.

### Stöder Firefox @property?

Ja. Firefox lade till @property i version 128, så det fungerar nu i alla stora aktuella webbläsare.

### Ska inherits vara true eller false?

Använd false för de flesta animerade värden. Det håller värdet på elementet där du sätter det och sparar webbläsaren extra arbete.
