Qué produce Figma e Illustrator
Anatomía de un SVG recién exportado: el prólogo inútil, los identificadores que colisionan, las clases globales, el fill none del contenedor, y por qué currentColor no funciona de fábrica.
Un SVG recién exportado de una herramienta de diseño no es un fichero mal hecho: es un fichero hecho para otro propósito. La herramienta escribe lo que garantiza que su dibujo se reproduzca exactamente en cualquier lector, incluidos los que no son navegadores. Ese objetivo produce, sistemáticamente, siete rasgos que en una página web sobran o hacen daño. Conocerlos uno a uno convierte la optimización de un ejercicio de fe en una lista de comprobación.
- Identificar los siete rasgos característicos de un SVG exportado.
- Explicar por qué
currentColorno funciona en un icono de Figma sin tocarlo. - Reconocer el bloque de estilo interno de Illustrator y el daño que hace.
- Decidir qué se corrige en la herramienta y qué en el pipeline.
El fichero típico de Figma
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
xmlns="http://www.w3.org/2000/svg">
<g id="Frame 27" clip-path="url(#clip0_1_43)">
<path id="Vector"
d="M12.0000 2.00000L15.0900 8.26000L22.0000 9.27000L17.0000 14.1400"
stroke="#1E1E1E" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1_43">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>
Cinco rasgos en ocho líneas.
width y height fijos junto al viewBox. No hacen daño y limitan: el icono toma ese tamaño si el CSS no dice otra cosa. Para un icono que se dimensiona desde CSS, sobran; para uno que se usa suelto, ayudan a que no colapse. La decisión depende de tu sistema.
fill="none" en el elemento raíz. Este sí hace daño. Como fill se hereda, ese none baja a todo el contenido. Si más tarde pones una regla .icono { fill: currentColor }, gana el CSS y funciona; pero si intentas que el icono herede el color por la vía de poner color en el contenedor sin tocar el fill, no pasa nada, porque el none del raíz gana a la herencia.
Nombres de capa como id. id="Frame 27", id="Vector". Son ruido, y con espacios. Peor: si el mismo fichero se exporta dos veces, esos identificadores se repiten en el documento.
El clipPath con identificador de forma clip0_1_43. Figma añade un recorte cuando el marco recorta contenido, aunque el contenido no se salga. Los números vienen del identificador interno del nodo, así que dos exportaciones distintas pueden generar el mismo, y ese es el origen de la colisión que se explicó en el nivel 20.
Colores literales en cada trazo. stroke="#1E1E1E". El icono está atado a un color, y ese color es el del tema de la herramienta, no el de tu producto.
A eso se añaden, según la exportación: coordenadas con seis decimales, grupos anidados sin función, atributos fill-rule="evenodd" clip-rule="evenodd" repetidos en cada ruta, y transformaciones que se podrían haber aplicado a la geometría.
El fichero típico de Illustrator
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.0.0, SVG Export Plug-In -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;"
xml:space="preserve">
<style type="text/css">
.st0{fill:#1E1E1E;}
.st1{fill:none;stroke:#1E1E1E;stroke-width:2;}
</style>
<g id="Capa_2_00000123456789">
<path class="st0" d="M12,2L15.09,8.26L22,9.27"/>
</g>
</svg>
Y aquí el problema es de otra categoría.
El prólogo XML, el comentario del generador y version="1.1" son bytes muertos. Inofensivos y prescindibles.
x="0px" y="0px", enable-background y xml:space="preserve" son atributos obsoletos o sin efecto. enable-background fue una propiedad de la especificación de filtros que ningún motor implementó.
El bloque <style> con clases st0, st1. Este es el peligroso, y no por colisión de identificadores sino por algo peor: son selectores globales de CSS. Si inlinas ese SVG en una página, esas reglas se aplican a cualquier elemento del documento que tenga la clase st0. Dos iconos de Illustrator en la misma página se pisan las reglas mutuamente, porque los dos definen .st0 y gana el último. Y si por casualidad tu propio CSS usa una clase con ese nombre, el icono la repinta.
Es la diferencia de gravedad entre los dos exportadores: Figma produce colisiones de identificadores dentro del SVG; Illustrator produce colisiones de CSS en toda la página.
La opción de exportación de Illustrator que lo evita se llama, según la versión, «Atributos de presentación» en el desplegable de estilo. Elegirla resuelve el problema en el origen.
Por qué currentColor no funciona de fábrica
Ninguna herramienta de diseño tiene el concepto de «color heredado del contexto», porque en un lienzo de diseño no hay contexto. Todo color es un valor concreto.
De modo que la sustitución de los colores por currentColor es un paso que siempre hay que hacer en el pipeline o a mano. No existe una opción de exportación que lo haga.
// Sustitucion basica para un icono monocromo
function aCurrentColor(svg, colorOriginal = '#1E1E1E') {
const re = new RegExp(colorOriginal.replace('#', '#'), 'gi');
return svg
.replace(re, 'currentColor')
.replace(/\sfill="none"(?=[^>]*<svg)/, ''); // el fill del raiz
}
Ese código es un punto de partida y no una solución general, porque los iconos multicolor necesitan un mapeo de varios colores a varias variables. El enfoque robusto es acordar con el equipo de diseño una paleta cerrada de tokens que se usa en los iconos, y mapear cada uno a su variable CSS. Entonces la sustitución es determinista.
La mayoría del ruido que sale de una herramienta no lo genera el exportador: lo genera la estructura del documento. Cinco casos concretos, con su síntoma en el SVG.
Un marco que recorta produce un clipPath. Si el icono está dentro de un marco con recorte activado, aunque nada se salga, sale un clipPath con su identificador colisionable. Desactivar el recorte del marco lo elimina en origen.
Un grupo con opacidad o modo de fusión produce un g con opacity o mix-blend-mode, y a menudo un filtro. Aplanar el grupo en la herramienta lo evita.
Una forma con trazo produce un stroke; una forma con trazo expandido produce un path con el doble de puntos. Expandir un trazo es irreversible y multiplica el peso; en un icono de línea, conservar el stroke es casi siempre mejor, porque permite cambiar el grosor desde CSS.
Una operación booleana produce un path con fill-rule="evenodd" y varias subrutas, en lugar de dos formas primitivas. A veces es lo que quieres; a menudo es una unión que se podía haber hecho con dos rectángulos.
Un efecto de sombra produce un filter con cuatro primitivas y una región enorme, y ese filtro se rasteriza en cada uso. En un icono es casi siempre un error: la sombra debería ir en CSS.
La conclusión operativa es que la optimización empieza en el fichero de diseño, y que la conversación productiva no es «optimiza mejor los SVG» sino «así se construye un icono que exporta limpio». Un documento de convenciones de una página (rejilla fija, sin marcos con recorte, sin efectos, sin grupos innecesarios, trazos sin expandir, paleta de tokens) elimina más peso y más bugs que cualquier configuración de optimizador.
Qué se corrige dónde
| Rasgo | Se corrige en |
|---|---|
Prólogo XML, comentarios, version |
Pipeline |
Bloque <style> con clases |
Herramienta, cambiando la opción de exportación |
id de capas |
Pipeline |
clipPath innecesario |
Herramienta, quitando el recorte del marco |
| Colores literales | Pipeline, sustituyendo por currentColor o variables |
| Decimales excesivos | Pipeline |
| Grupos vacíos y transformaciones | Pipeline |
| Trazos expandidos | Herramienta, no expandiendo |
| Efectos y filtros | Herramienta, quitándolos |
La columna de la derecha reparte el trabajo, y el reparto no es negociable: lo que se pierde en la exportación no se puede recuperar en el pipeline. Un trazo expandido no se puede desexpandir.
Coge tres iconos exportados de tu herramienta y anota, para cada uno, cuáles de los siete rasgos tiene. Después vuelve al fichero de diseño y averigua qué construcción produce cada uno. Con eso escribe la página de convenciones para el equipo de diseño; será el documento de optimización más rentable del proyecto.