Saltar al contenido
ConvertOwl

SVG a CSS - un background-image que funciona de verdad

Pegar un SVG en una hoja de estilos falla de dos formas concretas, y las dos son silenciosas. Si el escape está mal, una almohadilla sin codificar dentro de un color de relleno trunca la URL, así que la regla se analiza sin problemas y la imagen sencillamente no aparece nunca. Si usas currentColor en tu ilustración, deja de recolorear en el momento en que se convierte en una URI data:, porque la URI es un documento aparte del que no hay nada que heredar. Esta herramienta se ocupa de lo primero por ti y te avisa de lo segundo, y te entrega una declaración background-image que puedes pegar tal cual. Usa la forma codificada en URL en vez de base64, que para SVG es a la vez más ligera y más comprimible. Todo se ejecuta en tu dispositivo, y el archivo se sanea antes de generar nada.

Cómo usar esta herramienta

  1. Suelta tu SVG

    Arrastra un archivo a la caja de arriba o haz clic para elegirlo. Los scripts, los manejadores de eventos y las referencias fuera del documento se eliminan antes de generar nada, y el panel lista lo que ha quitado.

  2. Copia la regla background-image

    El primer fragmento es una declaración completa con la URI data: ya escapada y entrecomillada: pégala directamente en una regla. Debajo hay una versión en base64 para las cadenas de herramientas que la exijan, con las dos cuentas de bytes a la vista.

  3. Atiende al aviso de currentColor

    Si tu ilustración usa currentColor, aparece un aviso que explica por qué se verá negra y ofrece en su lugar un fragmento con mask-image. Ese fragmento pinta la forma con el color de texto del propio elemento, que es el equivalente funcional más cercano.

  4. Añade las propiedades de tamaño que necesites

    Un background-image por sí solo se repite al tamaño intrínseco de la ilustración. Añade background-size y background-repeat: no-repeat para controlarlo, o usa el fragmento de máscara, que ya incluye ambas.

Preguntas frecuentes

¿Qué caracteres hay que escapar?

Cinco, más los saltos de línea. El signo de porcentaje tiene que ir primero o escaparía los propios escapes. Después la almohadilla, que si no inicia un fragmento de URL y trunca todo lo que venga tras tu primer color hexadecimal. Después los corchetes angulares, que rompen un atributo HTML, y la comilla doble que envuelve el valor.

Mi background-image simplemente no aparece. ¿Por qué?

Casi siempre una almohadilla sin escapar. Un relleno de #c33 dentro de una URI data: sin escapar termina la URL en la almohadilla, así que el navegador pide un documento truncado, no obtiene nada utilizable y no muestra nada, sin ningún error en consola, porque para el CSS la regla era perfectamente válida.

¿Por qué currentColor deja de funcionar en una URI data:?

Porque la URI data: es un documento aparte. currentColor se resuelve contra la propiedad color calculada del elemento en el que está el SVG, y un SVG cargado como imagen no tiene tal elemento: no forma parte del árbol de tu página. Cae a su valor inicial, que es el negro.

¿En qué consiste el apaño con mask-image?

Usas el SVG como plantilla en vez de como imagen. Pon background-color a currentColor para que el elemento pinte con el color de texto heredado, y luego usa mask-image con tu URI data: para que solo se vea la forma de la ilustración. Incluye -webkit-mask-image al lado para Safari.

¿Debería usar base64 en CSS?

Rara vez. Base64 hace esa misma imagen un quinto más grande dentro de la hoja de estilos y se comprime mucho peor, ya que a gzip le parece ruido. Solo merece la pena cuando una herramienta de compilación o un CMS rechaza la forma codificada por porcentaje, y por eso esta página ofrece las dos.

¿Puedo usar comillas simples alrededor del valor de url()?

Con esta salida no, y es deliberado. Los delimitadores de atributo dentro del SVG se convierten en apóstrofos para no tener que escaparlos, y de ahí viene la mayor parte del ahorro de tamaño. Eso convierte la comilla doble en el único envoltorio seguro: un apóstrofo terminaría el valor antes de tiempo.

¿Funciona esto en una propiedad personalizada de CSS?

Sí. Asigna el valor url("…") completo a una propiedad personalizada y referénciala donde la necesites, que es una forma ordenada de sacar una URI data: larga de en medio de una regla. Las propiedades personalizadas toman el valor como una secuencia de tokens, así que el escape de aquí ya es el correcto.

¿A partir de qué tamaño es demasiado para una hoja de estilos?

En torno a 4 KB de código SVG, que es donde avisa el panel. Una URI data: en CSS la descarga todo visitante que cargue esa hoja de estilos, se aplique la regla o no, y no puede cachearse por separado. Por debajo de ese umbral suele ganar a una petición extra; por encima, normalmente no.

¿Puedo meter una ilustración entera en una hoja de estilos?

Puedes, pero probablemente no deberías. Las ilustraciones ocupan decenas de kilobytes, y todos y cada uno de esos bytes los descarga quien cargue la hoja de estilos, se aplique la regla o no. Los iconos y las formas decorativas pequeñas son para lo que sirven las URI data:; cualquier cosa con detalle real merece su propio archivo.

¿El navegador cacheará la imagen incrustada?

Solo como parte de la hoja de estilos que la contiene, y ese es el canje. No hay entrada de caché aparte ni petición aparte, así que la primera visita es más rápida, y cualquier cambio posterior en la hoja de estilos vuelve a descargar la imagen con ella. Para un icono usado en todas las páginas suele ser un buen trato.

¿Se envía algo a un servidor?

No. El escapado se ejecuta en tu navegador, así que el archivo nunca sale de tu dispositivo, nunca se almacena y nunca lo vemos nosotros. También significa que no hay nada que esperar: los fragmentos aparecen en cuanto se lee el archivo.

¿Algo no funciona? Informar de un error