# Gradientes SVG: linear, radial, traços, texto e máscaras

[Canonical HTML page](https://gradiently.design/pt-br/guide/svg-gradients)

O SVG tem seu próprio sistema de gradientes, mais antigo que os gradientes CSS e capaz de coisas que eles não fazem: colorir um traço, preencher uma palavra, compartilhar um gradiente entre várias formas e esmaecer qualquer coisa com uma máscara.

## The short version

- Um gradiente SVG é definido uma vez como um elemento linearGradient ou radialGradient com filhos stop, recebe um id e é aplicado com fill ou stroke definido como url(#id).
- Por padrão, as coordenadas de um gradiente SVG usam unidades objectBoundingBox, em que 0 e 1 são as bordas da forma que está sendo pintada.
- gradientUnits="userSpaceOnUse" posiciona o gradiente nas coordenadas do próprio desenho, o que permite que um gradiente atravesse várias formas e corrige gradientes em linhas perfeitamente retas.
- spreadMethod decide o que acontece além das pontas do gradiente: pad mantém as cores das pontas, reflect espelha a transição e repeat a reinicia.
- Uma máscara SVG usa o brilho, então um gradiente de branco a preto dentro de uma máscara esmaece aquilo em que ela é aplicada.

Um **gradiente SVG** é uma tinta que você define uma vez e aplica a qualquer forma, linha ou trecho de texto em um SVG. Você escreve um elemento `<linearGradient>` ou `<radialGradient>` dentro de `<defs>`, dá a ele filhos `<stop>` para as cores e um `id`, e então define o `fill` ou o `stroke` de uma forma como `url(#id)`. Diferente de um fundo em CSS, ele pode colorir um traço ou uma única palavra, e escala junto com o desenho.

```html
<svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="dusk" x1="0" y1="0" x2="1" y2="1">
      <stop offset="0" stop-color="#1e1b4b" />
      <stop offset="0.55" stop-color="#7c3aed" />
      <stop offset="1" stop-color="#f472b6" />
    </linearGradient>
  </defs>
  <rect width="200" height="120" rx="16" fill="url(#dusk)" />
</svg>
```

Um gradiente diagonal em um retângulo arredondado. x1, y1, x2 e y2 traçam a linha do gradiente do canto superior esquerdo ao inferior direito.

A mesma transição, em CSS: `linear-gradient(135deg, #1e1b4b 0%, #7c3aed 55%, #f472b6 100%)`

O SVG acima e este gradiente CSS coincidem em um quadrado. Em um retângulo, a versão SVG se estica com a forma; veja gradientUnits abaixo.

## linearGradient e suas paradas

`x1`, `y1`, `x2` e `y2` definem o início e o fim da linha do gradiente. Cada `<stop>` recebe um `offset` de 0 a 1 (ou de 0% a 100%), um `stop-color` e um `stop-opacity` opcional. `stop-color` também é uma propriedade CSS, então você pode tematizar gradientes a partir de uma folha de estilo, por exemplo `stop { stop-color: var(--accent); }`.

| Atributo | Padrão | O que faz |
| --- | --- | --- |
| `x1 y1 x2 y2` | `0 0 1 0`, da esquerda para a direita | Pontos inicial e final da linha do gradiente |
| `gradientUnits` | `objectBoundingBox` | Se as coordenadas são relativas à forma ou ao desenho |
| `spreadMethod` | `pad` | O que acontece além das pontas: `pad`, `reflect` ou `repeat` |
| `gradientTransform` | nenhum | Gira, escala ou inclina o gradiente, por exemplo `rotate(30)` |
| `href` | nenhum | Herda paradas e configurações de outro gradiente |

Os principais atributos de linearGradient. radialGradient compartilha todos, menos a primeira linha.

`href` evita repetição. Defina suas paradas uma vez em um gradiente base e crie variações que apontam para ele e mudam só a direção ou as unidades. A [referência de linearGradient na MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/linearGradient) cobre todos os atributos.

## radialGradient: centro, raio e ponto focal

Um gradiente radial recebe um centro (`cx`, `cy`) e um raio (`r`), todos com padrão 0.5, então preenche a forma a partir do meio. Ele também tem algo que o CSS não tem: um ponto focal separado (`fx`, `fy`), onde a primeira cor começa. Tirar o ponto focal do centro faz uma esfera parecer iluminada de um lado.

```html
<radialGradient id="orb" cx="0.5" cy="0.5" r="0.5" fx="0.32" fy="0.28">
  <stop offset="0" stop-color="#e0f2fe" />
  <stop offset="0.45" stop-color="#0ea5e9" />
  <stop offset="1" stop-color="#082f49" />
</radialGradient>

<circle cx="60" cy="60" r="50" fill="url(#orb)" />
```

Um ponto focal acima e à esquerda transforma um círculo chapado em uma esfera brilhante.

Esfera iluminada, aproximada em CSS: `radial-gradient(circle at 32% 28%, #e0f2fe, #0ea5e9 35%, #082f49 80%)`

O CSS consegue mover o centro, mas não separar centro e foco, então isto é só uma aproximação da esfera em SVG. Compare com [gradientes radiais em CSS](https://gradiently.design/pt-br/guide/css-radial-gradient).

## gradientUnits: objectBoundingBox ou userSpaceOnUse

Com o padrão `objectBoundingBox`, 0 e 1 significam as bordas da forma que está sendo pintada, então cada forma recebe o gradiente inteiro, esticado para caber. Com `userSpaceOnUse`, as coordenadas estão nas unidades do próprio SVG, então o gradiente fica parado e as formas revelam a parte dele que cobrem. É assim que uma fileira de barras pode compartilhar um gradiente contínuo.

### objectBoundingBox

- Coordenadas de 0 a 1 em cada forma
- Cada forma mostra o gradiente inteiro
- O gradiente se estica com as proporções da forma
- Falha em uma linha perfeitamente horizontal ou vertical

### userSpaceOnUse

- Coordenadas nas unidades do próprio desenho
- As formas revelam sua fatia de um único gradiente
- Os ângulos se mantêm fiéis em qualquer forma
- Funciona em linhas retas e traços finos

> **A linha reta invisível** Uma `<line>` horizontal tem uma caixa delimitadora de altura zero, e unidades de caixa delimitadora não podem ser calculadas a partir de zero, então um traço com gradiente padrão nela não renderiza nada. Defina `gradientUnits="userSpaceOnUse"` e informe coordenadas reais.

## Gradientes em traços e texto

`stroke="url(#id)"` pinta contornos, e é assim que se desenham ícones com gradiente, anéis de progresso e linhas de gráfico. Em `<text>`, `fill="url(#id)"` colore as letras, e as palavras continuam selecionáveis e pesquisáveis. Acrescente uma cor chapada depois da URL, como `fill="url(#dusk) #7c3aed"`, e ela é usada se o gradiente não for encontrado.

```html
<svg viewBox="0 0 320 120" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="line" gradientUnits="userSpaceOnUse" x1="20" y1="0" x2="300" y2="0">
      <stop offset="0" stop-color="#22d3ee" />
      <stop offset="1" stop-color="#a855f7" />
    </linearGradient>
  </defs>
  <path d="M20 90 C 90 20, 160 110, 300 30" fill="none" stroke="url(#line)" stroke-width="6" stroke-linecap="round" />
  <text x="20" y="115" font-size="20" font-weight="700" fill="url(#line) #7c3aed">Growth</text>
</svg>
```

Um gradiente em unidades do desenho, compartilhado por uma curva e uma palavra. Os dois vão do ciano ao roxo na mesma extensão horizontal.

Para letras com gradiente em HTML, e não em SVG, [texto com gradiente em CSS](https://gradiently.design/pt-br/guide/css-gradient-text) costuma ser mais simples. Recorra ao texto em SVG quando as palavras fazem parte de uma ilustração ou de um logo, ou precisam seguir um caminho.

## spreadMethod: pad, reflect e repeat

Quando a linha do gradiente é mais curta que a forma, `spreadMethod` decide o que preenche o resto. `pad` mantém as cores das pontas, `reflect` espelha a transição de um lado para o outro e `repeat` a recomeça com uma borda seca. Aqui, cada gradiente vai de 30% a 70% da largura.

- pad: `linear-gradient(90deg, #0f766e 30%, #fde68a 70%)`
- reflect: `repeating-linear-gradient(90deg, #fde68a -10%, #0f766e 30%, #fde68a 70%)`
- repeat: `repeating-linear-gradient(90deg, #0f766e 30%, #fde68a 70%)`

Verde-azulado a areia com os três métodos de extensão, reproduzidos em CSS para você comparar lado a lado.

## Fades com máscaras SVG

Uma máscara usa o brilho: áreas brancas mostram o que é mascarado, áreas pretas escondem, e os cinzas ficam no meio. Então um gradiente de branco a preto dentro de uma `<mask>` esmaece qualquer forma ou imagem suavemente até sumir, e é assim que você suaviza a borda de uma foto ou faz a linha de um gráfico surgir aos poucos no início.

```html
<defs>
  <linearGradient id="fade" x1="0" y1="0" x2="0" y2="1">
    <stop offset="0.4" stop-color="#fff" />
    <stop offset="1" stop-color="#000" />
  </linearGradient>
  <mask id="soft-bottom">
    <rect width="100%" height="100%" fill="url(#fade)" />
  </mask>
</defs>

<image href="photo.jpg" width="100%" height="100%" mask="url(#soft-bottom)" />
```

A foto fica totalmente visível no topo e esmaece ao longo dos 60% inferiores.

Para elementos HTML, o CSS `mask-image: linear-gradient(#000 40%, transparent)` faz o mesmo trabalho, usando alfa em vez de brilho. A técnica de máscara também está por trás das [bordas com gradiente em CSS](https://gradiently.design/pt-br/guide/css-gradient-border) transparentes.

### Evite

- Reutilizar o mesmo `id` de gradiente em dois SVGs inline na mesma página
- Esconder um sprite de definições de gradiente com `display: none`
- Unidades padrão em linhas retas
- Gradientes muito longos, lisos e escuros, sem textura

### Faça

- Ids únicos ou um sprite de definições compartilhado
- Esconda sprites com largura e altura zero
- `userSpaceOnUse` para traços e gradientes compartilhados
- Adicione grão a fades grandes, veja [textura de ruído em CSS](https://gradiently.design/pt-br/guide/css-noise-texture)

## FAQ

### Como adiciono um gradiente a um SVG?

Defina um `<linearGradient>` ou `<radialGradient>` com filhos `<stop>` e um `id` dentro de `<defs>`, e então defina o `fill` ou o `stroke` de uma forma como `url(#id)`.

### Por que o traço com gradiente do meu SVG não aparece em uma linha?

Uma linha reta horizontal ou vertical tem uma caixa delimitadora de tamanho zero, então as unidades padrão `objectBoundingBox` falham. Use `gradientUnits="userSpaceOnUse"` com coordenadas reais.

### Como giro um gradiente SVG?

Mude `x1`, `y1`, `x2` e `y2`, ou adicione `gradientTransform="rotate(45 0.5 0.5)"` para girar em torno do centro da caixa delimitadora.

### Posso mudar as cores de um gradiente SVG com CSS?

Sim. `stop-color` e `stop-opacity` são propriedades CSS, então regras como `stop { stop-color: var(--accent); }` funcionam em SVG inline.

### Por que meu gradiente SVG sumiu quando escondi o SVG?

Definições dentro de um SVG com `display: none` podem não ser renderizadas. Esconda o sprite com largura e altura zero, ou com posicionamento absoluto.
