Animando gráficos SVG con CSS

Animando gráficos SVG con CSS

Animar gráficos SVG con CSS es como animar cualquier otro elemento, se pueden aplicar transiciones, transformaciones y keyframes. Pero... ¿por qué usar gráficos SVG en lugar de imágenes?.

SVG (Scalable Vector Graphics) es el formato estándar de imagen vectorial para gráficos bidimensionales que soporta interacción y animación con CSS o JavaScript.

  • Es el formato estándar de gráficos vectoriales para web de la W3C.
  • Es escalable e independiente de la resolución de pantalla.
  • Es soportado por la inmensa mayoría de los navegadores actuales.
  • Es básicamente texto, por lo que se puede comprimir consiguiendo ficheros más pequeños que sus equivalentes en imagen (JPG y PNG).
  • Se pueden estilar y manipular con CSS y JavaScript.
  • Hay muchas herramientas que permiten crear y editar gráficos SVG. Inkscape es la mejor alternativa libre para trabajar con el formato SVG.

En este artículo vamos a ver el proceso básico de preparación de un archivo SVG para usarlo en una página web y cómo podemos manipularlo con estilos CSS.

Preparando el SVG con Inkscape

Inkscape es nuestra herramienta favorita para el diseño con gráficos vectoriales. Por defecto genera archivos .svg. No necesita ninguna configuración especial a la hora de guardar o exportar el trabajo que se realice con él.

Los archivos SVG normalmente contienen información redundante como metadatos sobre el editor, comentarios, grupos vacíos, etc. que se pueden eliminar sin afectar al dibujo que hayamos realizado. Es interesante utilizar alguna herramienta de optimización para tener un código XML más limpio, claro y al final, más fácil de manipular y estilar con CSS.

SVG Editor es una herramienta online que permite pegar el código XML o subir el archivo SVG a optimizar. Permite ver las optimizaciones en vivo a medida que vamos ajustando las diferentes opciones. Esto es interesante ya que ciertas optimizaciones pueden romper nuestro SVG.


Vamos a trabajar con un SVG sencillo para ilustrar los diferentes procesos. Partiremos del archivo original de 2,8 kB con multitud de información que no nos hace falta. Después de procesarlo con SVG Editor con todas las opciones activadas obtendremos un archivo mucho más ligero (680 bytes).

La opción de optimización extrema no es adecuada para todos los casos. En función de la complejidad del SVG (número de elementos, etc.) deberemos ajustar las configuraciones.


El resultado es un código XML fácil de interpretar y manipular:

<svg version="1.1" viewbox="0 0 132.3 132.3" width="500" height="500" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
    <g transform="translate(0,-164.70834)">
        <path d="m106.2 193.2c-0.6-0.5-1.4-0.5-2.1-0.3l-77.6 32.2c-0.8 0.3-1.3 1.1-1.3 2 0 0.9 0.5 1.7 1.3 2l25.3 10.9 2.7 27.1c0.1 0.9 0.7 1.6 1.5 1.9 0.2 0.1 0.4 0.1 0.6 0.1 0.7 0 1.3-0.3 1.7-0.8l14.1-17.6 25.6 12.1c0.6 0.3 1.4 0.3 2-0.1 0.6-0.4 1-1 1.1-1.7l5.9-65.8c0.1-0.8-0.3-1.5-0.9-1.9zM32.9 227.1 94.8 201.5 54.6 236.4Zm23.1 11.1c0-0.1 0-0.1 0-0.2l39.8-34.5-34.4 38.2-3.4 15.8zm7.1 5.6 6.6 3.3-10 12.5zm34 13.6-24.4-11.5c-0.3-0.1-0.6-0.2-0.9-0.2l-7.7-3.9 38.2-42.5z" stroke-width="0.1"></path>
    </g>
</svg>

Cómo incluir el SVG en la página web

Hay varias formas de incluir los gráficos SVG en nuestra página web. Si solo se quieren para aprovechar la escalabilidad y el menor tamaño de los archivos se pueden usar en la etiqueta <img> o mediante CSS con la propiedad background-image. Si se quieren estilar e interactuar con ellos se incluirán con la etiqueta <object> o directamente en el código HTML.

La etiqueta <object> es la mejor opción si queremos manipular el SVG sin incluirlo directamente en nuestro HTML. Además permite incluir una alternativa para aquellos navegadores que no soporten el formato SVG (principlamente IE8).

<object data="archivo.svg" type="image/svg+xml">
    Tu navegador no sporta SVG.
</object>

