SVG

En esta lección se trata la etiqueta principal de SVG, la etiqueta <svg>. Las formas básicas SVG (líneas, rectángulos, círculos, cuvas, etc.) se comentan en la lección Formas SVG.

Qué es SVG

SVG (Scalable Vector Graphics = Gráficos Vectoriales Escalables) es un lenguaje de marcas creado por el W3C y dirigido a la representación de gráficos vectoriales (dibujos y texto).

En la lección sobre Historia de la Web) se comentan las recomendaciones de SVG publicadas o en preparación por el W3C.

En un gráfico vectorial, los elementos de la imagen están definidos como formas elementales (líneas, rectángulos, círculos, curvas, polígonos, etc.), definidas mediante etiquetas simlares a las del HTML. Por ello SVG no es un formato adecuada para fotografías, pero es idóneo para cualquier tipo de dibujo, técnico o artístico.

Las ventajas de SVG son muchas:

Un gráfico SVG puede incluirse en una página web de dos maneras, como objeto interno o como objeto externo.

Desgraciadamente, el uso de SVG no está todo lo extendido que debería, entre otros motivos porque las implementaciones de las recomendaciones todavía son incompletas, pero sobre todo porque Internet Explorer no fue capaz de mostrar gráficos SVG hasta IE 9. Pero SVG se va imponiendo poco a poco como formato estándar de gráficos vectoriales frente a otros formatos propietarios y numerosos programas de edición de gráficos son capaces de importar y exportar en formato SVG.

Para saber más

La etiqueta <svg>

La etiqueta <svg> engloba la imagen SVG e incluye las formas que forman la imagen.

Una imagen SVG puede incluirse en una página web directamente o mediante la etiqueta <img />, como se comenta en la lección Imágenes.

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
width="170" height="165" viewBox="0 0 170 165">
<polygon fill="yellow" stroke="red" stroke-width="7"
points="129,150 85,119 41,150 57,104 15,66
68,66 85,15 102,65 156,66 113,98" />
</svg>

El plano SVG

Los dibujos SVG se definen en un plano infinito en el que el eje Y está orientado hacia abajo, como muestra el dibujo siguiente.

Y X (100, 100) (100, -100) (-100, -100) (-100, 100)

Atributos de <svg>

Los atributos version y xmlns de <svg>

El atributo version indica la versión de SVG empleada en el dibujo. En estos apuntes se utiliza la versión 1.1.

El atributo xmlns indica el espacio de nombres empleada en el dibujo, es siempre https://www.w3.org/2000/svg.

El atributo viewBox

El atributo viewBox establece la porción del plano SVG que muestra la imagen. Este atributo se establece con cuatro valores:

Y X viewBox="-100 -50 200 150" (-100, -50) (100, -50) (100, 100) (-100, 100)

La imagen siguiente muestra los ejes de coordenadas y un círculo de radio 100 centrado en el origen. La zona visible definida por viewBox empieza arriba a la izquierda en el punto (-100, -100) y tiene un tamaño de 200 x 200, por lo que se ve todo el círculo.

Correcto en Firefox Incorrecto en Internet Explorer Correcto en Chrome
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
  width="200" height="200" viewBox="-100 -100 200 200"
  style="background-color: lightgray">
  <circle cx="0" cy="0" r="100" fill="none" stroke="red" stroke-width="1" />
  <line x1="-200" y1="0" x2="200" y2="0" stroke="black" stroke-width="1" />
  <line x1="0" y1="-200" x2="0" y2="200" stroke="black" stroke-width="1" />
</svg>

Si en ese mismo dibujo la zona visible empieza en el punto (-5, -5) y tiene un tamaño de 105 x 105 sólo se verá el primer cuadrante (valores X e Y positivos).

Correcto en Firefox Incorrecto en Internet Explorer Correcto en Chrome
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
  width="105" height="105" viewBox="-5 -5 105 105"
  style="background-color: lightgray">
  <circle cx="0" cy="0" r="100" fill="none" stroke="red" stroke-width="1" />
  <line x1="-200" y1="0" x2="200" y2="0" stroke="black" stroke-width="1" />
  <line x1="0" y1="-200" x2="0" y2="200" stroke="black" stroke-width="1" />
</svg>

