CSS e web

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

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.

GradientlyConta verificada do Gradiently··6 min de leitura
Capa: Cold Salon · GR·4AB2·SW

Resumindo

  • 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.
Nesta página

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 CSSlinear-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); }.

AtributoPadrãoO que faz
x1 y1 x2 y20 0 1 0, da esquerda para a direitaPontos inicial e final da linha do gradiente
gradientUnitsobjectBoundingBoxSe as coordenadas são relativas à forma ou ao desenho
spreadMethodpadO que acontece além das pontas: pad, reflect ou repeat
gradientTransformnenhumGira, escala ou inclina o gradiente, por exemplo rotate(30)
hrefnenhumHerda 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 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 CSSradial-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.

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

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 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.

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 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

Perguntas frequentes

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.

Compartilhar este guia

Escrito pelo GradientlyConta verificada do Gradiently

A equipe por trás do Gradiently, uma ferramenta de design criada em torno dos Marks: gradientes vivos que fazem tudo o que você cria ter a sua cara.

Ver nosso perfil