Incluir el código SVG en la página HTML evitará una consulta HTTP (la que se hace en el caso de usar <object> para cargar la el archivo externo) pero en el caso de gráficos de cierta complejidad puede ser difícil manipularlos junto con el código HTML.

  Más información en: https://www.sitepoint.com/add-svg-to-web-page/


En el apartado anterior hemos incluido el código XML directamente en la página HTML tal y como se detalla. Para archivos SVG más complejos es recomedable usar la etiqueta <object> para incluir el archivo SVG externo, y aplicar los estilos sobre el propio archivo SVG como se explica a continuación.

Dar estilos al gráfico SVG con CSS

Hay varias maneras de aplicar estilos a los objetos definidos en el gráfico SVG. Los atributos de presentación son unas propiedades especiales de estilo que se aplican en línea, no los usaremos porque lo que queremos es usar propiedades CSS estándar. Los estilos los podemos incluir inline o mediante archivos externos.

Para incluir estilo "en línea" usaremos la etiqueta <style>:

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="" height="" viewBox="0 0 132.3 132.3" version="1.1">
    <style type="text/css">
        <![CDATA[
        .send-icon {
            fill:#d9534f;
        }
        ]]>
    </style>
    <g>
        <path class="send-icon" d="..."/>
    </g>
</svg>

Usaremos <![CDATA[ ... ]]> para evitar conflictos con ciertos caracteres (p.e. >).

Para usar hojas de estilo externas hay que referenciarlas en el código SVG, justo antes de la etiqueta <svg>:

<?xml-stylesheet type="text/css" href="style.css"?>
<svg xmlns="http://www.w3.org/2000/svg">
    <g>
        <path class="send-icon" d="..."/>
    </g>
</svg>

 

Acciones que soportan las diferentes formas de incluir los gráficos SVG en nuestro documento:

  Interacciones CSS (ej. :hover) Animaciones CSS
<img> No Sí, dentro de <svg>
CSS background image No Sí, dentro de <svg>
<object> Sí, dentro de <svg> Sí, dentro de <svg>
<iframe> Sí, dentro de <svg> Sí, dentro de <svg>
<embed> Sí, dentro de <svg> Sí, dentro de <svg>
<svg> (inline)

Vamos a ver un par de ejemplos de estilos CSS sobre un archivo SVG incluido en línea en la página. El código de ejemplo sería:

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 132.3 132.3" version="1.1">
    <style type="text/css">
        <![CDATA[
        .send-icon {
            fill:#000;
        }
        .send-icon:hover {
            fill:#d9534f;
        }
        ]]>
    </style>
    <g transform="translate(0,-164.70834)">
        <path class="send-icon" d="m106.2 193.2c-0.6-0.5-1.4-0.5-2.1-0.3l-77.6 32.2c-0.8 0.3-1.3 1.1-1.3 2 0 0.9 0.5 1.7 1.3 2l25.3 10.9 2.7 27.1c0.1 0.9 0.7 1.6 1.5 1.9 0.2 0.1 0.4 0.1 0.6 0.1 0.7 0 1.3-0.3 1.7-0.8l14.1-17.6 25.6 12.1c0.6 0.3 1.4 0.3 2-0.1 0.6-0.4 1-1 1.1-1.7l5.9-65.8c0.1-0.8-0.3-1.5-0.9-1.9zM32.9 227.1 94.8 201.5 54.6 236.4Zm23.1 11.1c0-0.1 0-0.1 0-0.2l39.8-34.5-34.4 38.2-3.4 15.8zm7.1 5.6 6.6 3.3-10 12.5zm34 13.6-24.4-11.5c-0.3-0.1-0.6-0.2-0.9-0.2l-7.7-3.9 38.2-42.5z" stroke-width="0.1"/>
    </g>
</svg>
    

Asignamos un color al objeto con clase .send-icon (fill: red;).

Asignamos una interacción al pasar por encima del dibujo (:hover).

Gráficos SVG responsive

Para que el gráfico incluido sea fluido y se ajuste siempre al ancho máximo del contenedor habrá que usar una serie de ajustes en función de la técnica utilizada.

Independientemente de la técnica elegida hay que quitar los atributos height y width del elemento <svg>. Hay que mantener el atributo viewBox y mantener el atributo preserveAspectRatio como xMidYMid meet (tomará este valor por defecto si no lo cambiamos). En la mayoría de navegadores esto bastará para que interpreten que el ancho por defecto del gráfico SVG es el 100%. Pero IE no lo interpreta así y necesita ajustes adicionales.

También podemos usar media queries para hacer el gráfico SVG responsive. Hay que tener en cuenta que el viewport que toma de referencia es el del propio SVG a no ser que se incluya en gráfico en el documento con la etiqueta <svg>.

