SVG `símbolo` una buena opción para los iconos | Programar Plus

Puede diseñar un conjunto de iconos en el que todos los iconos tengan exactamente la misma relación de aspecto. Pero probablemente ese no sea el caso. El recipiente alrededor de un pequeño icono de vaso de precipitados puede ser alto y estrecho. El recipiente alrededor de un pequeño pez quizás corto y largo. Probablemente no debería tener que pensar demasiado en eso, pero desafortunadamente tiene que hacerlo cuando usa un sistema de iconos SVG como lo describí en el pasado, porque necesita usar el viewBox atributo para describir esa relación de aspecto / contenedor.

Una mejora es utilizar el <symbol> elemento en SVG en lugar de hacer referencia directamente a formas (o un <g>), porque puede definir el viewBox directamente en el <symbol> y luego no necesito uno cuando tu <use> más tarde en un <svg>.

Un ejemplo está en orden.

Aquí hay dos íconos con relaciones de aspecto muy diferentes, como puede ver en la mesa de trabajo en Illustrator.

Podríamos ajustarlos para que todos se coloquen dentro de una relación de aspecto constante, pero creo que es más flexible y viable saber que los bordes de los iconos están justo donde se detienen las formas, no con una cantidad arbitraria de espacio en blanco alrededor.

La forma “antigua”

Si vamos al <defs>-ruta de bloque, podríamos combinarlos en:

<svg>
  <defs>
    <g id="shape-icon-1">
      <!-- all the paths and shapes and whatnot for this icon -->
    <g>
    <g id="shape-icon-2">
      <!-- all the paths and shapes and whatnot for this icon -->
    <g>
  </defs>
</svg>

Entonces úsalos como:

<!-- These viewBox's better be right or the icons won't look right! -->

<svg class="icon" viewBox="214.7 0 182.6 792">
  <use xlink:href="https://css-tricks.com/svg-symbol-good-choice-icons/#shape-icon-1" />
</svg>

<svg class="icon" viewBox="0 26 100 48">
  <use xlink:href="#shape-icon-2" />
</svg>

Eso pone una buena cantidad de responsabilidad en el implementador para obtener esos viewBox atributos correctos en el marcado. Ésa es una de las razones por las que es posible que desee intentar obtener todos esos iconos en un viewBox="0 0 100 100" (o algo), pero luego tenemos ese espacio en blanco arbitrario.

La “nueva” forma

Entran Fabrice Weinberg y TxHawks. Fabrice trabaja en grunt-svgstore, un complemento de Grunt para crear sprites SVG a partir de una carpeta de archivos SVG. Este tipo de cosas hace que el flujo de trabajo del icono SVG sea rápido y fácil. Es decir, excepto por el hecho de que necesitas saber que maldita sea viewBox para cada icono antes de usarlo.

TxHawks sugirió tener grunt-svgstore al menos poner data-* atributos en el <g> elementos que envuelven cada ícono, por lo que podría haber acceso programático a lo que se supone que es. Pero desafortunadamente SVG no los permite (probablemente habría funcionado, pero también podría hacer que una herramienta de compilación cumpla con las especificaciones). Sin embargo, no importa, porque poco después, sugirieron usar <symbol> en cambio, lo que resulta ser una buena idea.

En lugar de usar <g> para envolver todas las formas de los iconos, use <symbol>, como esto:

<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  
  <symbol id="beaker" viewBox="214.7 0 182.6 792">
    <!-- <path>s and whatever other shapes in here -->  
  </symbol>
  
  <symbol id="shape-icon-2" viewBox="0 26 100 48">
    <!-- <path>s and whatever other shapes in here -->  
  </symbol>
  
</svg>

Tenga en cuenta que viewBox se define para cada icono y como lo está definiendo en lugar de cuando lo está usando. Eso significa que usarlo se vuelve más fácil:

<!-- We ain't even need no viewBox round here. --> 

<svg class="icon">
  <use xlink:href="https://css-tricks.com/svg-symbol-good-choice-icons/#shape-icon-1" />
</svg>

<svg class="icon">
  <use xlink:href="#shape-icon-2" />
</svg>

Más fácil y menos propenso a errores.

Y se pone mejor: puedes agregar <title> y <desc> etiquetas en el símbolo también, lo que significa que las cosas de accesibilidad se incorporan a medida que las usa.

<symbol id="icon1" viewBox="original-file's-viewBox">
  <title>original-file's-title</title> 
  <desc>original-file's-desc</desc>

  <!-- <path>s and other shapes -->

</symbol>

grunt-svgstore hace esto ahora, ¡gracias a TxHawks y Fabrice!

Por qué es mejor para los íconos

Solo para señalarlo:

  1. El viewBox se puede definir en el símbolo, por lo que no es necesario utilizarlo en el marcado (más fácil y menos propenso a errores).
  2. title y desc las etiquetas se pueden agregar dentro del <symbol> y “vienen de paseo” cuando se usa el símbolo, lo que hace que la accesibilidad sea más fácil de hacer bien.
  3. Los símbolos no se muestran como los define, por lo que no es necesario <defs> cuadra.
  4. Probablemente esto es lo que <symbol> fue inventado de todos modos.

Manifestación

Funciona:

Vea Pen Hwcxp de Chris Coyier (@chriscoyier) en CodePen.