RSS 29 September 2020

Cómo simplificar código SVG usando formas básicas

Iconos SVG DIY

#svg#tutorial#espanol

Lea la versión en chino aquí. Traducido por Rotten orange 腐烂的橘子

***

Hay diferentes formas de trabajar con íconos, pero la mejor solución siempre incluye SVG, ya sea inline o vinculado como un archivo. A veces, los íconos que descargamos (o los que creamos con un software de dibujo) tienen mucho código innecesario que, si lo usamos en línea, hace que nuestro documento sea más largo para desplazarse, incómodo para trabajar y un poco más pesado. .

Podemos solucionar esto reutilizando fragmentos de código con el elemento <use> o [aplicar variables nativas a administre nuestros estilos SVG] (http://localhost:56203/posts/use-and-reuse-everything-in-svg-even-animations) desde un solo lugar.

Acá quiero enfocarme en una perspectiva diferente: cómo hacer las mismas figuras con menos código usando formas básicas. Y obtener los beneficios de íconos más pequeños, controlables y semánticos en nuestros proyectos sin sacrificar la calidad o los cambios visuales. Revisaré diferentes ejemplos que exploran el código de los íconos de uso común y cómo podemos volver a dibujarlos usando algunas de las formas SVG más fáciles que podemos hacer.

Estos son los iconos en los que trabajaremos:

svg icons
Iconos de cruz, reloj y sobre.

Veamos las formas básicas que podemos usar para hacer que el código sea pequeño y simple.

Psssst! ¡Aquí hay una lista más larga de íconos simples que creé en holasvg.com! Después de este artículo, podran cómo modificarlos y hacerlos suyos.

Construyendo un icono de cerrar con el elemento <line>

Este es el código para el icono de cerrar o cruz que se descargó de flaticon.com y lo creó [pixel-perfect](https://www.flaticon.com/authors/ pixel perfect):

En este ejemplo, todo sucede dentro de <path> con muchos comandos y parámetros en el atributo de datos d. Lo que hace este SVG es trazar la forma desde sus bordes.

Una demostración rápida utilizando mavo.io

Si están familiarizados con Illustrator, esto es el equivalente a dibujar dos líneas separadas, convertirlas en forma y luego combinarlas con el pathfinder para crear una forma compuesta.

Convertir dos líneas en una forma compuesta en Illustrator.

El elemento <path> nos permite dibujar formas complejas, pero en este caso, podemos crear la misma figura con dos líneas, manteniendo la misma apariencia:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50" height="50" overflow="visible" stroke="black" stroke-width="10" stroke-linecap="round">
   <line x1="0" y1="0" x2="50" y2="50" />
   <line x1="50" y1="0" x2="0" y2="50" />
</svg>

Empezamos definiendo un viewBox que va de 0,0 a 50,50. Pueden elegir las dimensiones que prefieran; el SVG siempre se escalará bien a cualquier ancho y alto que se defina. Para facilitar las cosas, en este caso, también definí un ancho y alto en línea de 50 unidades, lo que evita cálculos adicionales en el dibujo.

Para usar el elemento <línea>, declaramos las coordenadas del primer punto de la línea y las coordenadas de su último punto. En este caso específico, empezamos desde x=0 y=0 y terminamos en x=50 y=50.

Cuadrícula del sistema de coordenadas.

Así es como se ve en el código:

<line x1="0" y1="0" x2="50" y2="50" />

La segunda línea comenzará desde x=50 y=0 y terminará en x=0 y=50:

<line x1="50" y1="0" x2="0" y2="50" />

Un trazo SVG no tiene un color por defecto, por eso agregamos el valor negro en el atributo stroke. También le dimos al atributo 'stroke-width' un ancho de 10 unidades y a 'stroke-linecap' un valor 'round' para replicar esas esquinas redondeadas del diseño original. Estos atributos se agregaron directamente a la etiqueta <svg> para que ambas líneas los hereden.

<svg ... stroke="black" stroke-width="10" stroke-linecap="round" ...>

Ahora que el trazo es 10 unidades más grande que su tamaño predeterminado de 1 unidad, la línea podría quedar recortada por viewBox. Podemos mover los puntos 10 unidades dentro de viewBox o agregar overflow=visible a los estilos.

Los valores que son iguales a 0 se pueden eliminar, ya que 0 es el valor predeterminado. Eso significa que las dos líneas terminan con dos líneas de código muy pequeñas:

<line x2="50" y2="50" />
<line x1="50" y2="50" />

Con solo cambiar <path> a <line>, no solo creamos un archivo SVG más pequeño, sino también un fragmento de código más semántico y controlable que hace que cualquier mantenimiento futuro sea mucho más fácil. Y el resultado visual es exactamente igual que el original.

Misma cruz, diferente código.

Construyendo un icono de reloj con los elementos <circle> y <path>

Tomé este ejemplo de un icono de reloj creado por barracuda de The Noun Project:

Esta forma también se dibujó con <path>, pero también tenemos muchos espacios de nombres e instrucciones XML relacionadas con el software utilizado y la licencia del archivo que podemos eliminar sin afectar el SVG. ¿Pueden adivinar qué editor de ilustraciones se usó para crear el icono?

Recreemos este desde cero usando un círculo y un path con comandos más simples. Nuevamente, debemos comenzar con un viewBox, esta vez de 0,0 a 100,100, y con un ancho y alto que coincidan con esas unidades.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100" fill="none" stroke="black" stroke-width="10" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="50" cy="50" r="40"/>
  <path d="M50 25V50 H75" /> 
</svg>

Mantenemos los mismos estilos que el ícono anterior dentro de la etiqueta <svg>. fill es black de forma predeterminada, por lo que debemos darle explícitamente un valor none para eliminarlo. De lo contrario, el círculo tendrá un relleno negro sólido, oscureciendo las otras formas.

Para dibujar el <circle> necesitamos indicar un punto central desde donde se asentará el radio. Podemos lograr eso con cx (centro x) y cy (centro y). Entonces r (radio) declarará qué tan grande será nuestro círculo. En este ejemplo, el radio es ligeramente más pequeño que el viewBox, por lo que no se recorta cuando el trazo tiene 10 unidades de ancho.

¿Qué pasa con todas esas letras? Consulten la guía ilustrada de Chris Coyier para obtener una introducción a la sintaxis SVG.

Podemos usar un <path> para las manecillas del reloj porque tiene algunos comandos muy útiles y simples para dibujar. Dentro de la d (data) debemos comenzar con el comando M (mover a) seguido de las coordenadas desde donde comenzaremos a dibujar que, en este ejemplo, es 50,25 (cerca del centro superior de la círculo).

Después del comando V (vertical), solo necesitamos un valor ya que solo podemos movernos hacia arriba o hacia abajo con un número negativo o positivo. Un número positivo bajará. Lo mismo para 'H' (horizontal) seguido de un número positivo, 75, que dibujará hacia la derecha. Todos los comandos están en mayúsculas, por lo que los números que elijamos serán puntos en la cuadrícula. Si decidimos usar minúsculas (comandos relativos) los números serán la cantidad de unidades que nos movemos en una dirección y no un punto absoluto en el sistema de coordenadas.

Mismo reloj, diferente código.

Construyendo un icono de sobre con los elementos <rect> y <polyline>

Dibujé el ícono del sobre en Illustrator sin expandir las formas originales. Aquí está el código que vino de la exportación:

Hey! Illustrator ofrece algunas opciones de SVG para exportar el gráfico. Elegí Style Elements en el menú desplegable Propiedades de CSS para poder tener una etiqueta <styles> que contenga clases que podría querer mover a un archivo CSS. Pero hay diferentes formas de aplicar los estilos en SVG, por supuesto.

¡Ya tenemos formas básicas en este código! Deseleccioné la opción Shape to Path en Illustrator, lo que ayudó mucho. Podemos optimizar esto aún más con SVGOMG para eliminar los comentarios, las instrucciones XML y los datos innecesarios, como elementos vacíos. A partir de ahí, podemos eliminar manualmente otros extras, si es necesario.

Ya tenemos algo un poco más conciso:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 310 190" xml:space="preserve">
  <style>.st0{fill:none;stroke:#000;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}
  </style><rect x="5" y="5" class="st0" width="300" height="180"/>
  <polyline class="st0" points="5 5 155 110 305 5"/>
</svg>

Podemos eliminar aún más cosas sin afectar la apariencia visual del sobre, incluyendo:

  • version="1.1" (esto ha sido obsoleto desde SVG 2)
  • id="Layer_1" (esto no tiene significado ni uso)
  • x="0" (este es un valor predeterminado)
  • y="0" (este es un valor predeterminado)
  • xml:space="preserve" (esto ha sido obsoleto desde SVG 2)
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 310 190">
  <style>.st0{fill:none;stroke:#000;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}
  </style>
  <rect x="5" y="5" class="st0" width="300" height="180"/>
  <polyline class="st0" points="5 5 155 110 305 5"/>
</svg>

Podemos mover los estilos CSS a una hoja de estilo separada si queremos ser realmente agresivos.

<rect> necesita un punto de partida desde donde extenderemos un ancho y una altura, así que usemos x="5" y y="5", que es nuestro punto superior izquierdo. A partir de ahí, crearemos un rectángulo de 300 unidades de ancho con una altura de 180 unidades. Al igual que el icono del reloj, usaremos 5,5 como punto de partida porque tenemos un trazo de 10 unidades que se recortará si las coordenadas se encuentran en 0,0.

<polyline> es similar a <line>, pero con una cantidad infinita de puntos que definimos, como pares de coordenadas, uno tras otro, dentro del atributo de puntos, donde el primer número del par representará x y el segundo será y. Es más fácil leer la secuencia con comas, pero se pueden reemplazar con espacios en blanco sin afectar el resultado.

Mismo sobre, distinto código.

¡Bonus de formas!

No incluí ejemplos de íconos que se pueden simplificar con las formas <polygon> y <ellipse>, pero acá hay una forma rápida de usarlos.

<polygon> es lo mismo que <polyline>, solo que este elemento siempre definirá una forma cerrada. Aquí hay un ejemplo que viene [directamente de MDN] (https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon):

¿Recuerdan el círculo que dibujamos antes para el icono del reloj? Reemplacen r (radio) con rx y ry. Ahora tienen dos valores diferentes para el radio. Aquí hay otro [ejemplo de MDN] (https://developer.mozilla.org/en-US/docs/Web/SVG/Element/ellipse):

Terminando

¡Cubrimos mucho acá en un corto período de tiempo! Si bien usamos ejemplos para demostrar el proceso de optimización de SVG, esto es lo que espero que se lleven de esta publicación:

  • Recuerden que la compresión comienza con la forma en que se dibuja el SVG en el software de ilustración.
  • Usen las herramientas disponibles, como SVOMG, para comprimir SVG.
  • Eliminen los metatags innecesarios a mano, de ser necesario.
  • Reemplacen paths complejos con formas básicas.
  • <use> es una excelente manera de incluir SVG en línea, así como para establecer su propia biblioteca de iconos reutilizables.

¿Cuántos iconos se pueden crear combinando estas formas básicas?

Estoy trabajando en mi lista en holasvg.com/icons, estaré subiendo constantemente más íconos y optimizaciones acá, y ahora ya saben cómo modificarlos fácilmente con solo cambiar algunos números. ¡Haganlos tuyos!

Este artículo se publicó por primera vez en CSS-Tricks con ediciones de [Chris Coyier](https: //chriscoyier.net/) y Geoff Graham

Let's stay in touch.

mbeldi@gmail.com