Filtros CSS para todos: La propiedad filter con keywords y sus filtros SVG equivalentes

La propiedad Css filter y las dos formas de uso: mediante palabra clave y usando rutas a filtros SVG equivalentes a las keywords. Las diferencias y posibilidades de ambas.

Filtros CSS para todos: La propiedad filter con keywords y sus filtros SVG equivalentes

Por Kseso ✎ 4

La especificación Css que desarrolla los conocidos como filtros Css es el documento Filter Effects Module Level 1. Sobre el mismo ya hay varios post en este blog, entre otros el que publiqué allá por Mayo de 2012 "Photoshop en los estilos: Introducción a los Filtros Css. Css filter y animation".

En él tienes una introducción a cada uno de los filtros Css y as palabras claves y valores que admite cada uno de ellos.

Esta forma de uso (palabras clave o keywords) es quizás la forma más sencilla de uso. Pero no es la única. Tampoco la más soportada por los navegadores ni la que más juego da (potencia y diversidad de resultados).

Junto a ella, la documentación recoge la posibilidad de aplicar filtros SVG. Y sobre esta forma (y sus equivalentes a las keywords) es sobre lo que va el artículo.

Imagen de Marilyn Monroe con filtros Css y SVG
Custom filters: Filtros Css y SVG personalizados

Más concretamente, el filtro SVG equivalente a cada una de las palabras clave utilizadas. Pero de entrada recordemos la forma de declarar los filtros en Css, ya sea de una forma u otra.

Filtros Css con palabra clave

Es la forma más "sencilla". Sólo hay que recordar su nombre en inglés y elegir un valor entre el rango admitido para dicho filtro:

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

Su soporte, como puedes ver en canIuse no es casi total. Y aquellos que lo hacen requieren de prefijos privativos. Nota que el soporte parcial que le asigna a Firefox no es a esta forma, sino mediante rutas a SVG´s que vemos a continuación.

Soporte a los filtros Css por palabra clave
2016: Soporte a los filtros Css por palabra clave

Filtros Css con ruta a filtro SVG

La otra forma de aplicar filtros mediante Css es utilizar en su valor, en vez de la palabra, una ruta al SVG correspondiente.

No tan directo y sencillo como el método anterior (en el que navegador ya "tiene" en su programación los valores). Ahora somos nosotros quienes debemos haber "creado" el filtro SVG correspondiente.

El equivalente al código anterior sería el siguiente:

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

Y como ocurre con cualquier recurso utilizado en Css que se incluyen indicando una ruta, como las imágenes o archivos tipográficos, debe existir dicho recurso en la ruta indicada. En este caso, el valor de url() debe ser un SVG declarado y que realice la función deseada para el filtro.

<svg class='hide' xmlns="http://www.w3.org/2000/svg"> <filter id='svg-blur'> <feGaussianBlur stdDeviation='3' /> </filter> </svg>

Donde el valor de stdDeviation será el aplicado al elemento. Nota: no todos los filtros SVG son tan sencillos y a ellos iré a continuación.

Pese a ello, merece la pena tomarse el trabajo porque su soporte es mucho mayor. Ramén de la versatilidad de esta forma en alguno de los filtros y de la diferencia en el resultado final.

Soporte a los filtros Css usando SVG´s
2016 Soporte a los filtros Css usando SVG´s

Y ahora sí, vamos con cada uno de los filtros Css. En cada uno de ellos tendrás la imagen original y a su lado la misma con uno y otro filtro aplicado para que veas (en función de tu navegador) su efecto. Bajo ellas el código usado y el filtro SVG correspondiente.

Filtro Blur

See the Pen Filtro Blur by Kseso (@Kseso) on CodePen.

Ver demo a Full

En el caso del filtro Blur todo se reduce al valor declarado en stdDeviation. Es sencillo en su uso y manejo.

