Como utilizar SVG

facebook-svg gplus-svg twitter-svg

Probablemente la mejor opción es utilizar los elementos SVG dentro del documento HTML, como parte de este.

Me gusta guardar los iconos como grupos <g> o símbolos <symbol> dentro de un elemento SVG raíz cuya anchura y altura son 0 y position:absolute; para poder echarlo del layout, por ejemplo con left: -100em;.

Para que este elemento SVG no estorbe en el código lo pongo al inicio o al final del <body> muchas veces como <?php include....

Esto me permite utilizar los iconos cuando los necesite con <use>. También me permite interactuar con el SVG, manipularlo con JavaScript o con CSS para animarlo o cambiar el color según el caso.

Además de utilizar elementos SVG dentro del documento HTML podemos utilizar documentos SVG como imágenes <img> objetos <object> elementos <iframe> y <embed>. También podemos utilizar estos documentos SVG como imagen de fondo background-image en CSS. Sin embargo utilizarlos de esta manera tiene desventajas ya que perdemos la posibilidad de interactuar fácilmente con la imagen.

1. Imágenes SVG

Los documentos SVG pueden ser utilizados como imagen ( <img src= "apple.svg"... ) dentro de un documento HTML ya existente.

la manzana de apple

Desventajas:
-El SVG en imágenes no carga los ficheros externos como por ejemplo documentos Javascript o CSS enlazados.
-Los elementos dentro del documento SVG utilizado como imagen no interactúan con el ratón.
-Tampoco podrán ser modificados utilizando JavaScript o CSS  del documento HTML que utiliza la imagen.

2. SVG como imágenes de fondo

También podemos utilizarlos como imagen de fondo: background-image: url(apple.svg);.

div.bcg {
  background-image: url(apple.svg);
  background-repeat: no-repeat;
  background-position:center center;
}

Este método tiene las mismas limitaciones que las imágenes <img>.

3. SVG como objeto <object>

El elemento <object> es actualmente soportado en todos los navegadores, pero, por si acaso, tenemos la opción de utilizar una solución alternativa (fallback). En este caso utilizamos una imagen "apple.png" dentro de este elemento que aparecerá en pantalla solo en los navegadores que no soportan <object>.


  
  la manzana de apple

A diferencia de imágenes ( de fondo o no ) si utilizamos documentos svg incrustados dentro de un objeto <object>:
- podemos utilizar ficheros css y js externos dentro del documento SVG.
- los elementos del documento SVG serán sensibles al ratón.
Pero:
-No podrán ser modificados utilizando JavaScript o CSS del documento HTML que utiliza el objeto.

4. SVG dentro de un cuadro iframe

Exactamente como en el caso de <object>, el elemanto <iframe> es actualmente soportado en todos los navegadores, pero, por si acaso, tenemos la opción de utilizar una solución alternativa (fallback). En este caso utilizamos una imagen "apple.png" dentro de este elemento que aparecerá en pantalla solo en los navegadores que no soportan <iframe>.

Como en el caso de <object>, si utilizamos documentos svg incrustados dentro de un <iframe>:
- podemos utilizar ficheros css y js externos dentro del documento SVG.
- los elementos del documento SVG serán sensibles al ratón.
Pero:
-No podrán ser modificados utilizando JavaScript o CSS del documento HTML que utiliza el iframe.

A diferencia de <object>, los elementos SVG incrustados no serán redimensionados para ajustarse a las dimensiones del <iframe>

5. SVG dentro de un elemento embed

También podemos incluir una imagen SVG dentro de un elemento <embed>:

Este método tiene las mismas limitaciones que los objetos <object>.

Vea todos estos ejemplos en codepen.io:

See the Pen SVG #1 by Gabi (@enxaneta) on CodePen.

6. SVG en el CSS como data:uri

Otra manera de utilizar las imágenes SVG es convertirlas a data:uri.
Podemos utilizar elementos SVG codificados de esta manera en CSS como imagen de fondo background-image o como valor de border-image-source para definir el origen de la imagen border-image utilizada para trazar el borde de un elemento HTML. También podemos utilizar elementos SVG codificados como valor del atributo src de una imagen <img> o de un <iframe> o como valor del atributo data de un elemento <object>

Una propuesta que se puede ver por ahí es utilizar el código SVG no codificado ( unencoded ) así:

.data-uri-unencoded{ background-image:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="106px" height="122px" viewBox="41 54 106 122"><g><path fill="#FFFFFF" stroke="#ED1D24" stroke-width="2" d="M143.099 . . . . /><svg>');
}

De hecho esto ya no funciona. Hagámoslo bien. Para optimizar el código vamos a seguir estas reglas:

