Tutorial de SVG: Qué es y cómo se utiliza

html

El formato SVG es un formato de imagen vectorial muy extendido. En este tutorial veremos una introducción a este formato junto con un tutorial en el que aprenderás todo lo que necesitas saber del modo más sencillo posible.

Qué es el formato SVG

El formato SVG se introdujo a principios de la década del 2000. Su nombre es un acrónimo de Scalable Vector Graphics (Graficos Vectoriales Escalables). A pesar de que este formato lleva mucho tiempo entre nosotros, hace muy pocos años que comenzó a usarse masivamente, en especial debido a la baja compatibilidad de algunos navegadores con este formato. Cuando hablamos de navegadores poco compatibles casi siempre nos referimos a Internet Explorer, y en esta ocasión no iba a ser diferente.

Sin embargo, a día de hoy ya todos los navegadores soportan imágenes SVG, por lo que pueden ser usadas con total seguridad salvo que algunos de tus usuarios todavía estén usando Internet Explorer 8 o alguna versión inferior, lo cual es poco probable.

El formato SVG es un formato de imagen vectorial, por lo que funciona de un modo muy diferente a otros formatos rasterizados como JPG, PNG o GIF, que basan su estructura en una serie de matrices de pixels. Las imágenes vectoriales no tienen un tamaño fijo como ocurre con las imágenes que incluyen pixels, sino que se pueden escalar sin pérdida de calidad, siendo un formato ideal para la gran variedad de tamaños de pantalla y resoluciones que usamos hoy en día.

El éxito del formato SVG no fue casual, sino que coincidió con el decline de otras tecnologías como Flash, muy extendida décadas atrás. El formato SVG permite crear muchos de los gráficos y elementos que antes hacíamos con Flash sin necesidad de usar plugins externos o tecnologías propietarias.

La versión actual del formato SVG es la versión 1.1, aunque la versión 2.0 está ya en desarrollo.

Las ventajas del formato SVG

Las imágenes SVG se crean usando el lenguaje de marcado XML. El navegador se encargará de unir los puntos que definamos mediante líneas. De este modo, las imágenes se pueden adaptar a una gran variedad de resoluciones y tamaños de pantalla sin pérdida de calidad, ya que cuando aumentemos el tamaño de una imagen, los puntos únicamente estarán más separados, por lo que seguimos teniendo toda la información de la imagen original en todo momento.

Dado que las imágenes SVG se definen con sintaxis XML, son mucho más flexibles que las imágenes que usan otros formatos, pudiendo además manipular las imágenes mediante JavaScript o CSS, aunque ni el código JavaScript ni los estilos CSS podrán formar parte de la definición de una imagen SVG en sí misma. Animar una imagen SVG es tremendamente sencillo, lo cual es todo un mundo dentro del desarrollo web. Además, el propio formato proporciona algunos efectos de edición, como filtros, máscaras o la opción de recortar las imágenes.

Otra de las ventajas de las imágenes SVG está en la posibilidad de almacenarlas como texto plano junto al resto de tu código, pudiendo transmitirlas en formato GZip desde el servidor hasta el navegador del usuario en un mismo archivo comprimido.

Las imágenes SVG son muy convenientes cuando queremos representar imágenes muy pequeñas como iconos o logotipos, que suelen tener una calidad relativamente mala con los formatos tradicionales. También son ideales para aquellos elementos a pantalla completa cuyo tamaño varía en función del tamaño de la pantalla del usuario. Mientras que antes los packs de iconos se incluían mediante fuentes como por ejemplo FontAwesome, ahora se incluyen mediante elementos SVG, aceptado así una infinita variedad de tamaños.

Cómo crear una imagen SVG

Las imágenes en formato SVG se definen utilizando XML, por lo que su sintaxis es muy similar a la que utilizamos en HTML. Sin embargo, cuando creas una imagen en formato SVG no utilizarás etiquetas, sino bloques de imágenes vectoriales. A continuación puedes ver un ejemplo:

<svg width="80" height="10">
  <rect x="0" y="0" width="80" height="10" fill="red" />
</svg>

Lo que hemos hecho ha sido crear una línea roja de 80px de ancho por 10px de alto. Para ello hemos usado primero la etiqueta svg, en donde definimos el tamaño del área de trabajo en la que crearemos el gráfico. Todas las unidades se especifican en pixels por defecto. Seguidamente hemos usado la etiqueta rect junto con los atributos width y height para crear un rectángulo del tamaño indicado. El rectángulo se creará en la posición definida por los atributos x e y. También hemos usado el atributo fill para especificar el color del rectángulo.