Por tanto, si incluimos el SVG con la etiqueta <object> por ejemplo, el SVG se ajustará al viewport establecido por esta etiqueta, es decir, las dimensiones del elemento conformarán el viewport respecto al que se aplicarán las media queries que definamos en el CSS (sería un concepto similar a las element queries que mencionamos en otro artículo).

  Información detallada en: https://tympanus.net/codrops/2014/08/19/making-svgs-responsive-with-css/

Animando el gráfico SVG con CSS

Los gráficos SVG se pueden animar como cualquier elemento HTML, usando keyframes y propiedades de animación o usando transiciones. En muchos casos, las animaciones más complejas pueden suponer varios tipos de transformación.

Los elementos de un gráfico SVG responden a las transformaciones (propiedades transform y transform-origin) de la misma manera que los elementos HTML. Sin embargo, los elementos SVG no se rigen por el modelo de caja (box model), por lo que no tienen margen, borde, padding o contenido.

Por defecto, el origen de la transformación (transform-origin) de un elemento HTML está en el centro del elemento (50%,50%). Sin embargo, en un elemento SVG está ubicado en el origen del sistema de coordenadas del usuario, en la esquina superior izquierda (0,0).

Así que, si queremos rotar un elemento SVG sobre su centro, en lugar de sobre su esquina superior izquierda, tenemos que indicar explícitamente el origen de la transformación con la propiedad transform-origin. Si especificamos el transform-origin en %, el valor será relativo al cuadro que delimita el elemento incluyendo el trazo del borde. Si las unidades son absolutas, entonces el valor será relativo al lienzo del SVG en el sistema de coordenadas del usuario.

  Más información en: https://www.smashingmagazine.com/2014/11/styling-and-animating-svgs-with-css/#animating-svgs-with-css


Para terminar con nuestro ejemplo, aplicaremos a nuestro gráfico SVG un movimiento de traslación sobre los ejes x e y de manera cíclica usando keyframes.

El SVG con los estilos aplicados:
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="300" height="300" viewBox="0 0 132.3 132.3" version="1.1">
    <style type="text/css">
        <![CDATA[
        .send-icon {
            fill:#d9534f;
            animation:translate 3s ease infinite;
        }
        @keyframes translate {
            0%,25%,75%,100% {
                transform:translate(0px,0px);
            }
            50% {
                transform:translate(100px,-100px);
            }
        }
        ]]>
    </style>
    <g transform="translate(0,-164.70834)">
        <path class="send-icon" d="m106.2 193.2c-0.6-0.5-1.4-0.5-2.1-0.3l-77.6 32.2c-0.8 0.3-1.3 1.1-1.3 2 0 0.9 0.5 1.7 1.3 2l25.3 10.9 2.7 27.1c0.1 0.9 0.7 1.6 1.5 1.9 0.2 0.1 0.4 0.1 0.6 0.1 0.7 0 1.3-0.3 1.7-0.8l14.1-17.6 25.6 12.1c0.6 0.3 1.4 0.3 2-0.1 0.6-0.4 1-1 1.1-1.7l5.9-65.8c0.1-0.8-0.3-1.5-0.9-1.9zM32.9 227.1 94.8 201.5 54.6 236.4Zm23.1 11.1c0-0.1 0-0.1 0-0.2l39.8-34.5-34.4 38.2-3.4 15.8zm7.1 5.6 6.6 3.3-10 12.5zm34 13.6-24.4-11.5c-0.3-0.1-0.6-0.2-0.9-0.2l-7.7-3.9 38.2-42.5z"/>
    </g>
</svg>}

El resultado:


Otros artículos sobre técnicas CSS:

Otros artículos sobre diseño vectorial con Inkscape:



Historias relacionadas

Respuestas JSON con Timber

Respuestas JSON con Timber

Nuestro enfoque es construir sitios web rápidos y fácilmente mantenibles y actualizables a medio/largo plazo gracias a un reducido número de dependencias.

A pesar de que nuestra plataforma de preferencia es Python/Django, los tiempos cambian y las modas se imponen. Atrás quedaron el PHP-Nuke, Post-Nuke, Xoops, Mambo, Spip, Joomla. Ahora Wordpress está en ...

Mapas interactivos sin usar Google Maps

Mapas interactivos sin usar Google Maps

Leaflet es una librería JavasScript de código abierto para embeber mapas. Es una librería perfecta para sustituir a Google Maps en los sitios en que queremos incluir un mapa de situación de nuestro negocio o una serie de marcadores con direcciones de interés.

Recientemente, hemos utilizado esta librería en el proyecto Podorunners, en el que ...

Solicítanos información

 Tel: (+34) 983 070 900