W3docs

Ombre SVG

Scopri le ombre, gli elementi <defs> e <filter>. Esempi degli elementi SVG <feOffset>, <feGaussianBlur> e <feColorMatrix>.

Un'ombra fa sembrare che una forma SVG galleggi sopra la pagina, disegnando una copia sfocata e spostata della forma dietro di essa. In SVG questo effetto si costruisce con primitive di filtro — piccoli mattoni come sfocatura e spostamento che si concatenano all'interno di un elemento <filter>.

Quando usare i filtri SVG rispetto a CSS

Esistono tre modi per aggiungere un'ombra, e non sono intercambiabili:

  • box-shadow (CSS) — agisce sul rettangolo di delimitazione di un elemento HTML/CSS. Non segue la forma dei percorsi SVG, quindi un triangolo ottiene comunque un'ombra rettangolare. Ideale per riquadri, schede e pulsanti.
  • filter: drop-shadow() (CSS) — segue la forma effettivamente disegnata (inclusi i percorsi SVG e le PNG trasparenti). È il modo più rapido per applicare un'ombra a un SVG tramite foglio di stile ed è ampiamente supportato. Usalo quando hai bisogno di un'ombra semplice senza controllo fine.
  • SVG <filter> (questo capitolo) — l'opzione più potente. Puoi controllare ogni passaggio (distanza di spostamento, raggio di sfocatura, colore dell'ombra, modalità di fusione) e combinare più primitive. Usalo quando hai bisogno di un'ombra colorata, un'ombra interna o qualsiasi effetto oltre una semplice sfocatura.

Questo capitolo illustra l'approccio con <filter> SVG. Per altri effetti di filtro, consulta Effetti di sfocatura SVG e l'Introduzione ai filtri SVG.

Descrizione dei filtri SVG

Tutti i filtri SVG sono definiti all'interno di un elemento <defs>. L'elemento <defs> è una forma abbreviata di definitions (definizioni). Contiene la definizione di elementi specifici come i filtri. L'elemento <filter> definisce un filtro SVG. Questo elemento ha un attributo id (obbligatorio) che identifica il filtro, a cui poi si fa riferimento da una forma con filter="url(#id)".

Primitive di filtro e input

Ogni primitiva legge un'immagine di input e scrive un'immagine di output. Due input speciali sono integrati:

  • SourceGraphic — la forma originale con tutti i suoi colori.
  • SourceAlpha — la stessa forma ma che utilizza solo il canale alpha (opacità), quindi appare come una sagoma nera solida. Questo è il punto di partenza abituale per un'ombra, perché un'ombra dovrebbe essere una copia scura della forma, non una copia ricolorata.

Le primitive si collegano tra loro con due attributi:

  • in — quale immagine legge questa primitiva (es. SourceAlpha, o un nome result di una primitiva precedente).
  • result — un nome che assegni all'output di questa primitiva in modo che una primitiva successiva possa leggerlo.

Le primitive usate in questo capitolo:

  • <feOffset> — sposta un'immagine di dx (orizzontale) e dy (verticale). Posiziona l'ombra lontano dalla forma.
  • <feGaussianBlur> — sfoca un'immagine. Il suo attributo stdDeviation imposta il raggio di sfocatura: valori più grandi producono un'ombra più morbida e diffusa.
  • <feColorMatrix> — trasforma i valori RGBA di ogni pixel, permettendo di tingere l'ombra di un colore personalizzato.
  • <feBlend> / <feMerge> — combinano due immagini. <feBlend> sovrappone due input (in e in2) usando una mode come normal; <feMerge> sovrappone un numero qualsiasi di input in ordine. Entrambi vengono usati qui per disegnare la grafica originale sopra l'ombra completata.

Per creare ombre, si usa l'elemento <feOffset>. Si prende una copia della grafica SVG, la si sposta nel piano xy, la si sfoca, e poi si disegna l'originale sopra.

Esempio dell'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>

Nell'esempio sopra, l'attributo id dell'elemento <filter> specifica un nome univoco per il filtro, e l'attributo filter dell'elemento <rect> collega il rettangolo a quel filtro. <feOffset> copia SourceGraphic e lo sposta di 30px a destra e 30px verso il basso (dx="30" dy="30"), salvando il risultato come offOut. <feBlend> disegna poi il SourceGraphic originale sopra offOut, così si vede la forma con una copia spostata a bordi netti dietro di essa.

Esempio dell'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>

Qui la copia spostata viene sfocata con l'elemento <feGaussianBlur>. Il suo attributo stdDeviation specifica l'intensità della sfocatura — aumentalo per un'ombra più morbida, riducilo per una più nitida. Poiché l'input è ancora SourceGraphic, la copia sfocata mantiene i colori della forma, il che di solito non è realistico per un'ombra. L'esempio successivo risolve questo problema.

Esempio di ombra nera (sagoma) con SourceAlpha:

Per rendere l'ombra una sagoma scura invece di un clone sfocato della forma colorata, bisogna passare a <feOffset> l'input SourceAlpha invece di SourceGraphic. SourceAlpha contiene solo l'opacità, quindi la copia spostata e sfocata appare nera solida — esattamente come deve essere un'ombra.

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

Per tingere l'ombra di un colore personalizzato, si usa l'elemento <feColorMatrix>. Moltiplica i valori rosso, verde, blu e alpha di ogni pixel per i numeri forniti, permettendo di scurire o ricolorare la copia spostata prima di sfocarla.

Esempio di colorazione dell'ombra con <feColorMatrix>:

Nella matrice seguente, i canali rosso, verde e blu sono scalati ciascuno a 0.2 (i primi tre valori diagonali), il che scurisce la copia spostata verso un colore tenue, mentre il canale alpha rimane a 1 (il quarto valore diagonale) in modo che l'ombra mantenga l'opacità della forma. Modifica i tre valori 0.2 per tingere l'ombra — per esempio, un valore rosso più alto produce un'ombra rossastra.

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

La scorciatoia <feDropShadow>

Concatenare <feOffset>, <feGaussianBlur> e <feBlend> è prolisso per un effetto così comune. La primitiva <feDropShadow> raggruppa tutti e tre in un unico elemento ed è supportata dai browser moderni. Si imposta lo spostamento con dx / dy, la morbidezza con stdDeviation e il colore con flood-color (e opzionalmente flood-opacity).

Esempio dell'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>

Questo produce lo stesso tipo di risultato degli esempi con più primitive, ma con una singola riga.

Capitoli SVG correlati

Esercizio

Pratica
Quale input del filtro SVG bisogna passare a 'feOffset' per ottenere un'ombra sagoma nera invece di una copia ricolorata della forma?
Quale input del filtro SVG bisogna passare a 'feOffset' per ottenere un'ombra sagoma nera invece di una copia ricolorata della forma?
Was this page helpful?