SVG tiene un <use>
elemento que esencialmente significa: ve a buscar el trozo de SVG que tiene este #identificador y clónalo y colócalo aquí. Es un ingrediente esencial para un sistema de iconos SVG. Hay algunas cosas que debe saber sobre esto que no hemos cubierto antes.
Como recordatorio, se ve así:
<!-- Reference IN THIS SAME DOCUMENT -->
<svg>
<use xlink:href="https://css-tricks.com/svg-use-with-external-reference-take-2/#icon-1"></use>
</svg>
<!-- EXTERNAL reference -->
<svg>
<use xlink:href="sprite.svg#icon-1"></use>
</svg>
Que ese identificador #icon-1 probablemente haga referencia a un símbolo en ese archivo, como…
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="icon-1" viewBox="0 0 1024 1024">
<title>Kinda like alt text</title>
<path class="path-1" d="..."></path>
</symbol>
...
</svg>
La belleza de una referencia externa es que aprovecha bien la memoria caché del navegador.
También que es fácil de trabajar. Pones la ruta de archivo correcta al archivo (el “sprite SVG”) y haces referencia a un identificador, y simplemente funciona. Puede configurar su servidor para servir ese archivo con todos los encabezados correctos, de modo que el navegador se aferre a él como lo haría con cualquier otro activo que desee almacenar en caché.
El problema era IE, pero se está solucionando.
La mayoría de los navegadores que admitían SVG en línea admitían esto, por lo que era casi utilizable, con la gran excepción de IE. Pero ahora lo han arreglado en Microsoft Edge. Edge aún no tiene una participación de mercado masiva, pero es el futuro en Windows, por lo que eventualmente podremos comenzar a usar esto sin ningún trabajo adicional.
Debido a la falta de un soporte perfecto, existen dos opciones principales de solución alternativa.
- Incluya el sprite SVG en todos los documentos HTML. Funciona genial. Tiende a ser muy rápido, pero infla el caché de la página. Y para obtener el mejor soporte, debe incluirlo en la parte superior del documento, lo que significa un retraso leve en la representación de contenido probablemente más importante. O…
- Ajax para el sprite. Que luego puede aprovechar el almacenamiento en caché del navegador. Sin embargo, puede ser complicado hacer esto sin un poco de FONI (Flash of No Icons).
Una vez que podemos empezar a usar referencias externas directamente, no es lo mismo
Este concepto me eludió y es por eso que quería escribir este artículo.
Pensé que la referencia externa era la solución definitiva porque podía hacer todo lo que podía hacer SVG en línea que hace referencia a SVG en el mismo documento. Pero desafortunadamente, no se puede. Las referencias SVG de esta manera tienen su propio DOM separado. Va más allá del límite regular de Shadow DOM que todos <use>
está sujeta a.
Con este:
<svg class="icon-1">
<use xlink:href="https://css-tricks.com/svg-use-with-external-reference-take-2/#icon-1"></use>
</svg>
Podrías escribir CSS (en la misma hoja de estilo que usas para el resto del sitio) para colorearlo:
/* This works.
It will cascade this fill through the shapes,
as long as there are no presentational fill
attributes on the shapes themselves. */
.icon-1 {
fill: red;
}
Todavía puede hacer esto con una referencia externa <use>
, Realmente. Pero no puedes diseñar formas individuales como lo hacías antes.
/* You could reach individual shapes
to style because they share the same DOM.
But this WON'T WORK with externally referenced SVG. */
.path-1 {
fill: yellow;
}
/* This won't work either way,
because it crosses a shadow DOM boundary */
.icon-1 /* ~shadow~ */ .path-1 {
fill: yellow;
}
No puede tener en sus manos las formas internas cuando hace referencia externamente. Por ejemplo, del documento HTML:
<script>
var shape = document.querySelectorAll(".path-1");
console.log(shape);
// [ ] (empty set)
</script>
Aquí hay una esencia que un poco profundiza el punto.
Todavía es genial.
El hecho de que la cascada en un solo color aún funcione lo hace bastante útil. La mayoría de los íconos tienden a ser de un solo color. Y todavía puedes tener diferentes colores individuales.
Cosas extrañas del futuro
Tab Atkins en sus locas formas de pensar en el futuro ha documentado algunas posibles ideas futuras llamadas parámetros SVG:
.foo {
background-image: url("http://example.com/image.svg" param(--color var(--primary-color)));
}
Ese es un ejemplo de CSS, pero presumiblemente algo que SVG en línea podría usar también.