Para mostrar el tercer cuadrante (valores X e Y negativos, la zona visible podría empezar en el punto (-100, -100) y tener un tamaño de 105 x 105.

Correcto en Firefox Incorrecto en Internet Explorer Correcto en Chrome
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
  width="105" height="105" viewBox="-100 -100 105 105"
  style="background-color: lightgray">
  <circle cx="0" cy="0" r="100" fill="none" stroke="red" stroke-width="1" />
  <line x1="-200" y1="0" x2="200" y2="0" stroke="black" stroke-width="1" />
  <line x1="0" y1="-200" x2="0" y2="200" stroke="black" stroke-width="1" />
</svg>

Los atributos width y height de <svg>

El atributo viewBox establece la porción del plano SVG que se muestra en la imagen , mientras que los atributos width y height establecen el ancho y el alto de la imagen en la página web.

Así, una misma imagen en el plano SVG se puede ver en la página web más o menos grande:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
  width="100" height="100" viewBox="-50 -50 100 100"
  style="background-color: lightgray">
  <circle cx="0" cy="0" r="50" fill="none" stroke="red" stroke-width="1" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
  width="200" height="200" viewBox="-50 -50 100 100"
  style="background-color: lightgray">
  <circle cx="0" cy="0" r="50" fill="none" stroke="red" stroke-width="1" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
  width="50" height="50" viewBox="-50 -50 100 100"
  style="background-color: lightgray">
  <circle cx="0" cy="0" r="50" fill="none" stroke="red" stroke-width="1" />
</svg>

Simplificar una imagen hecha con Inkscape

Las imágenes SVG se pueden crear escribiendo las etiquetas directamente en un procesador de textos (como Brackets), pero también se pueden utilizar editores gráficos como Inkscape o descargar de repositorios como Open Clip Art. El problema es que Inkscape genera más código del necesario, por lo que a veces puede resultar conveniente simplificar ese código.

Si se crea con Inkscape la imagen de la estrella de los ejemplos anteriores y se guarda la imagen como SVG plano, se obtendría un código fuente similar a este:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!-- Created with Inkscape (https://inkscape.org/es/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="https://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="https://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1"
   width="100"
   height="100"
   id="svg2">
  <defs
     id="defs4" />
  <metadata
     id="metadata7">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     transform="translate(-100.10292,-228.90234)"
     id="layer1">
    <polygon
       points="124,145 80,114 36,145 52,93 10,61 63,61 80,10 97,60 151,61 108,93 "
       transform="matrix(0.60688557,0,0,0.60646101,101.24863,231.90161)"
       id="polygon4069"
       style="fill:#ffff33;stroke:#ff0000;stroke-width:7.30069113" />
  </g>
</svg>

Para insertarla en un documento html 5 es necesario eliminar parte de este código:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!-- Created with Inkscape (https://inkscape.org/es/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="https://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="https://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1"
   width="100"
   height="100"
   id="svg2">
  <defs
     id="defs4" />
  <metadata
     id="metadata7">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     transform="translate(-100.10292,-228.90234)"
     id="layer1">
    <polygon
       points="124,145 80,114 36,145 52,93 10,61 63,61 80,10 97,60 151,61 108,93 "
       transform="matrix(0.60688557,0,0,0.60646101,101.24863,231.90161)"
       id="polygon4069"
       style="fill:#ffff33;stroke:#ff0000;stroke-width:7.30069113" />
  </g>
</svg>

Por lo que la imagen quedaría:

<svg
   width="100"
   height="100"
   id="svg2">
  <g
     transform="translate(-100.10292,-228.90234)"
     id="layer1">
    <polygon
       points="124,145 80,114 36,145 52,93 10,61 63,61 80,10 97,60 151,61 108,93 "
       transform="matrix(0.60688557,0,0,0.60646101,101.24863,231.90161)"
       id="polygon4069"
       style="fill:#ffff33;stroke:#ff0000;stroke-width:7.30069113" />
  </g>
</svg>

Ese código se puede simplificar todavía más, hasta obtener el código que se ha utilizado en esta lección:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
  width="170" height="165" viewBox="0 0 170 165">
  <polygon fill="yellow" stroke="red" stroke-width="7"
    points="129,150 85,119 41,150 57,104 15,66 68,66 85,15 102,65 156,66 113,98" />
</svg>