Del mismo modo que hemos usado la etiqueta rect para crear un rectángulo, también puedes usar las etiquetas text, path o line, entre otras, para definir otros elementos. Sin embargo, la mayor parte de las veces no crearás los gráficos manualmente, sino que usarás aplicaciones como Adobe Illustrator, Sketch, Figma o cualquier otra aplicación que permita crear gráficos vectoriales y exportarlos luego al formato SVG.

Puedes incluir imágenes SVG de en una página HTML de varias formas. Por ejemplo, puedes incluir una imagen en formato SVG del mismo modo que harías con cualquier otra imagen:

<img src="imagen.svg" alt="Imagen SVG" />

Tal y como ves, la forma de incluir la imagen no difiere de cómo incluirías cualquier otra imagen en formato PNG, JPG, GIF o WEBP.

Además, también puedes incluir directamente el código SVG en tu código HTML para representar la imagen resultante en pantalla:

<svg width="5" height="5">
  <rect x="0" y="0" width="5" height="5" fill="blue" />
</svg>

A esta forma de incluir código HTML se le conoce como HTML en línea o inline. Incluyendo el código de la imagen SVG junto con tu código HTML reducirás el número de peticiones al servidor, reduciendo los tiempos de carga de la página y mejorando el rendimiento. Esto no es posible con las imágenes que están en otros formatos, por lo que la ventaja es clara.

Es importante destacar que la sintaxis del código SVG difiere un poco entre los estándares HTML5 y XHTML, aunque es poco probable que a día de hoy alguien cree una página usando XHTML, en desuso desde hace muchos años.

En muchas imágenes SVG podrás encontrar el atributo xmlns, que indica el espacio de nombres de la imagen SVG. Si este atributo está presente, significa que el elemento SVG está usando la sintaxis XHTML, apenas utilizada a día de hoy:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  ...
</svg>

Si el documento usa el estándar HTML5 y en la cabeza del documento está definido el DOCTYPE como <!DOCTYPE html>, entonces no necesitas agregar el atributo xmlns:

<svg>
  ...
</svg>

Etiquetas gráficas del formato SVG

Mediante el formato SVG puedes crear varios tipos de elementos o figuras para dar forma al gráfico final. Los elementos se dibujarán por defecto en las coordenadas x=0 e y=0 dentro de un plano bidimensional. Los elementos se dibujarán siempre hacia la derecha en el plano horizontal y hacia abajo en el vertical.

A continuación vamos a ver cuáles son las etiquetas SVG más utilizadas junto con un ejemplo de uso para cada una de ellas.

Etiqueta SVG text

La etiqueta SVG text permite agregar texto. Mediante los atributos x e y definimos el punto en el que se agregará el texto. Este texto también se puede seleccionar con el ratón del mismo modo que cualquier otro texto. A continuación puedes ver un ejemplo en el que agregamos texto en las coordenadas (5px, 30px):

<svg>
  <text x="5" y="20">Un texto cualquiera</text>
</svg>

Este sería el resultado:

Etiqueta SVG rect

La etiqueta rect sirve para crear un rectángulo en las coordenadas definidas por los atributos x e y. Mediante los atributos width y height podrás definir la anchura y la altura del mismo. Puedes rellenar el rectángulo con algún color mediante el atributo fill. En el siguiente ejemplo agregamos un rectángulo de 80px de ancho por 80px de alto en las coordenadas (0px, 0px):

<svg>
  <rect x="0" y="0" width="80" height="80" fill="#0092b7" />
</svg>

Este sería el resultado:

Etiqueta SVG circle

La etiqueta circle sirve para crear un círculo cuyo centro estará en las coordenadas definidas por los atributos cx y cy. El radio del círculo permitirá definir su tamaño mediante el atributo r. Finalmente, podemos rellenar el círculo con algún color mediante el atributo fill. A continuación puedes ver un ejemplo en el que agregamos círculo con un radio de 60px en las coordenadas (70px, 70px):

<svg>
  <circle cx="70" cy="70" r="60" fill="#0092b7" />
</svg>

Este sería el resultado:

Etiqueta SVG ellipse

