Puede que ahora parezca una perogrullada, pero una de las características que contribuyó a la popularización de la web y de HTML (junto a los enlaces de hipertexto) fue la posibilidad de insertar imágenes, mapas de bits donde reinaban los gif y los jpg por su relación calidad/peso y que se usaban en función de las características de cada imagen.
Pero pronto apareció la necesidad de buscar un formato estándar vectorial, así que, en 1998 se empezó a buscar una solución y finalmente nació SVG (Scalable Vector Graphics), que se convirtió en recomendación en 2001, aunque actualmente va por su segunda versión de la recomendación 1.1 (del 2011) y la recomendación definitiva de SVG2 cada día está más cerca.
Al principio le costó un poco abrirse paso por la competencia de la tecnología Flash (que estaba muy extendida) y porque el soporte de SVG en los navegadores era irregular, como en otros muchos estándares en la época. Pero hoy por hoy es un arma de primer nivel para cualquier desarrollador frontend.
La principal ventaja de SVG es que se trata de imágenes vectoriales que se definen a través de XML. O sea, que se verán bien independientemente del tamaño y resolución a las que se muestren, y que se pueden definir y/o alterar a través de código usando el DOM. Por ejemplo, puedes modificarle el color o animarla a través de CSS o JavaScript.
¿Cómo crear imágenes SVG?
En realidad, SVG es más que un simple tipo de imagen más, es todo un sistema de representación gráfica que tiene su propia especificación y cuyo verdadero alcance y potencia se irá viendo en los próximos años. Dado que esto escapa al alcance de este post, lo dejaremos simplemente como un tipo de imágenes vectoriales que se pueden crear con código XML de una forma sencilla. La verdad es que es muy agradecido, al menos dibujando formas simples.
Como muestra, un cuadrado con un borde naranja de 10px se escribiría así:
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" viewBox="0 0 150 150">
<rect x="0" y="0" width="150" height="150" fill="#ffffff" stroke="#ff9900" stroke-width="10"></rect>
</svg>
Y se vería así:
Fíjate en el parámetro viewbox
, ya que actúa como una ventana que muestra el rectángulo y, si es más pequeño que el rectángulo, enmascarará a este. A su vez, hay que delimitar el tamaño del SVG (el lienzo sobre el que se dibujará el rectángulo, que tiene su propio viewport y, por defecto, crece hasta el infinito) y el tamaño del elemento que se dibuja. Estos conceptos se explican muy bien aquí, y créeme, te recomiendo que los tengas bien claros antes de ponerte a jugar con SVG.
Quizá SVG te recuerde un poco al funcionamiento del elemento canvas
(en inglés, canvas significa lienzo), solo que canvas permite actuar a nivel de pixel, necesita JavaScript y no es accesible a través del DOM, lo que lo hace un poquito más rápido y con más posibilidades. En cambio, a favor de SVG, al ser accesible a través del DOM, es accesible para los lectores de pantalla y es más fácil añadirle interactividad.
Ahora bien, si lo que quieres es crear imágenes complejas, lo más práctico es que uses un software de dibujo vectorial. El buque insignia hoy por hoy de este tipo de software es Adobe Illustrator, pero también puedes crear SVGs con software más asequible como Sketch (en el momento de escribir esto solo para Mac) o incluso gratuito y open source, como Inkscape.
Es más, hay soluciones online gratuitas que te pueden sacar de un apuro sin necesidad de instalar nada, como Vectr y http://editor.method.ac/
¿Cómo insertamos SVG?
Tenemos varias formas de usar una imagen SVG en nuestras páginas
Directamente en el código HTML5
Este método es el que acabamos de ver en nuestro ejemplo. Está bien para imágenes sencillas y que quieres manipular con CSS o JavaScript. Si lo usas con una imagen muy compleja te puede ensuciar y/o sobrecargar el código de la web.
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" viewBox="0 0 150 150">
<rect x="0" y="0" width="150" height="150" fill="#ffffff" stroke="#ff9900" stroke-width="10"></rect>
</svg>
Con una etiqueta <object>
Si tomas el código del ejemplo anterior en un bloc de notas, y lo guardas con extensión .svg lo podrás insertar con la etiqueta <object
>. Esta es la mejor opción si vas a usar opciones avanzadas con CSS y JavaScript, porque te permite añadir contenido alternativo en el caso de no estar soportado.
<object type="image/svg+xml" data="cuadrado.svg">
Este texto se verá si el navegador no soporta SVG
</object>
En una etiqueta <embed>
Esta es solo para que sepas que existe, mejor no la uses, porque es una reminiscencia de la época de la guerra entre navegadores que funciona igual que la etiqueta object
pero, a diferencia de esta, jamás ha estado dentro de una especificación estándar. Así que, aunque funcione y los navegadores la soporten, lo mejor es no usarla.
<embed src="cuadrado.svg" type="image/svg+xml" />
Dentro de un <iframe>
<iframe id="miframe" name="miframe" src="cuadrado.svg">
Este texto se verá si el navegador no soporta frames
</iframe>
Los iframes son una solución muy poco elegante y además es un engorro manipular su contenido, pero oye, que sepas que existe esta posibilidad para mantener el código del SVG fuera de tu página
Dentro de una etiqueta <img>
<img src="cuadrado.svg" />
Este caso es útil si no necesitas modificar el SVG al vuelo ni usar características avanzadas porque, por seguridad, los navegadores deshabilitan cualquier capacidad interactiva de SVG, y tampoco podremos modificar su apariencia usando código CSS externo en la mayoría de los navegadores
Como una imagen de fondo en CSS
También podemos usar nuestro SVG en la propiedad background-image
de cualquier elemento:
#micuadrado { background-image: url("cuadrado.svg"); }
En este caso, como en la etiqueta <img>
tampoco podremos acceder a editarlo directamente con CSS o JavaScript.
Usando SVG en los bullets de listas para poder cambiarles el color
A través de CSS es bastante sencillo sustituir los bullets por defecto de las listas de HTML por una imagen de fondo dentro de cada <li>
. Es una técnica sencilla, potente y bastante común a la hora de crear listas y menús.
¿Y cuál es el problema? Pues que, como acabamos de ver, si usamos una imagen de fondo SVG en nuestros bullets, de entrada no podemos modificar sus propiedades al vuelo desde un CSS externo ni con JavaScript
Pero hay una forma alternativa que nos puede resultar útil si, en vez de indicar la URL de la imagen, embebemos directamente el código usando el esquema data:
.
Por ejemplo, a una lista cualquiera:
<ul class="arrows-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
Le podemos poner como bullet a los <li>
un triángulo naranja en SVG de esta manera (fíjate en la regla en negrita):
.arrows-list {
list-style:none inside;
background-position:left center;
background-repeat: no-repeat;
background-image: url('data:image/svg+xml, <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="13" height="13" ><polygon points="0,0 0,100 95,50" style="fill:#84BA0D;"></polygon></svg>');
}
Embebiéndola de esta manera podríamos cambiar el color (o cualquier otra variable) sirviéndonos de JavaScript, de propiedades personalizadas de CSS o de algún otro valor de nuestro CMS que nos convenga. Vale, que no es tan limpio como poder acceder directamente a través del DOM, pero te saca de un apuro.
Si quieres, puedes verlo en acción en este ejemplo, o descargarlo desde aquí (ZIP 6KB).
Por si te interesa saberlo, en nuestro curso de HTML5 y CSS3a fondo para programadores, entre otros muchos temas se estudia a fondo el formato SVG y se aprende a añadirle interactividad.
Personalmente, hace poco necesité poder cambiarle el color puntualmente a los bullets de una lista de forma sencilla y me costó un poco encontrar cómo podría hacerlo. Espero que, gracias a este post, tengas que invertir menos tiempo que yo buscando una solución. Si es así, házmelo saber en los comentarios.