.blur {filter: blur(3px);} .svg-blur {filter: url(#svg-blur);} <!--SVG BLUR--> <svg class='hide' xmlns="http://www.w3.org/2000/svg"> <filter id='svg-blur'> <feGaussianBlur stdDeviation='3' /> </filter> </svg>

En puridad el atributo stdDeviation admite dos valores separados por comas. El primero para el desfase horizontal y el segundo para el vertical. En caso de declararse sólo uno, como en el código anterior, lo aplica a ambos.

See the Pen Filtro SVG Blur 2 valores by Kseso (@Kseso) on CodePen.

Filtro: Grayscale

See the Pen Filtro: Grayscale by Kseso (@Kseso) on CodePen.

Ver demo a Full

.grayscale {filter: grayscale(1);} .grayscale {filter: url(#svg-grayscale);} <!--SVG escala grises al 100%--> <filter id="svg-grayscale"> <feColorMatrix 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" type="matrix"/> </filter>

Este filtro podría englobarse entre los complejos ya que hace uso de una matriz de colores, feColorMatrix. Esto lo hace muy potente y versátil, pues dependiendo de los valores de la matriz el resultado final variará. Mira la relación de enlaces del final del artículo.

Filtro: Sepia

See the Pen Filtro: Sepia by Kseso (@Kseso) on CodePen.

Ver demo a Full

.sepia {filter: sepia(1);} .sepia {filter: url(#svg-sepia);} <!--SVG SEPIA--> <filter id="svg-sepia"> <feColorMatrix values=" 0.343 0.669 0.119 0 0 0.249 0.626 0.130 0 0 0.172 0.334 0.111 0 0 0 0 0 1 0" type="matrix"/> </filter>

Para el filtro Svg sepia aplica lo mismo que para el de escala de grises al basarse también en una matriz de color.

Filtro: Saturate

See the Pen Filtro: Saturate by Kseso (@Kseso) on CodePen.

Ver demo a Full

.saturate {filter: saturate(2);} .saturate {filter: url(#svg-saturate);} <!--SVG SATURATE--> <filter id="svg-saturate"> <feColorMatrix type="saturate" values="2"> </filter>

Sencillo y simple. Todo se reduce al valor declarado en el atributo values

Filtro: hue-rotate

See the Pen Filtro: hue-rotate by Kseso (@Kseso) on CodePen.

Ver demo a Full

.hue-rotate {filter: hue-rotate(90deg);} .hue-rotate {filter: url(#svg-hue-rotate);} <!--SVG HUE-ROTATE--> <filter id="svg-saturate"> <feColorMatrix type="hueRotate" values="90> </filter>

La variación del tono (hue-rotate) se expresa en grados en el valor del atributo values del filtro SVG. El resultado final depende tanto de dicho valor como del color al que aplica.

Filtro: Invert

See the Pen Filtro: invert by Kseso (@Kseso) on CodePen.

Ver demo a Full

.invert {filter: invert(100%);} .hue-rotate {filter: url(#svg-invert);} <!--SVG INVERT--> <filter id="svg-invert"> <feComponentTransfer> <feFuncR tableValues="1 -1" type="table"/> <feFuncG tableValues="1 -1" type="table"/> <feFuncB tableValues="1 -1" type="table"/> </feComponentTransfer> </filter>

Con el filtro SVG invert se actúa sobre cada uno de los tres canales RGB mediante el doble valor de tableValues.

Filtro Opacity

<!--SVG OPACITY--> <svg class='hide' xmlns="http://www.w3.org/2000/svg"> <filter id="svg-opacity"> <feComponentTransfer> <feFuncA type="table" tableValues="0 0.5" /> </feComponentTransfer> </filter> </svg>

El grado de transparencia está definido por el segundo valor de tableValues="0 0.5". En este ejemplo es el equivalente a opacity: .5

Filtro: brightness

See the Pen Filtro: brightness by Kseso (@Kseso) on CodePen.

Ver demo a Full

El atributo en el SVG a modificar para variar el brillo es slope. Nota que mientras que el filtro Css actúa en los 3 canales simultáneamente (rojo, verde y azul) y con el mismo valor, el filtro SVG permite hacerlo sobre cada uno de ellos independientemente:

.brightness {filter: brightness(2);} .brightness {filter: url(#svg-brightness);} <!--SVG brightness--> <filter id="svg-brightness"> <feComponentTransfer> <feFuncR type="linear" slope="2"></feFuncR> <feFuncG type="linear" slope="2"></feFuncG> <feFuncB type="linear" slope="2"></feFuncB> </feComponentTransfer> </filter>

Filtro: contrast

See the Pen Filtro: contrast by Kseso (@Kseso) on CodePen.

Ver demo a Full

En el caso del filtro contrast tienes dos valores por canal RGB para lograr el contraste deseado: slope y intercept:

.contrast {filter: contrast(2);} .contrast {filter: url(#svg-contrast);} <!--SVG contrast--> <filter id="svg-contrast"> <feComponentTransfer> <feFuncR type="linear" slope="2" intercept="-0.1"></feFuncR> <feFuncG type="linear" slope="2" intercept="-0.1"></feFuncG> <feFuncB type="linear" slope="2" intercept="-0.1"></feFuncB> </feComponentTransfer> </filter>

Filtro: drop-shadow

See the Pen Filtro: drop-shadow by Kseso (@Kseso) on CodePen.

Ver demo a Full

.drop-shadow {filter: drop-shadow(0px 0px 10px #000);} .drop-shadow {filter: url(#svg-drop-shadow);} <!--SVG drop-shadow--> <filter id="svg-drop-shadow"> <feGaussianBlur in="SourceAlpha" stdDeviation="10" /> <feOffset dx="0" dy="0" result="offsetblur" /> <feFlood flood-color="#000" /> <feMerge> <feMergeNode></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge> </filter>

Este es un filtro bastante complejo, es decir, permite mucho y muy variado juego. Una característica de las sombras mediante filtros frente a la propiedad box-shadow es que la segunda crea sombra a todos y cada uno de los elementos, mientras que si se declara vía filtros a un grupo de elementos la sombra es la silueta formada por todos ellos, no son sombras individuales de cada uno. Ver demo Diferencias entre Box-shadow y drop-shadow.

Filtros personalizados

Son los marcados por la especificación como custom filters. Es el resultado de aplicar varios de los posibles, ya sea utilizando la vía Css o mediante filtros SVG.

A modo de ejemplo esta demo. No he buscado lograr el mismo resultado final. Aprovecho la posibilidad que ofrece el filtro invert en cada canal.

See the Pen Filtro: personalizado by Kseso (@Kseso) on CodePen.

Ver demo a Full

Muy importante: cuando se usan varios filtros simultáneamente el resultado final obtenido es función del orden en que se declaran. No es lo mismo convertir primero a escalas de grises 100% y después aplicar un filtro sepia que filtro sepia más escala grises. En el segundo caso el resultado será un elemento sólo en grises y en el primero un monotono en sepia.

Los filtros nativos de SVG

La especificación sobre SVG define, además de los filtros incluidos en este artículo, otros cuantos más.

Una buena fuente para iniciarse en ellos es el libro Scalable de Jorge Aznar. En su página 49 y siguientes le dedica todo un capítulo a explicarlos, ejemplos en codepen incluidos. Como esta demo:

See the Pen Capitulo 7 - varios efectos de filtro by Jorge Aznar (@jorgeatgu) on CodePen.

Lecturas para ampliar información

Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Don Kseso Kseso

Comentarios: 4

  1. La sintaxis de Css3 es más cómoda para aplicar filtros, pero SVG quizás tenga más opciones de personalización de imágenes.

    Hay un efecto parecido que se usa mucho ahora. Al pasar el ratón por encima de una imagen, ésta pasa de escala de grises a color, seguro que lo has visto en alguna web. Aunque este efecto se hace jugando con opacidad de capas y js, no con filtros css3.

    Gracias por el artículo.

    ResponderEliminar
    Respuestas
    1. Gracias a tí, Sergio
      Está bien tu apunte para que conste ;-)

      A modo de disclaimer no mencioné que los filtros Css aceptan tanto animaciones como transiciones Css según qué propiedades y valores se vean afectadas (ver spec) porque creí que ya era conocido y como bien indicas, hay demos al respecto.
      SVG Animation

      Tampoco entré en este aspecto porque no era ese el objeto del post (bastante tocho me salió ya xD


      Un saludo

      Eliminar
    2. OK. Ya entendimos que el artículo no cubre las animaciones, pero ahora que lo mencionaron ... el efecto de pasar una imagen de B&N a color también se puede hacer con 'grayscale'.
      Se aplica el filtro a una imagen en color y se le quita al pasar el puntero.

      Eliminar
  2. Con SVG+SMIL y muy pocas líneas de código se puede animar cualquier propiedad de los filtros de SVG.

    Algunos experimentos que he hecho con feTurbulence:

    http://codepen.io/jorgeatgu/pen/Ayevf/
    http://codepen.io/jorgeatgu/pen/npsAq/

    ResponderEliminar

EsCss RSS del Blog RSSS Comentarios Humans.txt ᛯ Diseno por Kseso SiteMap