La etiqueta ellipse se usa para crear una elipsis. Mediante los atributos cx y cy es posible definir el centro de la elipsis. Los atributos rx y ry se usan para definir el radio horizontal y vertical respectivamente. A continuación puedes ver un ejemplo:

<svg>
  <ellipse cx="200" cy="80" rx="100" ry="50" fill="#0092b7"" />
</svg>

Este sería el resultado:

Etiqueta SVG line

La etiqueta line sirve para crear una línea que comenzará en las coordenadas definidas por los atributos x1 e y1 y finalizará en las coordenadas definidas por los atributos x2 e y2. Para definir el color de la línea se usa el atributo stroke. En el siguiente ejemplo agregamos una línea que comienza en el punto (0px, 80px) y finaliza en el punto (80px, 0px):

<svg>
  <line x1="0" y1="80" x2="80" y2="0" stroke="#0092b7" />
</svg>

Este sería el resultado:

Etiqueta SVG path

La etiqueta path permite definir una serie de líneas para dibujar un gráfico del mismo modo que lo harías con cualquier aplicación visual de edición de gráficos vectoriales. Además de definir las líneas, también podemos curvarlas. Se trata de la herramienta más completa y a su vez compleja de todas las disponibles en la API SVG.

Para dibujar las líneas nos valdremos de una serie de atributos. Mediante el atributo d indicamos las direcciones a seguir utilizando alguno de los comandos disponibles.

Los comandos se separan por espacios en el interior de dicho atributo, al igual que los parámetros de cada uno de los comandos. A continuación puedes ver una lista con los comandos más relevantes. Se incluyen a modo de referencia, así que no te preocupes si algunos resultan demasiado complejos, ya que habitualmente usarás aplicaciones visuales para generarlos:

  • Comando M: Mover el cursor a las coordenas indicadas por los parámetros x e y.
  • Comando H: Agregar una línea horizontal que terminará en el punto indicado por el parámetro x.
  • Comando V: Agregar una línea vertical que terminará en el punto indicado por el parámetro y.
  • Comando L: Agregar una línea que terminará en las coordenadas indicadas por los parámetros x e y.
  • Comando A: Agregar un arco. Acepta los parámetros rx, ry, x-axis-rotation, large-arc-flag, sweep-flag x e y, que representan el radio de la elipsis en la coordenada x, el radio de la elipsis en la coordenada y, la rotación en grados del eje x, la opción de que el arco sea mayor o menor a 180º, la opción de que el arco se mueva o no a posiciones positivas o negativas, la coordenada x y la coordenada y respectivamente.
  • Comando Q: Crea una curva Bézier y acepta tres conjuntos de coordenadas como parámetros. Las coordenadas x1 e y1 son el primer conjunto de coordenadas y son el punto en el que comienza la curva. Las coordenadas x2 e y2 son el segundo conjunto de coordenadas y representan la curvatura o inclinación de la línea en cada coordenada. Si has usado alguna aplicación visual de gráficos vectoriales, son los puntos equivalentes a los elementos que te permiten inclinar las líneas en dichas aplicaciones. Finalmente, las coordenadas x e y son el tercer conjunto de coordeadas e indican en dónde terminará la curva.
  • Comando Z: Mueve el cursor al punto en el que se ha comenzado a dibujar el conjunto de líneas y cierra el gráfico con una línea.

A continuación puedes ver un ejemplo en el que creamos una serie de líneas mediante la etiqueta path:

<svg height="300" width="300">
	<path
		d="M150 0 L75 200 L225 200 Z"
		fill="#0092b7"
		stroke="#000"
		stroke-width="3"
	/>
</svg>

Este sería el resultado:

Etiqueta SVG textPath

La etiqueta textPath permite agregar un texto que seguirá la forma de una línea definida. Como parámetro, acepta una referencia al identificador asociado a la línea que debe seguir el texto. En el siguiente ejemplo definimos primero un path y le asignamos un identificador. Para definir el path y no dibujarlo lo incluimos en el interior de la etiqueta defs. Seguidamente, dibujamos el path mediante le etiqueta use y agregamos el texto, al que asociamos con el path definido mediante el atributo xlink:href:

