# Interpolação OKLCH em gradientes CSS para misturas suaves

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

A maioria dos gradientes baços, de meio cinzento, não é um problema de cor mas de matemática. Duas palavras, in oklch, mudam onde o navegador faz as contas.

## The short version

- Os gradientes CSS misturam-se em sRGB por predefinição quando todas as suas cores estão escritas em hexadecimal, rgb() ou hsl(), o que muitas vezes deixa o meio de uma mistura baço ou cinzento.
- Acrescentar in oklch ou in oklab a um gradiente diz ao navegador para misturar num espaço de cor perceptual, o que mantém a luminosidade uniforme e as cores limpas.
- O in oklab faz o caminho mais reto entre duas cores, enquanto o in oklch percorre o círculo dos matizes e mantém a saturação alta.
- Palavras-chave de matiz como shorter hue, longer hue, increasing hue e decreasing hue escolhem o sentido em que um gradiente oklch percorre o círculo cromático.
- Os navegadores ignoram declarações que não conseguem interpretar, por isso escrever primeiro um gradiente sRGB e depois a versão oklch é uma reserva segura.

A interpolação **OKLCH em gradientes CSS** significa pedir ao navegador que calcule as cores intermédias de um gradiente no espaço de cor OKLCH em vez de em sRGB. Acrescentas duas palavras a seguir à direção: `linear-gradient(90deg in oklch, #2563eb, #facc15)`. O resultado é uma mistura cuja luminosidade muda de forma uniforme e cujo meio se mantém vivo, em vez de descair para a faixa cinzenta e lamacenta pela qual as misturas sRGB simples são conhecidas.

- sRGB (predefinição para hex): `linear-gradient(90deg, #2563eb, #facc15)`
- in oklab: `linear-gradient(90deg in oklab, #2563eb, #facc15)`
- in oklch: `linear-gradient(90deg in oklch, #2563eb, #facc15)`

Azul a amarelo de três formas. O sRGB passa por cinzento; o oklab mantém-se limpo e neutro; o oklch mantém a cor plena ao passar por verde-azulado e verde.

## Porque é que os gradientes sRGB ficam cinzentos

