Si dibuja sus propios archivos SVG o si los descarga de Internet, herramientas como este SVG-Editor o SVGOMG son sus amigos. Comprimir los archivos con esas herramientas toma solo unos segundos y reduce mucho el tamaño de su archivo. Pero si necesita usar su SVG en línea para animar o interactuar con el código, todavía hay mucho que puede hacer sobre la legibilidad del código.
Reutilizar contenido con SVG <use>
No siempre es una opción, pero cuando lo es, no te arrepentirás de tomarte unos minutos más para ponerlo en práctica.
En este artículo, mostraré un ejemplo en el que pude aprovechar mucho este elemento, no solo para mantener el tamaño del archivo bajo, sino también para un marcado más claro que se volvió más legible y fácil de mantener.
Este es el primer diseño con el que necesitaba trabajar. Fue creado originalmente en Illustrator:
Eche un vistazo al siguiente código, este es el archivo original exportado directamente desde el software, pesa 2.05 KB:
No es un archivo pesado en absoluto. Sin embargo, ábralo y verá que hay muchas etiquetas vacías, espacios de nombres obsoletos, espacios en blanco innecesarios, comas e información adicional aplicada por el software. Esto hace que sea difícil trabajar con el código, molesto de escanear y crea un gran desplazamiento para esos cientos de líneas en su documento.
También notará que el archivo está usando <use>
y <defs>
elementos, pero no de la mejor manera posible. ¡Y eso no es culpa del software! Cada ilustración de astronauta en el archivo original tiene una máscara de recorte: un círculo invisible que actúa como una ventana a través de la cual podemos ver a nuestro personaje. Sin él, el traje del astronauta se inundaría fuera del círculo. Hay algunas formas de evitar esto en Illustrator, como recortar esas partes adicionales con una opción de buscador de caminos. De esa forma obtendríamos unos pocos bytes y evitaríamos usar un círculo extra solo para recortar información del gráfico que no mostraremos. La compresión del archivo comienza en el software. Aún así, hay muchas cosas que podremos mejorar en el código en caso de que no queramos editar el archivo original.
Comprimir el SVG con SVGOMG y mantener las opciones predeterminadas no requerirá ningún esfuerzo y obtendrá un archivo que pesa 1,46 KB. Eso es una reducción del 30% en comparación con el tamaño original y el gráfico se verá exactamente igual.
Reutilizando contenido
Esto requerirá pasar por el SVG y hacer algunos ajustes. Sé que esta opción lleva más tiempo con respecto al ejemplo anterior, pero no es tan difícil como parece.
Tenemos un elemento repetido, que es el astronauta dentro del círculo. Ese es el que comprimiremos en SVGOMG. El resultado se verá así:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 95.8 95.8">
<style>.st3,.st4{fill:#ffcb2f;stroke:#12192c;stroke-width:1.4891;stroke-miterlimit:10}.st4{fill:#69b2b1}</style>
<circle cx="47.9" cy="47.9" r="47.9" fill="#12192c"/>
<circle cx="47.9" cy="47.9" r="40.7" fill="#f6a2a4"/>
<defs><circle id="SVGID_1_" cx="47.9" cy="47.9" r="40.7"/></defs>
<clipPath id="SVGID_2_"><use xlink:href="https://css-tricks.com/going-beyond-automatic-svg-compression-with-the-use-element/#SVGID_1_" overflow="visible"/></clipPath>
<g clip-path="url(#SVGID_2_)">
<path class="st3" d="M63.9 45.6H32c-4 0-7.2 1.9-7.3 4.3l-.8 26.6H72l-.8-26.6c-.2-2.5-3.4-4.3-7.3-4.3z"/>
<path class="st4" d="M74.3 86.9L66 88.2C53.8 90 41.4 90 29.1 88.1l-7.7-1.2v-14c0-4 3.2-7.2 7.2-7.2h38.5c4 0 7.2 3.2 7.2 7.2v14z"/>
<path class="st3" d="M31.8 47.3h-.6c-.7 0-1.2-.6-1.2-1.2V23.2c0-.7.6-1.2 1.2-1.2h.6c.7 0 1.2.6 1.2 1.2v22.9c0 .7-.6 1.2-1.2 1.2z"/>
<circle class="st4" cx="31.5" cy="20.7" r="2.8"/>
<circle class="st4" cx="47.9" cy="51.4" r="20.3"/>
<path d="M64.5 53.1c0 8-7.4 11.2-16.5 11.2S31.4 61 31.4 53.1s7.4-14.4 16.5-14.4 16.6 6.4 16.6 14.4z" fill="#13192d" stroke="#12192c" stroke-width="1.489" stroke-miterlimit="10"/>
<path fill="none" stroke="#12192c" stroke-width="1.489" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-dasharray="9.6793,3.7228" d="M65.9 88V76.9"/>
<path fill="none" stroke="#12192c" stroke-width="1.489" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M29.6 87.9v-11"/>
</g>
</svg>
Primeras recomendaciones:
- Mueve el
<style>
contenido al archivo CSS (asumiendo que puede usar su SVG en línea y que tiene una hoja de estilo vinculada en su documento). - Cambie el nombre de las ID con algo que tenga sentido para usted.
- Redondea esos números complicados, como
stroke-width="1.489"
astroke-width="1.5"
. Esto es algo que podría suceder si cambia el tamaño de sus vectores en Illustrator con la opción de escalar los bordes marcada. - Quitar el
stroke-miterlimit="10"
ya que no lo necesitamos desde nuestrostroke-linejoin
es redondo. - Este código será nuestra plantilla de astronauta. Necesitamos envolver todo en un grupo, agregar una identificación a ese grupo y colocarlo dentro de un
<defs>
etiqueta. Observe que ya tenemos un<defs>
elemento con un círculo en su interior. Podemos eliminar ese, ya que será parte de un mayor<defs>
etiqueta.
Observe que los dos primeros círculos son formas rellenas con diferente radio y color. Podemos mantener el más pequeño y agregar un trazo lo suficientemente grande para lograr el mismo efecto, nuevamente, algo que podríamos evitar al usar un círculo con borde en Illustrator en primer lugar.
Otra cosa importante es que nuestro viewBox actual es demasiado pequeño para lo que queremos construir. Hagámoslo más grande y agreguemos algo de espacio negativo en el eje X para que podamos comenzar a clonar a nuestro astronauta desde el medio.
Para obtener más información sobre viewBox, consulte esta hermosa guía para escalar SVG por Amelia Wattenberger.
Terminaremos con algo como esto:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-400 0 1000 5000">
<defs>
<g id="astronaut">
<circle cx="94.5" cy="48" r="44" fill="currentColor" stroke="#12192c" stroke-width="8"/><clipPath id="a"><circle cx="94.5" cy="47.9" r="40"/></clipPath>
<g clip-path="url(#a)"><path class="st3" d="M110.5 45.6H78.6c-4 0-7.2 1.9-7.3 4.3l-.8 26.6h48.1l-.8-26.6c-.1-2.5-3.4-4.3-7.3-4.3z"/><path class="st4" d="M121 86.9l-8.3 1.3C100.4 90 88 90 75.8 88.1l-7.7-1.2v-14c0-4 3.2-7.2 7.2-7.2h38.5c4 0 7.2 3.2 7.2 7.2v14z"/><path class="st3" d="M78.4 47.3h-.6c-.7 0-1.2-.6-1.2-1.2V23.2c0-.7.6-1.2 1.2-1.2h.6c.7 0 1.2.6 1.2 1.2v22.9c0 .7-.5 1.2-1.2 1.2z"/><circle class="st4" cx="78.1" cy="20.7" r="2.8"/><circle class="st4" cx="94.5" cy="51.4" r="20.3"/><path d="M111.1 53.1c0 8-7.4 11.2-16.5 11.2S78 61 78 53.1s7.4-14.4 16.5-14.4 16.6 6.4 16.6 14.4z" fill="#13192d" /><path fill="none" stroke="#12192c" stroke-width="1.5" stroke-linecap="round" d="M112.5 88V76.9"/><path fill="none" stroke="#12192c" stroke-width="1.5" stroke-linecap="round" d="M76.3 87.9v-11"/></g>
</g>
</defs>
</svg>
¿Qué va dentro del <defs>
no se renderizará en ningún lado. Para comenzar a clonar a nuestro astronauta, necesitamos vincular su ID dentro de un <use>
elemento como este:
<use xlink:href="https://css-tricks.com/going-beyond-automatic-svg-compression-with-the-use-element/#astronaut"/>
xlink:href
está en desuso desde SVG2, pero es mejor usarlo por motivos de compatibilidad. Puede usar href en navegadores modernos, pero lo probé en Safari y no funcionaba al momento de escribir este artículo. Si usa xlink: href, asegúrese de incluir este espacio de nombres en su etiqueta SVG: xmlns:xlink="http://www.w3.org/1999/xlink
(no lo necesitará si decide usar href
).
Ahora podemos agregar el texto correspondiente a esta primera figura y alinearlo con el atributo de transformación. Es mejor que coloquemos ambos elementos dentro de un grupo para que en instancias futuras podamos trasladar todo el grupo a la posición que queremos:
<g transform="translate(-95 210)">
<use xlink:href="https://css-tricks.com/going-beyond-automatic-svg-compression-with-the-use-element/#astronaut"/>
<text transform="translate(25 130)">Tech Leader</text>
</g>
Las líneas de conexión son formas simples que se pueden dibujar directamente con <path>
. Los caminos dan miedo pero, para las líneas rectas, no hay mucho de qué preocuparse. Explicaré este código:
<path class="line" d="M-4 200v-25h200"/>
d=""
es para datos y ahí es donde colocaremos nuestros comandos. M
es mover nuestra mano al lugar donde comenzaremos a dibujar (pero no está dibujando nada). -4 200
significa que colocamos nuestro lápiz cuatro unidades a la izquierda y 200 en la parte inferior de nuestro viewBox (siguiendo la orientación del sistema de coordenadas SVG). v
es el comando para empezar a dibujar una línea vertical que irá desde este lugar hasta -25 unidades hacia arriba. h
es para horizontal, por lo que trazamos una línea desde allí hasta 200 a la derecha. Se siente como un escritor de logotipos.
Separé las líneas en tres caminos, pero podemos usar solo uno con el M
valor después de una serie de comandos para mover nuestra mano y empezar a dibujar desde un nuevo punto en el sistema de coordenadas.
Eche un vistazo al documento final. Ahora el archivo pesa 779 octetos y tiene 12 líneas de código legible y escalable:
Si declaramos algún valor en los atributos que definimos en el <defs>
entonces no será posible cambiarlo en sus clones debido a la naturaleza del <use>
elemento. Es por eso que en el ejemplo anterior, el relleno del círculo principal se reemplazó con un valor de currentColor
tener el control de los fondos de todas las réplicas. currentColor
heredará el valor de color CSS del elemento (o cualquier elemento por encima de él). En el SVG, estoy agregando una clase a algunos astronautas replicados y agregando un valor de color en CSS a esas clases. De esta forma, podré cambiar todas las instancias del <use>
elemento con esa clase. Para entender más sobre <use>
y cómo diseñar su contenido, esta publicación de Sara Soueidan tiene todo lo que necesitas saber.
Con este código listo, podremos escalar el gráfico a algo como esto mucho más fácilmente:
Organigrama SVG (Demo)
Aquí están los tres ejemplos uno al lado del otro para comparar la legibilidad y la cantidad de código, pasamos de 241 a 10 líneas ordenadas:
De izquierda a derecha: código directamente de Illustrator, código después de SVGOMG, código después de la optimización.