<svg viewBox="0 0 800 500" >
  <defs>
    <path id="miPath" d="M 20 40 Q 260 200 400 400" />
  </defs>
  <use xlink:href="#miPath" fill="none" stroke="#0092b7" />
  <text font-family="Arial" font-size="42.5">
    <textPath xlink:href="#miPath">
      Ejemplo de uso de textPath
    </textPath>
  </text>
</svg>

Este sería el resultado:

 

Etiqueta SVG polygon

La etiqueta polygon permite dibujar un polígono definiendo secuencialmente el conjunto de puntos del mismo mediante el atributo points. Los pares de coordenadas (x, y) se separan con espacios y las coordenadas de cada par se separan por una coma ,. El polígono se rellenará con el color indicado por el atributo fill. A continuación puedes ver un ejemplo:

<svg height="210" width="500">
  <polygon points="200,10 250,190 160,210" fill="#0092b7" />
</svg>

Este sería el resultado:

Etiquetas no gráficas del formato SVG

Existen una serie de elementos de apoyo que permiten gestionar mejor los elementos SVG visibles. A continuación vamos a ver los más relevantes.

Etiqueta SVG symbol

Mediante la etiqueta symbol podrás definir una imagen SVG una vez y reutilizarla posteriormente en varios lugares. Además, podrás cambiar algunas propiedades cuando la vuelvas a utilizar.

En el siguiente ejemplo agregamos un elemento symbol junto con un identificador que nos permitirá tener una referencia a los elementos que definamos en su interior:

<svg class="hidden">
  <symbol id="mi-elemento" viewBox="0 0 80 80">
    <rect x="0" y="0" width="80" height="10" fill="red" />
  </symbol>
</svg>

Etiqueta SVG defs

Si quieres, puedes definir elementos individuales pero sin que se muestren en pantalla, dejándolos listos para poder ser usados más de una vez posteriormente. Para ello debes definir los elementos en el interior de la etiqueta defs:

<svg width="80" height="10">
  <defs>
    <rect id="mi-elemento" x="0" y="0" width="80" height="10" fill="red" />
  </defs>
</svg>

Etiqueta SVG use

Podrás mostrar cualquier elemento ya definido mediante la etiqueta defs o mediante la etiqueta symbol utilizando la etiqueta use, indicando el identificador del mismo mediante el atributo xlink:href:

<svg width="80" height="10">
  <use xlink:href="#mi-elemento" href="mi-elemento" />
</svg>

El atributo xlink:href ya está obsoleto, pero se incluye por temas te compatibilidad con el navegador Safari.

Si quieres, puedes aplicar estilos diferentes a los elementos que muestres mediante le etiqueta use. Para ello puedes utilizar variables CSS. Primero vamos a declarar un símbolo junto con una variable CSS como valor de la propiedad fill:

<svg class="hidden">
  <symbol id="mi-elemento" viewBox="0 0 20 20">
    <rect x="0" y="0" width="80" height="10" fill="var(--color)" />
  </symbol>
</svg>

Seguidamente, vamos a representar dos versiones diferentes del mismo símbolo aplicando una clase CSS diferente a la etiqueta SVG:

<svg class="red">
  <use xlink:href="#mi-elemento" href="#mi-elemento" />
</svg>

<svg class="blue">
  <use xlink:href="#mi-elemento" href="#mi-elemento" />
</svg>

<style>
  svg.blue {
    --color: blue;
  }
  svg.red {
    --color: red;
  }
</style>

Ese sería el resultado, en donde puedes ver que cada rectángulo se muestra de un color diferente:

Etiqueta SVG g

Le etiqueta g permite agrupar múltiples elementos en un grupo al que es posible dotar de un identificador.  Aquí tienes un ejemplo:

<svg width="200" height="200">
  <g id="mi-grupo">
    <rect x="0" y="90" width="90" height="90" fill="#0092b7" />
    <rect x="90" y="0" width="90" height="90" fill="#8416bf" />
  </g>
</svg>

Este sería el resultado:

Gestión del espacio visible

El tamaño de un elemento SVG siempre será relativo al elemento que lo contiene. Podemos configurar el espacio visible usando tanto el viewport como el atributio viewBox.

Viewport SVG

El viewport SVG es el área visible del elemento SVG, independientemente de su contenido. El viewport se define mediante mediante los atributos width y height de la etiqueta SVG. Estos atributos se definen en pixels por defecto, aunque también pueden estar definidos en porcentajes % o unidades em.

El viewport debería dejar ver todo el área visible de sus contenidos.

