Filtros CSS en SVG

facebook-svg gplus-svg twitter-svg

Los filtros en CSS3 tienen su origen en SVG. En 2008 Robert O'Callahan ( Mozilla ) vio un gran potencial en aplicar filtros SVG a los elementos HTML mediante CSS. Para aplicar un filtro SVG a un elemento HTML utilizamos esta sintaxis:

.imagen{ filter: url(#hueRotate);}

donde #hueRotate representa el id del filtro SVG aplicado. Este filtro puede ser aplicado tanto a elementos HTML como a elementos SVG. Normalmente el elemento svg que contiene el filtro esta situado en el mismo documento.

A continuación viene una lista de filtros CSS y sus equivalentes en SVG:
- desenfoque ( blur ),
- brillo ( brightness ),
- contraste ( contrast ),
- sombra ( drop-shadow ), - escala de grises ( grayscale ),
- manipular el color ( hue-rotate ),
- negativo ( invert ),
- opacidad ( opacity ),
- saturación ( saturate ),
- sepia.

Desenfoque ( blur )

En CSS la función blur() aplica un desenfoque gaussiano al elemento, y toma como único parámetro el radio del blur en pixeles.

.elemento{ filter: blur(5px);}

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

<svg>
   <filter id="blur">
    <feGaussianBlur in="SourceGraphic" stdDeviation="5"/>
  </filter>
</svg>

Por favor observe que el valor de stdDeviation es 5, el mismo valor que habría utilizado para el filtro css blur

En este caso el CSS utilizado sería:

.elemento{ filter: url(#blur);}

donde #blur representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#blur)" . . . 
original
filter: blur(5px)
filter="url(#blur)"

Brillo ( brightness )

En CSS podemos modificar el brillo de un elemento HTML utilizando la función brightness(), que toma como único parámetro un número o un porcentaje. Si el valor de este parámetro es 1 ( o 100% ) la imagen queda sin cambiar. Si el valor es más pequeño que 1 la imagen aparece oscurecida. Si el valor es más grande la imagen aparece como iluminada.

.elemento{ filter: brightness(1.5);}

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

<svg color-interpolation-filters="sRGB">
  <filter id="brightness">
    <feComponentTransfer>
      <feFuncR type="linear" slope="1.5"/>
      <feFuncG type="linear" slope="1.5"/>
      <feFuncB type="linear" slope="1.5"/>
    </feComponentTransfer>
  </filter>
</svg>

Por favor observe que el valor de slope de los filtros primitivos feFuncX es 1.5, el mismo valor que habría utilizado para el filtro css brightness

En este caso el CSS utilizado sería:

.elemento{ filter: url(#brightness);}

donde #brightness representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#brightness)" . . . 
original
filter: brightness(2)
filter="url(#brightness)"

Contraste ( contrast )

El contraste representa la diferencia de luminosidad y/o color entre las áreas más claras y más oscuras de una imagen. En CSS podemos manipular el contraste de una imagen utilizando la función contrast(). Esta función toma como único parámetro un número o un porcentaje. Si el valor de este parámetro es 1 la imagen queda sin cambiar. Si el valor es más pequeño que 1 el contraste baja, produciendo una imagen completamente gris para filter:contrast(0). Para valores más grandes que 1 el contraste se acentúa.

.elemento{ filter: contrast(2);}

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

 <svg color-interpolation-filters="sRGB">
  <filter id="contrast">
    <feComponentTransfer>
      <feFuncR type="linear" slope="2" intercept="-.5"/>
      <!--slope="valor" intercept="-(0.5 * valor) + 0.5"-->
      <feFuncG type="linear" slope="2" intercept="-.5"/>
      <!--slope="valor" intercept="-(0.5 * valor) + 0.5"-->
      <feFuncB type="linear" slope="2" intercept="-.5"/>
      <!--slope="valor" intercept="-(0.5 * valor) + 0.5"-->
    </feComponentTransfer>
  </filter>
  </svg>

Por favor observe que el valor de slope de los filtros primitivos feFuncX es 2, el mismo valor que habría utilizado para el filtro css contrast. El valor del atributo intercept fue calculado utilizando esta fórmula: intercept="-(0.5 * valor) + 0.5". En este caso valor = 2.

En este caso el CSS utilizado sería:

.elemento{ filter: url(#contrast);}

donde #contrast representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#contrast)" . . . 
original
filter: contrast(2)
filter="url(#contrast)"

Sombra ( drop-shadow )

En CSS la función drop-shadow() aplica una sombra a la imagen teniendo en cuenta las zonas transparentes.

.elemento{ filter: drop-shadow(2px 3px 5px #000);}

donde 2px representa el desplazamiento horizontal; 3px representa el desplazamiento vertical; 5px representa el radio del desenfoque aplicado y #000 es el color de la sombra

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

<svg>
 <filter id="drop-shadow">
    <feGaussianBlur in="SourceAlpha" stdDeviation="5"/> 
    <!--stdDeviation="[radius]"-->
    <feOffset dx="2" dy="3" result="offsetblur"/> 
    <!--dx="[offset-x]" dy="[offset-y]"-->
    <feFlood flood-color="black"/> 
    <!--flood-color="[color]"-->
    <feComposite in2="offsetblur" operator="in"/>
    <feMerge>
      <feMergeNode/>
      <feMergeNode in="SourceGraphic"/>
    </feMerge>
  </filter>
</svg>

Por favor observe que
- el valor de stdDeviation del filtro primitivo <feGaussianBlur> es 5, o sea el mismo valor utilizado para el radio del desenfoque aplicado.
- el valor de dx del filtro primitivo <feOffset> es 2, o sea el mismo valor utilizado para el desplazamiento horizontal aplicado.
- el valor de dy del filtro primitivo <feFlood> es 3, o sea el mismo valor utilizado para el desplazamiento vertical aplicado.
- el valor de flood-color del filtro primitivo <feOffset> es black, el mismo valor utilizado para el color de la sombra.

En este caso el CSS utilizado sería:

.elemento{ filter: url(#drop-shadow);}

donde #drop-shadow representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#drop-shadow)" . . . 
original
filter: drop-shadow()
filter="url(#drop-shadow)"

Escala de grises ( grayscale )

En CSS la función grayscale() toma como único parámetro un número de 0 a 1 o un porcentaje. Si el parámetro es 1 o 100% la imagen aparece en blanco y negro.

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

<svg>
<filter id="grayscale">
    <feColorMatrix type="matrix" 
               values="0.2126 0.7152 0.0722 0 0
                       0.2126 0.7152 0.0722 0 0
                       0.2126 0.7152 0.0722 0 0
                       0      0      0      1 0">  
  </feColorMatrix>
  </filter>
</svg>

En este caso el CSS utilizado sería:

.elemento{ filter: url(#grayscale);}

donde #grayscale representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#grayscale)" . . . 
original
filter: grayscale(1);
filter="url(#grayscale)"

Una solución alternativa sería utilizar feColorMatrix type="saturate" con una saturación entre 0 y 1. Si lo que queremos conseguir es identico a filter: grayscale(.7) el valor del atributo values de feColorMatrix tendría que ser igual a 1 - .7 = .3.

<svg>
<filter id="saturate05">
    <feColorMatrix type="saturate" in="SourceGraphic" values="0.3"/>
</filter>  
</svg>
original
filter: grayscale(.7);
filter="url(#grayscale)"

Manipular el color ( hue-rotate )

El filtro CSS hue-rotate() se utiliza para manipular el color de cada pixel de una imagen girando ( de 0 a 360 grados ) el valor del matiz ( hue ) de un color hsl

.elemento{ filter: hue-rotate(270deg); }

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

 <svg color-interpolation-filters="sRGB">
  <filter id="hueRotate">
    <feColorMatrix type="hueRotate" values="270" />
  </filter>
</svg>

Por favor observe que el valor del atributo type es hueRotate y el valor del atributo values es igual al número de grados del filtro CSS ( 270 ).

En este caso el CSS utilizado sería:

.elemento{ filter: url(#hueRotate);}

donde #hueRotate representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#hueRotate)" . . . 
original
filter: hue-rotate(270deg)
filter="url(#hueRotate)"

El negativo ( invert )

Podemos conseguir la "inversa" o la "negativa" de una imagen, utilizando filtros CSS y la función invert().

.elemento{ filter: invert(); }

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

<svg color-interpolation-filters="sRGB">
<filter id="invert">
    <feComponentTransfer>
       <feFuncR type="table" tableValues="1 0"/>
       <feFuncG type="table" tableValues="1 0"/>
       <feFuncB type="table" tableValues="1 0"/>
</feComponentTransfer>
</filter>
</svg>

En este caso el CSS utilizado sería:

.elemento{ filter: url(#invert);}

donde #invert representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#invert)" . . . 
original
filter: invert()
filter="url(#invert)"

Opacidad ( opacity )

En CSS podemos cambiar la opacidad de los elementos HTML utilizando filtro CSS y la función opacity().

.elemento{filter:opacity(.5);}

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

<svg color-interpolation-filters="sRGB">
<filter id="opacity">
    <feComponentTransfer>
       <feFuncA type="table" tableValues="0 0.5"/>
    </feComponentTransfer>
</filter>
</svg>	

En este caso el CSS utilizado sería:

.elemento{ filter: url(#opacity);}

donde #opacity representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#opacity)" . . . 
original
filter: opacity(.5)
filter="url(#opacity)"

Saturación ( saturate )

En CSS la función saturate() se utiliza para intensificar los colores de una imagen.

.elemento{filter:saturate(2);}

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

<svg color-interpolation-filters="sRGB">
<filter id="saturate">
    <feColorMatrix type="saturate" values="2"/>
 </filter>
</svg>

Por favor observe que el valor del atributo type es saturate y el valor del atributo values es igual al valor utilizado en el filtro CSS ( 2 en este caso ).

En este caso el CSS utilizado sería:

.elemento{ filter: url(#saturate);}

donde #saturate representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#saturate)" . . . 
original
filter: saturate(2)
filter="url(#saturate)"

Sepia

En CSS podemos convertir una imagen a tonos de sepia utilizando la función sepia()

.elemento{filter:sepia(1);}

Podemos conseguir el mismo efecto utilizando el siguiente filtro SVG:

<svg viewBox="0 0 220 205.6" color-interpolation-filters="sRGB">
    <filter id="sepia">
    <feColorMatrix type="matrix" values="0.393 0.769 0.189 0 0
                                         0.349 0.686 0.168 0 0
                                         0.272 0.534 0.131 0 0
                                         0     0     0     1 0"/>
 </filter>
</svg>

En este caso el CSS utilizado sería:

.elemento{ filter: url(#sepia);}

donde #sepia representa el id del filtro utilizado.

Podemos hacer lo mismo en SVG si utilizamos el atributo presentacional filter:

<image filter="url(#sepia)" . . . 
original
filter: sepia(1)
filter="url(#sepia)"

Puede ver todos estos ejemplos en Codepen:

See the Pen SVG filters equivalents*** by Gabi (@enxaneta) on CodePen.

Enlaces útiles

MDN: