W3docs

Sombras Projetadas SVG

Aprenda sobre sombras projetadas, os elementos <defs> e <filter>. Veja exemplos de <feOffset>, <feGaussianBlur> e <feColorMatrix> em SVG.

Uma sombra projetada faz uma forma SVG parecer flutuar acima da página ao pintar uma cópia desfocada e deslocada da forma atrás dela. Em SVG, esse efeito é construído a partir de primitivos de filtro de baixo nível — pequenos blocos de construção como desfoque e deslocamento que você encadeia dentro de um elemento <filter>.

Quando usar filtros SVG versus CSS

Existem três maneiras de adicionar uma sombra, e elas não são intercambiáveis:

  • box-shadow (CSS) — funciona na caixa retangular de um elemento HTML/CSS. Ela não segue a forma de caminhos SVG, portanto, um triângulo ainda recebe uma sombra retangular. Ideal para caixas, cartões e botões.
  • filter: drop-shadow() (CSS) — segue a forma pintada real (incluindo caminhos SVG e PNGs transparentes). É a maneira mais rápida de adicionar sombra a um SVG a partir de uma folha de estilos e tem amplo suporte. Use quando precisar apenas de uma sombra sem controle fino.
  • SVG <filter> (este capítulo) — a opção mais poderosa. Você controla cada etapa (distância do deslocamento, raio de desfoque, cor da sombra, modo de mesclagem) e pode combinar vários primitivos. Use quando precisar de uma sombra colorida, uma sombra interna ou qualquer efeito além de um desfoque simples.

Este capítulo aborda a abordagem com <filter> SVG. Para outros efeitos de filtro, consulte Efeitos de Desfoque SVG e a Introdução aos Filtros SVG.

Descrição dos filtros SVG

Todos os filtros SVG são definidos dentro de um elemento <defs>. O elemento <defs> é uma forma abreviada de definitions (definições). Ele contém a definição de elementos específicos, como filtros. O elemento <filter> define um filtro SVG. Este elemento possui um atributo id (obrigatório) que identifica o filtro, o qual você referencia a partir de uma forma com filter="url(#id)".

Primitivos de filtro e entradas

Cada primitivo lê uma imagem de entrada e grava uma imagem de saída. Duas entradas especiais estão integradas:

  • SourceGraphic — a forma original com todas as suas cores.
  • SourceAlpha — a mesma forma, mas usando apenas seu canal alpha (opacidade), de modo que resulta em uma silhueta preta sólida. Este é o ponto de partida usual para uma sombra, pois uma sombra deve ser uma cópia escura da forma, não uma cópia recolorida.

Você conecta os primitivos com dois atributos:

  • in — qual imagem este primitivo lê (por exemplo, SourceAlpha ou um nome de result de um primitivo anterior).
  • result — um nome que você atribui à saída deste primitivo para que um primitivo posterior possa lê-la.

Os primitivos usados neste capítulo:

  • <feOffset> — desloca uma imagem por dx (horizontal) e dy (vertical). Isso posiciona a sombra afastada da forma.
  • <feGaussianBlur> — desfoca uma imagem. Seu atributo stdDeviation define o raio de desfoque: valores maiores produzem uma sombra mais suave e ampla.
  • <feColorMatrix> — transforma os valores RGBA de cada pixel, que é como você tinta uma sombra com uma cor personalizada.
  • <feBlend> / <feMerge> — combinam duas imagens. <feBlend> empilha duas entradas (in e in2) usando um mode como normal; <feMerge> camada qualquer número de entradas em ordem. Ambos são usados aqui para pintar o gráfico original sobre a sombra finalizada.

Para criar sombras projetadas, use o elemento <feOffset>. Você tira uma cópia do gráfico SVG, move-a no plano xy, depois a desfoca e então desenha o original por cima.

Exemplo do elemento SVG <feOffset>:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <svg width="150" height="150">
      <defs>
        <filter id="filter" x="0" y="0" width="150%" height="150%">
          <feOffset result="offOut" in="SourceGraphic" dx="30" dy="30" />
          <feBlend in="SourceGraphic" in2="offOut" mode="normal" />
        </filter>
      </defs>
      <rect width="110" height="110" stroke="purple" stroke-width="5" fill="pink" 
            filter="url(#filter)" /> 
      Sorry, your browser doesn't support inline SVG.
    </svg>
  </body>
</html>

No exemplo acima, o atributo id do elemento <filter> especifica um nome único para o filtro, e o atributo filter do elemento <rect> vincula o retângulo a esse filtro. <feOffset> copia SourceGraphic e move-o 30px para a direita e 30px para baixo (dx="30" dy="30"), salvando o resultado como offOut. <feBlend> então desenha o SourceGraphic original sobre offOut, de modo que você vê a forma com uma cópia deslocada de bordas nítidas atrás dela.