<svg width="100" height="100">
  <ellipse cx="50" cy="50" rx="50" ry="50" fill="#8416bf"></ellipse>
</svg>

Este sería el resultado:

Si el contenido del elemento SVG desborda el viewport definido, la imagen resultante aparecerá recortada. En el siguiente ejemplo, el viewport de 50xp x 50px es menor que el tamaño del círculo definido en su interior, ya que un círculo de 50px de radio tiene 100px de diámetro.

<svg width="50" height="50">
  <ellipse cx="50" cy="50" rx="50" ry="50" fill="#8416bf"></ellipse>
</svg>

Este sería el resultado:

ViewBox SVG

El atributo viewBox te permite definir un sistema de coordenadas visibles en el interior del elemento SVG. Permite seleccionar un área y aplicar un zoom a la misma, obteniendo una panorámica de la imagen diferente en función de sus valores.

El atributo viewBox acepta dos pares de valores, organizados en cuatro parámetros que van uno tras otro, separados por espacios:

  • Plano: Los dos primeros parámetros del atributo viewBox indican la posición de la cámara con respecto al área del elemento SVG. El primero valor controla la posición horizontal y el segundo la vertical. Estos valores sirven para indicar la posición superior izquierda de la cámara, partiendo del origen. Acepta tanto valores positivos como negativos.
  • Aumento: Los dos últimos parámetros del atributo viewBox permiten aumentar o reducir el plano visible, aceptando tanto valores positivos como negativos para ambos valores.

Vamos a partir del siguiente ejemplo, en el que definimos un círculo en formato SVG de de 200px x 200px:

<svg width="200" height="200">
  <circle cx="100" cy="100" r="100" fill="#8416bf" />
</svg>

La representación del círculo anterior es la siguiente:

Mediante el atributo viewBox vamos a mostrar una porción del círculo anterior haciendo un aumento, manteniendo el área de visualización y mostrando en ese mismo área una porción de 100px x 100px del círculo:

<svg width="200" height="200" viewBox="0 0 100 100">
  <circle cx="100" cy="100" r="100" fill="#8416bf" />
</svg>

Este es el resultado tras aplicar el zoom:

Si ahora mantenemos ese mismo aumento pero movemos el plano, veremos otra porción del círculo con ese mismo zoom. Vamos a moverlo a las coordenadas (100px, 100px):

<svg width="200" height="200" viewBox="100 100 100 100">
  <circle cx="100" cy="100" r="100" fill="#8416bf" />
</svg>

Este es el resultado tras mover el plano a otras coordenadas manteniendo el zoom:

Lo que estamos haciendo es lo equivalente a moverse o aplicar un zoom en cualquier aplicación de GPS. De hecho, aplicaciones como Google Maps funcionan con gráficos vectoriales, ya que cuando te desplazas por el mapa únicamente cambias las coordenadas (x, y). Del mismo modo, cuando redimensionas un mapa, cambias la anchura y la altura del viewBox.

Cómo insertar una imagen SVG

Puedes insertar imágenes SVG en una página de diversas formas. Ya hemos visto cómo insertar un archivo SVG usando la etiqueta img y también cómo insertar el código SVG directamente en el código HTML. Sin embargo, también podemos insertar imágenes SVG como fondo usando la propiedad background-image de CSS, o también usando las etiquetas object, iframe y embed. A continuación vamos a ver cada uno de estos casos.

Utiliza una etiqueta svg

Mediante la etiqueta svg podemos crear imágenes vectoriales en línea, directamente en nuestro código HTML. En el siguiente ejemplo agregamos una bandera:

<svg width="200" height="300" viewBox="0 0 200 300" version="1.1" >
  <desc>Bandera de España</desc>
  <g id="flag">
    <rect fill="red" x="0" y="0" width="200" height="40"></rect>
    <rect fill="yellow" x="0" y="40" width="200" height="70"></rect>
    <rect fill="red" x="0" y="110" width="200" height="40"></rect>
  </g>
</svg>

Utiliza una etiqueta img

Si tienes una imagen en formato SVG, puedes insertarla mediante una etiqueta img, haciendo referencia al archivo SVG:

<img src="tortuga.svg" alt="Tortuga" />

Hemos proporcionado también una descripción, útil si quieres que tu página sea más accesible.