a. Lo ponemos todo entre comillas dobles ( " ) y ponemos los atributos entre comillas sencillas ( por ejemplo height = '122px' ). De esta manera no tendremos que escaparlas.

b. Ciframos los caracteres no-alfanuméricos, los así llamados caracteres reservados o caracteres inseguros ( unsafe in URLs characters ) pero no los espacios en blanco:

< se transforma en %3C
> se transforma en %3E

Por ejemplo <svg> vuelve a ser %3Csvg%3E

# se transforma en %23

Por ejemplo fill = "#abcdef" vuelve a ser fill = "%23abcdef"

el guión - se transforma en %2D

Por ejemplo stroke-width="2" vuelve a ser stroke%2Dwidth="2"

el símbolo matemático porciento % se transforma en %25

Por ejemplo width ='50%' vuelve a ser width ='50%25'

.data-uri-encoded{ 
	background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='106px' height='122px' viewBox='41 54 106 122'%3E%3Cg%3E%3Cpath fill='%23FFFFFF' stroke='%23ED1D24' stroke%2Dwidth='2' d='M143.099 . . . . %3C/svg%3E";
}

Para una lista completa de los caracteres reservados y su codificación consulte Wikipedia: Código porciento
También puede leer este articulo en codepen.io: Optimizing SVGs in data URIs

Todo esto puede resultar muy tedioso pero la buena noticia es que hay herramientas que convierten el código SVG en data uri, por ejemplo el URL-encoder for SVG).
Solo hay que pegar el codigo SVG en el textarea donde pone Insert your SVG: y copiar el codigo que aparece en el textarea donde pone Ready for CSS: o Take encoded:.

See the Pen SVG-encoder by yoksel (@yoksel) on CodePen.

En el caso en que necesita codificar el svg de manera dinámica, a continuación viene un ejemplo de cómo hacerlo utilizando javascript:

Supongamos que hay este elemento SVG dentro de un elemento <div id="svgwrap">. El SVG no tiene que ser visible. Puede tener display:none;

En el JavaScript primero hay que recuperar el elemento SVG y transformarlo en una cadena de texto

let cadena = svgwrap.innerHTML.toString();

A continuación habrá que comprobar si el elemento SVG tiene el atributo xmlns que define el espacio de nombre, y si no lo tiene hay que agregarlo:

let conEspaciosDeNombre = agregarEspaciosDeNombre(cadena);

Y esta es la función agregarEspaciosDeNombre:

function agregarEspaciosDeNombre(cadena) {
  // si la cadena de texto NO contiene "http://www.w3.org/2000/svg"
  if (cadena.indexOf("http://www.w3.org/2000/svg") < 0) {
  // agregalo
    cadena = cadena.replace(/<svg/g, "<svg xmlns='http://www.w3.org/2000/svg'");
  }
  // y devuelve la cadena de texto modificada
  return cadena;
}

Aquí viene lo más importante : codificar la cadena de texto para poder ser utilizada como url:

let escapado = encodeSVG(conEspaciosDeNombre);

Donde encodeSVG es una función que primero cambia las comillas dobles por silmles y después toma todos los símbolos que hay que codificar y los reemplaza con los valores codificados de estos

function encodeSVG(cadena) {
  let simbolos = /[\r\n%#()<>?\[\\\]^`{|}]/g;
  // reemplaza las comillas dobles con simples
  cadena = cadena.replace(/"/g, "'");
  //devuelve la cadena de texto codificada
  return cadena.replace(simbolos, encodeURIComponent);
}

Una vez que tengamos el valor escapado lo podemos utilizar como imagen de fondo

let src =  `data:image/svg+xml,${escapado}`;
let dataURI = `url("${src}")`;
// establece la imagen de fondo del elemento svgbg
svgbg.style.backgroundImage = dataURI;
// establece la imagen para el borde del elemento svg_border
svg_border.style.borderImageSource  = dataURI;
// establece el valor del atributo src del elemento svgimg
svgimg.src = src;

See the Pen SVG to data URI by Gabi (@enxaneta) on CodePen.

Convertir el código SVG a base64

Otra propuesta sería convertir primero el código SVG a base64 y después utilizarlo.

<a href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0. . . ">Imagen SVG</a>

En internet encontramos herramientas que codifican una cadena de texto en base64:
https://www.base64encode.org/
http://www.mobilefish.com/services/base64/base64.php
Y seguramente hay más.

También podemos utilizar PHP con este propósito: para ser más exactos lo podemos hacer utilizando la función base64_encode (PHP 4, PHP 5).

Veamos un ejemplo:


$svg_img ="<svg xmlns='http://www.w3.org/2000/svg'> . . . . </svg>";
$data_URI = base64_encode ( $svg_img );
echo "<a href='data:image/svg+xml;base64,".$data_URI."'>Abra esta imagen y mire la barra de direcciones</a>";