# CSS-liukuvärin hover-efekti: neljä animointitapaa

[Canonical HTML page](https://gradiently.design/fi/guide/css-hover-gradient)

Uusi liukuväri :hover-tilassa vaihtuu äkillisesti. Selaimet eivät osaa häivyttää liukuväriä toiseksi, mutta ne voivat liikuttaa sitä, häivyttää sen tai animoida sen värejä. Tässä jokainen tapa koodeineen.

## The short version

- CSS-liukuvärin hover-efekti ei synny background-image-siirtymällä, sillä selaimet vaihtavat liukuvärin heti interpoloimatta sitä.
- Yhteensopivin tapa on ylikokoinen liukuväri ja background-position-siirtymä, joka liu’uttaa uudet värit näkyviin.
- Väripisteiden tai kulmien rekisteröinti @property-säännöllä mahdollistaa pehmeät siirtymät kaikissa nykyisissä valtavirran selaimissa.
- Pseudo-elementin toisen liukuvärin peittävyyden häivytys on kevyin piirtää, sillä peittävyysmuutokset eivät vaadi uudelleenmaalausta.
- Hover-efektit kannattaa rajata hover-mediakyselyllä ja niiden pitää kunnioittaa prefers-reduced-motion-asetusta.

**CSS-liukuvärin hover-efekti** tarvitsee kiertotavan, koska selaimet eivät tee `background-image`-siirtymiä. `:hover`-tilassa muutettu liukuväri vaihtuu kerralla. Neljä tapaa tuottaa pehmeän tuloksen: liu’uta ylikokoista liukuväriä `background-position`-ominaisuudella, animoi rekisteröityjä väripisteitä `@property`-säännöllä, ristihäivytä pseudo-elementin toinen liukuväri tai liikuta säteittäistä hohdetta osoittimen mukana. Eri tavat sopivat eri elementteihin. Kaikki löytyvät alta koodeineen.

## Miksi transition ei toimi liukuväreillä

Selaimelle liukuväri on kuva. Se osaa interpoloida luvun tai värin, muttei kuvaa toiseksi. Siksi `background-image` ei interpoloidu, vaan uusi liukuväri korvaa vanhan heti. Liukuvärissä käytetyt mukautetut ominaisuudet toimivat samoin, ellet rekisteröi niitä. Rekisteröimätön ominaisuus on pelkkää tekstiä.

```css
/* This snaps, with no easing */
.btn {
  background-image: linear-gradient(135deg, #1e1b4b, #6d28d9);
  transition: background-image 400ms ease;
}
.btn:hover {
  background-image: linear-gradient(135deg, #6d28d9, #f472b6);
}
```

Liukuvärin transition-rivi sivuutetaan. Kaikki alla olevat tavat kiertävät tämän.

- Lepotila: `linear-gradient(135deg, #1e1b4b 0%, #6d28d9 100%)`
- Hover-tila: `linear-gradient(135deg, #6d28d9 0%, #f472b6 100%)`

Esimerkkien kaksi tilaa. Tavoite on pehmeä muutos vasemmasta värinäytteestä oikeaan.

## Tapa 1: liu’uta ylikokoista liukuväriä

Tee taustasta elementtiä suurempi ja maalaa siihen molemmat tilat. Liikuta sitten taustaa. `background-position` tukee siirtymiä, joten uudet värit liukuvat näkyviin. Tapa toimii kaikissa selaimissa eikä tarvitse rekisteröintiä.

```css
.btn {
  background-image: linear-gradient(90deg, #1e1b4b 0%, #6d28d9 50%, #f472b6 100%);
  background-size: 200% 100%;
  background-position: 0% 50%;
  transition: background-position 500ms ease;
}

.btn:hover {
  background-position: 100% 50%;
}
```

Lepotilassa näkyy vasen puolisko indigosta violettiin. Hover-tilassa oikea puolisko violetista pinkkiin liukuu paikalleen.

Koko 200 %:n kaistale: `linear-gradient(90deg, #1e1b4b 0%, #6d28d9 50%, #f472b6 100%)`

Tässä on koko tausta. Painike näyttää siitä kerrallaan vain puolet.

Liike näyttää pyyhkäisyltä, mikä sopii painikkeisiin ja linkkeihin. Suurissa korteissa se ei vakuuta yhtä hyvin, koska liukuvärin liikkumisen huomaa. `background-position`-animointi vaatii uudelleenmaalausta, mikä sopii pieniin elementteihin. Suurille pinnoille käytä tapaa 3. [CSS-liukuväripainikkeissa](https://gradiently.design/fi/guide/css-gradient-button) on lisää tähän perustuvia malleja.

## Tapa 2: animoi väripisteitä @property-säännöllä

Rekisteröi väripisteet tyypitetyiksi mukautetuiksi ominaisuuksiksi, niin selain voi interpoloida niitä. Liukuväri vaihtaa väriä paikallaan liukumatta. `@property` toimii kaikissa nykyisissä valtavirran selaimissa. Vanhoissa tilat vaihtuvat kerralla, mikä on hover-efektille hyväksyttävä vararatkaisu. Rekisteröintisäännöt käsitellään [CSS:n @property-oppaassa](https://gradiently.design/fi/guide/css-property-animation).

```css
@property --stop-a {
  syntax: "<color>";
  inherits: false;
  initial-value: #1e1b4b;
}

@property --stop-b {
  syntax: "<color>";
  inherits: false;
  initial-value: #6d28d9;
}

.card {
  background-image: linear-gradient(135deg, var(--stop-a), var(--stop-b));
  transition: --stop-a 450ms ease, --stop-b 450ms ease;
}

.card:hover {
  --stop-a: #6d28d9;
  --stop-b: #f472b6;
}
```

Jokainen väripiste muuttuu itsenäisesti. Anna niille eri kestot, niin väri näyttää virtaavan kulmasta toiseen.

Sama keino animoi kulmaa. Rekisteröi `--angle` asetuksella `syntax: "<angle>"`, käytä sitä muodossa `linear-gradient(var(--angle), ...)` ja muuta sitä hover-tilassa. Osoittimen saapuessa 135 asteesta 225 asteeseen kääntyvä liukuväri on hienovarainen viimeistely korteissa ja [liukuvärireunuksissa](https://gradiently.design/fi/guide/css-gradient-border).

Molemmat tähänastiset tavat toimivat myös [liukuväritekstissä](https://gradiently.design/fi/guide/css-gradient-text). `background-clip: text` rajaa taustan kirjaimiin, joten otsikon taustan liuku tai väripisteiden siirtymä kuljettaa väriä kirjainten läpi hover-tilassa. Pidä luettavien otsikoiden muutos hillittynä ja varmista molempien tilojen kontrasti sivun taustaan.

## Tapa 3: ristihäivytä kaksi liukuväriä

Aseta hover-liukuväri pseudo-elementtiin pohjan yläpuolelle ja häivytä sen peittävyyttä. Koostaja käsittelee peittävyyden muutokset ilman uudelleenmaalausta. Tämä on sujuvin valinta suuriin kortteihin, pääosioihin ja pitkiin ruudukkoihin.

```css
.tile {
  position: relative;
  isolation: isolate;
  background-image: linear-gradient(135deg, #1e1b4b, #6d28d9);
}

.tile::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image: linear-gradient(135deg, #6d28d9, #f472b6);
  opacity: 0;
  transition: opacity 400ms ease;
}

.tile:hover::before {
  opacity: 1;
}
```

`z-index: -1` ja `isolation: isolate` pitävät pseudo-elementin laatan tekstin takana mutta sen pohjaliukuvärin päällä.

## Tapa 4: osoitinta seuraava hohde

Mukautetuilla ominaisuuksilla sijoitettu säteittäinen liukuväri voi seurata osoitinta. Aseta `--x` ja `--y` pienellä skriptillä, niin valo liikkuu käden mukana. Pidä se pehmeänä ja poissa tekstistä. Sen pitäisi näyttää pinnan valolta, ei sanoja ympäröivältä sädekehältä.

```css
.panel {
  background-image:
    radial-gradient(circle 220px at var(--x, 50%) var(--y, 50%), rgb(244 114 182 / 0.35), transparent 70%),
    linear-gradient(135deg, #1e1b4b, #312e81);
}

/* JavaScript:
   panel.addEventListener("pointermove", (e) => {
     const r = panel.getBoundingClientRect();
     panel.style.setProperty("--x", `${e.clientX - r.left}px`);
     panel.style.setProperty("--y", `${e.clientY - r.top}px`);
   });
*/
```

Hohde on tumman pohjan päällimmäinen kerros. Kahden mukautetun ominaisuuden päivitys on kevyt, mutta jokainen liike vaatii uudelleenmaalauksen. Käytä sitä muutamassa paneelissa, älä sivun jokaisessa kortissa.

## Sopivan tavan valinta

| Tapa | Ulkoasu | Piirtokustannus | Sopii parhaiten |
| --- | --- | --- | --- |
| Liuku background-position-ominaisuudella | Uuden värin pyyhkäisy | Uudelleenmaalaus siirtymän aikana | Painikkeet, linkit, tunnisteet |
| @property-väripisteet | Värit muuttuvat paikallaan | Uudelleenmaalaus siirtymän aikana | Kortit, merkit, reunukset |
| Peittävyyden ristihäivytys | Liukuväri sulautuu toiseksi | Koostetaan ilman uudelleenmaalausta | Suuret paneelit, pitkät ruudukot |
| Osoittimen hohde | Osoitinta seuraava valo | Uudelleenmaalaus jokaisella liikkeellä | Muutama esittelypaneeli |

Jos epäröit, ristihäivytä. Se on kevyin tapa ja toimii kaikkialla.

Itsestään liikkuvia liukuvärejä käsitellään [animoiduissa CSS-liukuväreissä](https://gradiently.design/fi/guide/css-animated-gradient). Laajempi katsaus maalausaikaan löytyy [CSS-liukuvärien suorituskyvystä](https://gradiently.design/fi/guide/css-gradient-performance).

## Kosketusnäytöt ja vähennetty liike

### Vältä

- Puhelimessa napautuksen jälkeen päälle jääviä hover-tyylejä
- Vain hover-tilassa näkyvää tietoa
- Pitkiä, toistuvia hover-animaatioita
- Vähennetyn liikkeen asetuksen sivuuttamista

### Tee näin

- Rajaa hover-säännöt kyselyllä `@media (hover: hover)`
- Näytä sama tila kosketuksessa `:active`-valitsimella
- Pidä siirtymät 200 ja 500 ms:n välillä
- Poista liike `prefers-reduced-motion`-asetuksella mutta säilytä värimuutos

```css
@media (hover: hover) {
  .btn:hover { background-position: 100% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
}
```

Väri vaihtuu edelleen kaikille. Vain liike poistetaan niiltä, jotka pyysivät sitä vähennettäväksi.

Hover-efektit elävöittävät verkkosivua. Somejulkaisuissa ei ole osoitinta, joten liikkeen täytyy kuulua itse suunnitelmaan. Gradientlyn Markit voivat liikkua lempeästi, ja Prolla viet suunnitelman MP4-, WebM- tai GIF-muodossa selaimen tukiessa tallennusta, valmiina tarinaan tai julkaisuun.

## FAQ

### Voiko CSS-liukuvärille tehdä siirtymän hover-tilassa?

Ei suoraan. `background-image` vaihtuu heti. Tee ylikokoiselle liukuvärille `background-position`-siirtymä, animoi rekisteröityjä pisteitä `@property`-säännöllä tai häivytä toisen liukuvärin peittävyyttä.

### Miten liukuväripainike vaihtaa väriä pehmeästi hover-tilassa?

Käytä kolmen väripisteen liukuväriä ja asetusta `background-size: 200% 100%`. Tee sitten hover-tilassa `background-position`-siirtymä arvosta `0% 50%` arvoon `100% 50%`.

### Toimiiko @property kaikissa selaimissa?

Se toimii Chromen, Edgen, Safarin ja Firefoxin nykyversioissa. Vanhemmat selaimet vaihtavat tilojen välillä heti ilman pehmennystä.

### Mikä on suorituskyvyltään paras liukuvärin hover-efekti?

Peittävyyden ristihäivytys: hover-liukuväri on pseudo-elementissä ja vain sen peittävyys muuttuu, jolloin uudelleenmaalausta ei tarvita.

### Pitääkö liukuvärin hover-efektin kunnioittaa vähennettyä liikettä?

Kyllä. Poista liike asetuksella `prefers-reduced-motion: reduce` ja säilytä yksinkertainen värimuutos.