También puedes agregar el código SVG en línea mediante la etiqueta img usando una Data URL que incluya los datos. En el siguiente ejemplo deberías reemplazar {DATA} por los datos de la imagen:

<img src="data:image/svg+xml;{DATA}" alt="Tortuga" />

Utiliza una etiqueta object

También puedes insertar un archivo en formato SVG usando la etiqueta genérica object, siempre y cuando especifiques el tipo de objeto como image/svg+xml mediante el atributo type:

<object data="tortuga.svg" type="image/svg+xml"></object>

También puedes incluir el código del archivo SVG en línea usando una Data URL como valor del atributo src de la etiqueta object. En el siguiente ejemplo deberías reemplazar {DATA} por los datos de la imagen:

<object data="data:image/svg+xml;{DATA}" type="image/svg+xml"></object>

Si no se especifica un tamaño para el elemento object, variará su tamaño para adaptarse al elemento SVG.

Utiliza una etiqueta iframe

Aunque no es muy habitual, también puedes insertar imágenes SVG usando la etiqueta iframe, especificando el archivo SVG como origen:

<iframe src="tortuga.svg" frameborder="0"></iframe>

También es posible incluir el código del archivo SVG en línea usando una Data URL como valor del atributo src de la etiqueta iframe. En el siguiente ejemplo deberías reemplazar {DATA} por los datos de la imagen:

<iframe data="data:image/svg+xml;{DATA}" frameborder="0"></iframe>

Siempre que se use un iframe para cargar un archivo SVG debe especificarse un tamaño para el mismo, ya que de lo contrario puede que se recorte la imagen SVG.

Utiliza una etiqueta embed

Otra alternativa no demasiado común consiste en usar la etiqueta embed para insertar imágenes SVG:

<embed src="tortuga.svg" type="" />

La ventaja de usar la etiqueta embed consiste en que puedes hacer referencia al objeto que contiene la imagen SVG para extraerla del mismo:

<embed id="imagen-tortuga" src="tortuga.svg" type="" />

Mediante JavaScript, extraemos la imagen SVG mediante el método getSVGDocument:

document.getElementById('imagen-tortuga').getSVGDocument()

Además, también puedes hacer referencia al documento principal desde el interior de la imagen SVG:

window.parent.document

Si no se especifica un tamaño para el elemento embed, variará su tamaño para adaptarse al elemento SVG.

Propiedad CSS background-image

Ya sea mediante el código CSS de un archivo CSS o desde el código CSS agregado en nuestros archivos HTML, podemos establecer una imagen SVG como fondo de otro elemento mediante la propiedad background-image.

En el siguiente ejemplo agregamos la clase CSS svg-background, a cuyos elementos asignaremos una imagen SVG como fondo:

<style>
  .bandera-svg {
    background-image: url(bandera.svg);
    height: 300px;
    width: 200px;
  }
</style>
<div class="bandera-svg"></div>

También puedes incluir los datos de la imagen como una Data URL, reemplazando {DATA} por los datos de la imagen:

.bandera-svg {
  background-image: url('data:image/svg+xml;{DATA}');
}

Aspecto general de los elementos SVG

Existen ciertos atributos que puedes utilizar para cambiar el aspecto de los elementos SVG. Por ejemplo, puedes usar los siguientes atributos:

  • fill: Cambia el color de relleno de un elemento.
  • stroke: Cambia el color del borde de un elemento.
  • stroke-width: Modifica el ancho del borde de un elemento.
  • fill-opacity: Cambia la opacidad del elemento con un valor entre 0 y 1.

En el siguiente ejemplo usamos estos atributos para modificar el color y el borde del círculo:

<svg width="250" height="250">
  <circle cx="125" cy="125" stroke-width="5" stroke="#000"; r="100" fill="#8416bf" />
</svg>

Este sería el resultado:

Cómo usar estilos CSS con elementos SVG

Podrás aplicar estilos CSS a elementos SVG siempre y cuando el código SVG se agregue en línea o mediante las etiquetas object, embed o iframe, aunque según el navegador que utilices, en estos últimos tres casos puede ser un requerimiento que la imagen se cargue desde el mismo dominio, utilizando el mismo protocolo de la página para cumplir con la política del mismo origen «same-origin».

Si la imagen SVG se carga mediante la etiqueta img o como fondo en una hoja de estilos CSS, los estilos CSS no afectarán a estos elementos en ningún caso. Además, estos elementos no se cargarán si se trata de recursos externos que son cargados desde otro dominio.