Exemplo do elemento SVG <feGaussianBlur>:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <svg width="200" height="200">
      <defs>
        <filter id="filter" x="0" y="0" width="250%" height="250%">
          <feOffset result="offOut" in="SourceGraphic" dx="30" dy="30" />
          <feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
          <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
        </filter>
      </defs>
      <rect width="150" height="150" stroke="coral" stroke-width="5" fill="pink" 
            filter="url(#filter)" /> 
      Sorry, your browser doesn't support inline SVG.
    </svg>
  </body>
</html>

Aqui, a cópia deslocada é desfocada com o elemento <feGaussianBlur>. Seu atributo stdDeviation especifica a quantidade de desfoque — aumente-o para uma sombra mais suave, diminua-o para uma sombra mais nítida. Como a entrada ainda é SourceGraphic, a cópia desfocada mantém as cores da forma, o que geralmente não é como uma sombra real se parece. O próximo exemplo corrige isso.

Exemplo de sombra preta (silhueta) com SourceAlpha:

Para tornar a sombra uma silhueta escura em vez de um clone desfocado da forma colorida, alimente <feOffset> com a entrada SourceAlpha em vez de SourceGraphic. SourceAlpha carrega apenas opacidade, portanto a cópia deslocada e desfocada resulta em preto sólido — exatamente como uma sombra deve ser.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <svg height="200" width="200">
      <defs>
        <filter id="filter" x="0" y="0" width="150%" height="150%">
          <feOffset result="offOut" in="SourceAlpha" dx="15" dy="15" />
          <feGaussianBlur result="blurOut" in="offOut" stdDeviation="8" />
          <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
        </filter>
      </defs>
      <rect width="120" height="120" stroke="purple" stroke-width="5" fill="pink" 
            filter="url(#filter)" /> 
       Sorry, your browser doesn't support inline SVG.
    </svg>
  </body>
</html>

Para tingir a sombra com uma cor personalizada, use o elemento <feColorMatrix>. Ele multiplica os valores de vermelho, verde, azul e alpha de cada pixel pelos números que você fornece, permitindo escurecer ou recolorir a cópia deslocada antes de desfocá-la.

Exemplo de coloração da sombra com <feColorMatrix>:

Na matriz abaixo, os canais vermelho, verde e azul são cada um escalado para 0.2 (os três primeiros valores diagonais), o que escurece a cópia deslocada para uma cor tênue, enquanto o canal alpha permanece em 1 (o quarto valor diagonal) para que a sombra mantenha a opacidade da forma. Altere os três valores 0.2 para tingir a sombra — por exemplo, um valor mais alto de vermelho produz uma sombra avermelhada.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <svg height="200" width="200">
      <defs>
        <filter id="filter" x="0" y="0" width="150%" height="150%">
          <feOffset result="offOut" in="SourceGraphic" dx="25" dy="25" />
          <feColorMatrix result="matrixOut" in="offOut" type="matrix" 
                         values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" />
          <feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="9" />
          <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
        </filter>
      </defs>
      <rect width="150" height="150" stroke="purple" stroke-width="5" fill="lightblue" 
            filter="url(#filter)" /> 
       Sorry, your browser doesn't support inline SVG.
    </svg>
  </body>
</html>

O atalho <feDropShadow>

Encadear <feOffset>, <feGaussianBlur> e <feBlend> é verboso para um efeito tão comum. O primitivo <feDropShadow> agrupa os três em um único elemento e é suportado nos navegadores modernos. Você define o deslocamento com dx / dy, a suavidade com stdDeviation e a cor com flood-color (e opcionalmente flood-opacity).

Exemplo do elemento SVG <feDropShadow>:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <svg height="200" width="200">
      <defs>
        <filter id="shadow" x="-20%" y="-20%" width="150%" height="150%">
          <feDropShadow dx="15" dy="15" stdDeviation="8" flood-color="purple" flood-opacity="0.5" />
        </filter>
      </defs>
      <rect width="120" height="120" stroke="purple" stroke-width="5" fill="pink" 
            filter="url(#shadow)" /> 
      Sorry, your browser doesn't support inline SVG.
    </svg>
  </body>
</html>

Isso produz o mesmo tipo de resultado que os exemplos com múltiplos primitivos acima, mas com uma única linha.

Capítulos SVG relacionados

Prática

Prática
Qual entrada de filtro SVG você deve usar em 'feOffset' para criar uma sombra de silhueta preta em vez de uma cópia recolorida da forma?
Qual entrada de filtro SVG você deve usar em 'feOffset' para criar uma sombra de silhueta preta em vez de uma cópia recolorida da forma?
Was this page helpful?