O sRGB foi concebido para codificar cores de ecrã de forma eficiente, não para corresponder à forma como as pessoas veem. Misturar duas cores sRGB significa fazer a média dos seus números de vermelho, verde e azul, e a meio caminho entre um azul e um amarelo há um conjunto de números medianos que parece cinzento. A sua luminosidade também muda de forma irregular, por isso algumas misturas ficam mais claras ou mais escuras no meio. O lado de design deste problema está nos [gradientes lamacentos](https://gradiently.design/pt-pt/guide/muddy-gradients).

O Oklab e a sua forma cilíndrica, o OKLCH, foram concebidos para que passos iguais nos seus números pareçam passos aproximadamente iguais ao olho. Misturar neles mantém a luminosidade percebida a mover-se de forma constante, e é por isso que os gradientes feitos assim parecem mais suaves e mais brilhantes com os mesmos extremos.

## A sintaxe: in oklch e in oklab

O método de interpolação vai no primeiro argumento, antes ou depois da direção. Funciona em `linear-gradient()`, `radial-gradient()`, `conic-gradient()` e nas suas formas repetidas, e também em `color-mix()`. As tuas paragens de cor podem continuar em hexadecimal; só a matemática muda.

```css
/* direction first or interpolation first: both are valid */
background: linear-gradient(135deg in oklch, #7c3aed, #f97316);
background: linear-gradient(in oklch 135deg, #7c3aed, #f97316);

/* works in the other gradient functions too */
background: radial-gradient(in oklab circle at 30% 30%, #22d3ee, #1e1b4b);
background: conic-gradient(in oklch from 90deg, #ef4444, #3b82f6, #ef4444);
```

Só a mistura muda; as paragens de cor ficam como foram escritas.

| Espaço de cor | Como mistura | Usa-o para |
| --- | --- | --- |
| `srgb` | Faz a média de vermelho, verde e azul | Reproduzir exatamente designs antigos |
| `srgb-linear` | Faz a média da luz física | Efeitos de mistura de luz; os pontos médios parecem brilhantes |
| `oklab` | Linha reta por um espaço perceptual | A maioria das misturas e qualquer esbatido para branco, preto ou cinzento |
| `oklch` | À volta do círculo dos matizes com croma constante | Misturas vivas de vários matizes, arco-íris, pores do sol |
| `hsl` | À volta do círculo dos matizes, não perceptual | Círculos cromáticos; a luminosidade é irregular |

Os espaços que mais provavelmente vais usar. A [página color-interpolation-method da MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/color-interpolation-method) lista todos.

## oklab ou oklch: qual escolher

Ambos são perceptuais; diferem no caminho que fazem. O **Oklab** traça uma linha reta entre as duas cores, por isso o meio pode perder alguma saturação quando os extremos estão longe no círculo cromático, mas nunca passa por um matiz que não pediste. O **OKLCH** mantém o croma, a intensidade da cor, e percorre o círculo dos matizes, por isso o meio mantém-se saturado mas passa pelos matizes intermédios. Azul a amarelo em oklch passa por verde. Às vezes é esse o objetivo; outras vezes é uma surpresa.

- Rosa a verde-azulado, em oklab: `linear-gradient(90deg in oklab, #db2777, #0891b2)`
- Rosa a verde-azulado, em oklch: `linear-gradient(90deg in oklch, #db2777, #0891b2)`
- Índigo a branco, em oklab: `linear-gradient(90deg in oklab, #1e1b4b, #ffffff)`
- Violeta a laranja, em oklch: `linear-gradient(90deg in oklch, #7c3aed, #f97316)`

O oklab fica no caminho direto; o oklch varre os matizes entre os seus extremos: rosa a verde-azulado passa por violeta e azul, violeta a laranja por magenta e vermelho.

> **Esbater para branco, preto ou cinzento** As cores neutras não têm um matiz real, por isso uma mistura oklch para branco ou preto pode fazer um caminho estranho. Para esbater para um neutro, usa `in oklab`, ou escreve a ponta neutra como um quase neutro com o mesmo matiz da outra ponta, como `oklch(97% 0.02 290)`.

## Escolher a direção do matiz

Entre quaisquer dois matizes há duas maneiras de dar a volta ao círculo cromático. Por predefinição o oklch usa o `shorter hue`. Podes pedir `longer hue`, ou forçar uma direção com `increasing hue` ou `decreasing hue`. A palavra-chave vai logo a seguir ao espaço de cor.

- Vermelho a azul, shorter hue: `linear-gradient(90deg in oklch shorter hue, #ef4444, #3b82f6)`
- Vermelho a azul, longer hue: `linear-gradient(90deg in oklch longer hue, #ef4444, #3b82f6)`

O caminho curto do vermelho ao azul passa por magenta e violeta. O caminho longo passa por laranja, amarelo, verde e ciano.

O `longer hue` é a forma mais limpa de desenhar um espetro: duas paragens em vez de sete. É também como se faz um [gradiente arco-íris](https://gradiently.design/pt-pt/guide/rainbow-gradient) cujas cores parecem todas igualmente brilhantes, o que um arco-íris em sRGB nunca consegue bem.

## Escrever cores em oklch()

Também podes escrever as próprias paragens em OKLCH: `oklch(L C H)`, em que L é a luminosidade de 0% a 100%, C é o croma de 0 até cerca de 0,37 e H é o ângulo do matiz. Manter o L igual em todas as paragens dá um gradiente de luminosidade uniforme, o que é difícil de fazer a olho em hexadecimal. O [oklch.com](https://oklch.com) é um bom seletor para encontrar valores.

```css
.band {
  /* same lightness and chroma, only the hue changes */
  background: linear-gradient(
    90deg in oklch,
    oklch(68% 0.17 300),
    oklch(68% 0.17 20),
    oklch(68% 0.17 70)
  );
}
```

Violeta, passando por coral, até âmbar, com uma só luminosidade: nenhuma paragem salta à vista como mais brilhante do que as outras.

Luminosidade igual: violeta, coral, âmbar: `linear-gradient(90deg in oklch, oklch(68% 0.17 300), oklch(68% 0.17 20), oklch(68% 0.17 70))`

O código acima, desenhado. As cores fora da gama de um ecrã são mapeadas para a cor mais próxima que ele consegue mostrar.

## Suporte nos navegadores e reservas

Os métodos de interpolação e as cores `oklch()` são suportados nos atuais Chrome, Edge, Safari e Firefox. Os navegadores ignoram qualquer declaração que não consigam interpretar, por isso a reserva é simplesmente escrever primeiro a versão simples. Onde a linha melhorada for ignorada, o gradiente sRGB fica.

```css
.hero {
  background-color: #7c3aed;
  background-image: linear-gradient(135deg, #7c3aed, #f97316);
  background-image: linear-gradient(135deg in oklch, #7c3aed, #f97316);
}
```

Cor lisa, depois sRGB, depois oklch. Cada navegador fica com a última linha que compreende.

Se queres ir mais longe, as misturas perceptuais combinam bem com grão para evitar as [faixas nos gradientes](https://gradiently.design/pt-pt/guide/gradient-banding) e com as técnicas de paragens e dicas do guia sobre o [gradiente linear em CSS](https://gradiently.design/pt-pt/guide/css-linear-gradient).

## FAQ

### O que faz o in oklch num gradiente CSS?

Faz o navegador calcular as cores intermédias no espaço de cor OKLCH, o que mantém a luminosidade uniforme e as cores saturadas em vez de misturar por cinzento.

### Devo usar oklab ou oklch nos gradientes?

Usa oklch para misturas vivas entre matizes diferentes e oklab para esbatidos para branco, preto ou cinzento, ou quando não queres que a mistura passe por matizes extra.

### Porque é que o meu gradiente oklch passa por verde?

O OKLCH percorre o círculo dos matizes e, entre azul e amarelo, o caminho mais curto passa por verde. Usa `in oklab` para um caminho direto, ou acrescenta uma paragem intermédia.

### Preciso de escrever as cores em oklch() para usar a interpolação oklch?

Não. As cores hexadecimais funcionam bem com `in oklch`; só a mistura muda. Escrever as paragens em `oklch()` é útil quando queres controlar a luminosidade com precisão.

### O que acontece nos navegadores que não suportam in oklch?

Ignoram a declaração inteira. Põe um gradiente sRGB normal na linha anterior e esses navegadores ficam com esse.