Las imágenes SVG definidas en línea son, sin lugar a duda, las más útiles y flexibles, ya que aceptarán todas las operaciones posibles. Si quieres modificar una imagen SVG mediante estilos CSS y que los estilos se apliquen en todos los casos, la imagen debe estar definida en línea. Sin embargo, las imágenes SVG definidas mediante etiquetas img, object o embed tienen la ventaja de que pueden reutilizarse en más partes del código.

Código CSS en línea

Los elementos SVG aceptan también el atributo style, mediante el cual podrás agregar estilos CSS. Sin embargo, debido a la naturaleza de los elementos SVG, no todas las propiedades CSS funcionarán tal y como esperas.

Por ejemplo, el atributo color no cambiará el color de un elemento SVG aunque agregues texto; para ello deberás usar el atributo fill:

<svg>
  <text x="10" y="20" style="fill: red;">Texto en rojo</text>
</svg>

Del mismo modo, también podrás usar la propiedad fill-opacity para cambiar la opacidad del elemento, la propiedad stroke para cambiar el color de borde y la propiedad stroke-width para modificar el ancho del borde:

<svg width="250" height="250">
  <circle cx="125" cy="125" r="100" style="fill:#8416bf; fill-opacity:0.9; stroke-width:5; stroke:#000;" />
</svg>

Código CSS en la etiqueta SVG

Puedes agregar estilos CSS en el interior de la etiqueta SVG usando la directiva CDATA:

<svg>
  <style>
    <![CDATA[
      #mi-circulo { fill: #8416bf; }
    ]]>
  </style>
  <circle id="mi-circulo" cx="125" cy="125" r="100" />
</svg>

También puedes agregar una referencia a una hoja de estilos externa:

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/css" href="estilos.css"?>
<svg
  xmlns="http://www.w3.org/2000/svg"
  version="1.1"
  width=".."
  height=".."
  viewBox=".."
>
  <circle id="mi-circulo" cx="125" cy="125" r="100" />
</svg>

Código CSS fuera de la etiqueta SVG

Puedes modificar un elemento SVG mediante código CSS localizado o incluido fuera de la etiqueta SVG:

<style>
  #mi-circulo {
    fill: #8416bf;
    stroke-width: 5;
    fill: #8416bf;
    fill-opacity: 0.9;
  }
</style>
<circle id="mi-circulo" cx="125" cy="125" r="100" fill="#000" />

Los atributos de los elementos SVG tienen menor prioridad que las propiedades CSS, por lo que siempre podrás sobrescribir cualquier atributo por su respectiva propiedad CSS:

Cómo usar JavaScript con elementos SVG

Podrás utilizar scripts de JavaScript para interactuar con imágenes SVG siempre y cuando el código SVG se agregue en línea o se cargue mediante las etiquetas  object, embed o iframe. En estos últimos tres casos, la imagen debe cargarse desde el mismo dominio para cumplir con la política «same-origin».

Si la imagen SVG se carga mediante la etiqueta img, no será posible interactuar con ella mediante JavaScript y, además, los scripts definidos en el interior del archivo SVG estarán desactivados. Del mismo modo, los recursos externos a los que se haga referencia en el archivo SVG tampoco se cargarán.

Estas son las condiciones generales de los diferentes métodos de carga de archivos SVG en relación con JavaScript:

  • SVG en línea: Soporta animaciones y puede ejecutar tanto su propio código JavaScript como el definido externamente.
  • Etiqueta object: Soporta animaciones y puede ejecutar su propio código JavaScript, pero no el definido externamente.
  • Etiqueta embed: Soporta animaciones y puede ejecutar su propio código JavaScript, pero no el definido externamente.
  • Etiqueta iframe: Soporta animaciones y puede ejecutar su propio código JavaScript, pero no el definido externamente.
  • Etiqueta img: Soporta animaciones, pero no puede ejecutar ni su propio código JavaScript ni el definido externamente.

El SVG en línea es el mejor modo de definir la imagen cuando quieres garantizar la compatibilidad total con JavaScript.

Código JavaScript en la etiqueta SVG

Puedes agregar código JavaScript en el interior de una etiqueta SVG. Para ello, debes usar la directiva CDATA e incluir el código JavaScript en el evento load, de modo que se ejecute cuando la página se haya cargado, momento en el que la imagen SVG ya estará presente en el DOM:

<svg>
  <script>
    <![CDATA[ window.addEventListener("load", () => { ... }, false) ]]>
  </script>
  <circle cx="100" cy="100" r="100" fill="#8416bf" />
</svg>

También puedes obviar por el evento load si incluyes el código JavaScript después del código SVG al que hace referencia:

<svg>
  <circle cx="100" cy="100" r="100" fill="#8416bf" />
  <script>
    <![CDATA[ //... ]]>
  </script>
</svg>

Podrás interactuar con cualquier elemento definido en el gráfico SVG mediante los selectores JavaScript, por lo que es conveniente agregarles una clase o un identificador:

<svg>
  <circle id="mi-circulo" class="circulo" cx="100" cy="100" r="100" fill="#8416bf" />
  <script>
    <![CDATA[
      console.log(document.getElementsByTagName('circle'));
      console.log(document.getElementById('mi-circulo'));
      console.log(document.querySelector('.circulo'));
      console.log(document.querySelectorAll('.circulo'));
    ]]>
  </script>
</svg>

Código JavaScript fuera de la etiqueta SVG

Siempre y cuando los elementos SVG estén definidos en línea en el código HTML, podrás utilizar código JavaScript externo a los elementos SVG para interactuar con dichos elementos:

<svg>
  <circle cx="100" cy="100" r="100" fill="#8416bf" />
</svg>

El código JavaScript que ves a continuación cambiará el color del círculo:

document.getElementById('mi-circulo').setAttribute('fill', '#000');

Diferencias entre elementos SVG y Canvas

La API Canvas también se utiliza para representar gráficos, al igual que la API SVG. Ambas tienen una gran compatibilidad a día de hoy con casi cualquier navegador. La mayor diferencia radica en que la API Canvas no se basa en elementos vectoriales sino en pixels, sufriendo los mismo problemas de escalado que los formatos de imagen basados en pixels, como los formatos JPG, PNG, GIF o WebP.

Es imposible modificar los elementos que hay dentro de un Canvas usando CSS o JavaScript del mismo modo que lo hacemos con los elementos SVG. Ahora seguramente estés pensando en los montones de motores gráficos, como Phaser o PixiJS, que usan JavaScript con la API Canvas. Lo cierto, es que estos motores gráficos refrescan la imagen completa del Canvas para dar sensación de movimiento al igual que la mayor parte de motores gráficos. Es decir, su funcionamiento interno es completamente diferente al de los elementos SVG.

Validación XML de elementos SVG

Los archivos SVG pueden contener elementos inválidos que no se adapten al estándar SVG, por lo que las imágenes podrían no representarse correctamente. Además, muchas aplicaciones no aceptarán imágenes SVG inválidas.

Para validar si una imagen SVG puedes usar el validador SVG W3C, en donde podrás especificar un enlace al archivo SVG, subir un archivo SVG o pegar el código del elemento SVG.

Compatibilidad

Actualmente el formato SVG es ampliamente soportado por casi todos los navegadores. De todos modos, no está de más tener en cuenta que no funcionará con Internet Explorer 8 y versiones anteriores. Este formato tampoco funcionará con los navegadores de algunos terminales Android antiguos, algo poco común. De todos modos, ya existen soluciones contempladas para ambos casos.

A continuación puedes ver la tabla de compatibilidad del formato SVG con los navegadores más utilizados a día de hoy:

Existen librerías como Modernizr que permiten comprobar si el navegador soporta el formato SVG. De no estar soportado, siempre puedes mostrar una imagen en otro formato en lugar de la imagen SVG:

if (!Modernizr.svg) {
  document.querySelector('#elemento').setAttribute('src', 'imag/elemento.png')
}

Esto ha sido todo.


Avatar de Edu Lazaro

Edu Lázaro: Ingeniero técnico en informática, actualmente trabajo como desarrollador web y programador de videojuegos.

👋 Hola! Soy Edu, me encanta crear cosas y he redactado esta guía. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirla en Twitter 😊

Si quieres conocer mis proyectos, sígueme en Twitter.

2 comentarios en “Tutorial de SVG: Qué es y cómo se utiliza

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

“- Hey, Doc. No tenemos suficiente carretera para ir a 140/h km. - ¿Carretera? A donde vamos, no necesitaremos carreteras.”