Alguien me preguntó recientemente cómo debuggeo SVGs inline. Debido a que son parte del DOM, podemos inspeccionar cualquier SVG inline en cualquier navegador con las DevTools. Gracias a eso, tenemos la capacidad de analizar los elementos y descubrir cualquier problema u oportunidad potencial para optimizar el SVG.
Pero hay veces que ni siquiera podemos ver nuestros SVG. En esos casos, hay seis cosas específicas que busco cuando estoy depurando.
1. Los valores de viewBox
El viewBox
es un punto común de confusión cuando se trabaja con SVG. Está técnicamente bien usar SVG inline sin él, pero perderíamos uno de sus beneficios más significativos: escalar con el contenedor. Al mismo tiempo, puede ser contraproducente cuando se configura de forma incorrecta, generando un recorte no deseado.
Los elementos están ahí cuando están clipeados, solo que están en una parte del sistema de coordenadas que no vemos. Si abriéramos el archivo en algún programa de edición de gráficos, se vería algo así:
¿La forma más fácil de arreglar esto? Agregar overflow="visible"
al SVG, ya sea en nuestra hoja de estilo, inline en el atributo de estilo o directamente como un atributo de presentación SVG. Pero si también aplicamos un color de fondo al SVG o si tenemos otros elementos a su alrededor, las cosas pueden verse un poco mal. En este caso, la mejor opción será editar viewBox
para mostrar esa parte del sistema de coordenadas que estaba oculta:
Hay algunos puntos adicionales sobre el viewBox
que vale la pena mencionar mientras estamos en el tema:
¿Cómo funciona el viewBox?
SVG es un lienzo infinito, pero podemos controlar lo que vemos y cómo lo vemos a través del viewport
y el viewBox
.
El viewport
es un marco de ventana en un canvas infinito. Sus dimensiones se definen por atributos width
y heigh
, o en CSS con las propiedades de width
y heigh
correspondientes. Podemos especificar cualquier unidad de longitud que queramos, pero si proporcionamos números sin unidades, por defecto serán equivalentes a píxeles.
El viewBox
está definido por cuatro valores. Los dos primeros son el punto de partida en la esquina superior izquierda (valores x
e y
, se permiten números negativos). Edito estos valores para reencuadrar la imagen. Los dos últimos son el ancho y la altura del sistema de coordenadas dentro de la ventana gráfica — aquí es donde podemos editar la escala de la cuadrícula (que abordaremos en la sección sobre Zoom).
Acá hay un ejemplo simplificado que muestra el viewBox
SVG y los atributos de width y height establecidos en <svg>
:
<svg viewBox="0 0 700 700" width="700" height="700">
<!-- etc. -->
</svg>
Reencuandre
Así que esto:
<svg viewBox="0 0 700 700">
…equivale a esto:
<svg viewBox="comienzo-eje-x comienzo-eje-y ancho alto">
El viewport
(o ventana) que vemos comienza donde se encuentran 0 en el eje x
y 0 en el eje y
.
Cambiando esto:
<svg viewBox="0 0 700 700">
…a esto:
<svg viewBox="300 200 700 700">
…el ancho y la altura siguen siendo los mismos (700 unidades cada uno), pero el inicio del sistema de coordenadas ahora está en el punto 300 en el eje x
y 200 en el eje y
.
En el siguiente video, agrego un <circle>
rojo al SVG con su centro en el punto 300 en el eje x
y 200 en el eje y
. Se puede observar cómo al cambiar las coordenadas de viewBox
a los mismos valores, también cambia la ubicación del círculo en la esquina superior izquierda del marco, mientras que el tamaño representado del SVG sigue siendo el mismo (700 × 700). Todo lo que hice fue “reencuadrar” los elementos con viewBox
.
Zoom
Podemos cambiar los dos últimos valores dentro de viewBox
para acercar o alejar la imagen. Cuanto mayores sean los valores, más unidades SVG se agregan para que quepan en el viewport
, lo que da como resultado una imagen más pequeña. Si queremos mantener una proporción de 1: 1, el ancho y la altura de nuestro viewBox
deben coincidir con los valores de ancho y alto de nuestro viewport.
Veamos qué sucede en Illustrator cuando cambiamos estos parámetros. El artwork es igual al viewport
que está representada por un cuadrado blanco de 700px. Todo lo demás fuera de esa área es nuestro canvas SVG infinito y queda recortada por default.
La Figura 1 a continuación muestra un punto azul en 900 en eleje x
y 900 en el eje y
. Si cambio los dos últimos valores de viewBox
de 700 a 900 así:
<svg viewBox="300 200 900 900" width="700" height="700">
… entonces el punto azul vuelve a estar casi completamente a la vista, como se ve en la Figura 2 a continuación. Nuestra imagen se redujo porque aumentamos los valores de viewBox
, pero las dimensiones reales de ancho y alto del SVG se mantuvieron iguales, y el punto azul volvió a acercarse al área sin recortar.
Hay un cuadrado rosa como evidencia de cómo la cuadrícula se escala para ajustarse a la ventana gráfica: la unidad se vuelve más pequeña y más líneas de cuadrícula encajan en la misma área del viewport
. Dejo un Pen acá abajo para jugar con los mismos valores y ver ese trabajo en acción:
2. Width y height ausentes
Otra cosa común que miro al depurar SVG en línea es si el archivo contiene los atributos de ancho o alto. Esto no es gran cosa en muchos casos, a menos que el SVG esté dentro de un contenedor con position absolute o un contenedor flex (ya que Safari calcula el valor de ancho de SVG con 0px
en lugar de auto
). Excluir el width o el height en estos casos nos impide ver la imagen completa, como podemos ver al abrir esta demostración de CodePen y compararla en Chrome, Safari y Firefox.
¿La solución? Agregar un width
o height
, ya sea como un atributo de presentación, inline en el atributo de estilo o en CSS. Evitar usar height
sólo, especialmente cuando está configurado al 100%
o en auto
. Otra solución es declarar los valores right
y left
.
Se puede jugar con el siguiente Pen y combinar las diferentes opciones.
3. Colores de fill and stroke involuntarios
También puede ser que estemos aplicando color a la etiqueta <svg>
, ya sea un estilo inline o proveniente de CSS. Eso está bien, pero podría haber otros valores de color a lo largo del código interno o estilos que entren en conflicto con el conjunto de colores en el <svg>
, causando que las partes sean invisibles.
Es por eso que tiendo a buscar los atributos de fill
y stroke
en el código del SVG y los elimino. El siguiente video muestra un SVG que tiene estilos en CSS con un fill
rojo. Hay un par de instancias en la que partes del SVG se pintan de blanco directamente en el código; las eliminé para revelar las piezas que faltan.
4. IDs faltantes
Este puede parecer súper obvio, pero es sorprendente la frecuencia con la que lo veo surgir. Digamos que creamos un archivo SVG en Illustrator y fuimos muy diligentes en nombrar nuestras capas para que obtengan IDs en el código al exportar el archivo. Y digamos que planeamos estilear ese SVG en CSS conectando con estos IDs.
Esa es una buena manera de hacer las cosas. Pero hay muchas ocasiones en las que he visto el mismo archivo SVG exportado por segunda vez a la misma ubicación y los IDs son diferentes, generalmente al copiar/pegar los vectores directamente. Tal vez se agregó una nueva capa, o se cambió el nombre de una de las existentes o algo así. Cualquiera que sea el caso, las reglas de CSS ya no coinciden con los IDs del código SVG, lo que hace que el SVG se presente de manera diferente a lo esperado.
En archivos SVG de gran tamaño, puede que nos resulte difícil encontrar esos IDs. Este es un buen momento para abrir DevTools, inspeccionar la parte del gráfico que no funciona y ver si esos IDs aún coinciden o cambiaron su nombre con alguna versión _1_
por ejemplo.
5. Checklist para clipping y masking
Si encuentro un SVG recortado inesperadamente pero el viewBox
funciona bien, normalmente busco en el CSS las propiedades de clip-path
o mask
que podrían interferir con la imagen. Es tentador seguir mirando el código inline, pero es bueno recordar que el estilo de un SVG podría estar ocurriendo en otro lugar.
El recorte y el enmascaramiento de CSS nos permiten “ocultar” partes de una imagen o elemento. En SVG, <clipPath>
es una operación vectorial que corta partes de una imagen sin resultados intermedios. La etiqueta <mask>
es una operación de píxeles que permite transparencia, efectos de semitransparencia y bordes borrosos.
Esta es una pequeña checklist para depurar casos en los que están involucrados el clip-path
y/o mask
:
- Asegurarse de que el clipping path (o mask) y el gráfico se superpongan entre sí. Las partes superpuestas son las que se muestran.
- Si hay un
path
complejo que no se cruza con nuestro gráfico, internar aplicar transformaciones hasta que coincidan. - Todavía se puede inspeccionar el código interno con DevTools aunque
<clipPath>
o<mask>
no se renderizen, podemos ver su caja. - Copiar el código dentro del
<clipPath>
o<mask>
y pegarlo antes de cerrar la etiqueta</svg>
. Luego agregar unfill
a esas formas y verificar las coordenadas y dimensiones del SVG. Si aún no se ve la imagen, intentar agregaroverflow="visible"
a la etiqueta<svg>
. - Verificar que se use un ID único para
<clipPath>
o<mask>
, y que el mismo ID se aplique a las formas o grupo de formas que están recortadas o enmascaradas. Un ID que no coincida romperá la apariencia. - Comprobar si hay errores tipográficos en el código entre las etiquetas
<clipPath>
o<mask>
. fill
,stroke
,opacity
o algunos otros estilos aplicados a elementos dentro de<clipPath>
son inútiles — la única parte útil es la geometría de la región de relleno de esos elementos. Es por eso que si usamos un<polyline>
se comportará como un<polygon>
y si usamos una<line>
no se verá ningún efecto de recorte.- Si no se ve la imagen después de aplicar una
<mask>
, hay que asegurarse de que el relleno del contenido de la máscara no sea completamente negro. La luminancia del elemento de la máscara determina la opacidad del gráfico final. Podremos ver a través de las partes más brillantes y las partes más oscuras ocultarán el contenido de la imagen.
En este Pen se puede jugar con elementos enmascarados y recortados.
6. Namespaces
¿Sabías que SVG es un lenguaje de markup basado en XML? ¡Bueno, lo es! El namespace
para SVG se establece en el atributo xmlns:
<svg xmlns="http://www.w3.org/2000/svg">
<!-- etc. -->
</svg>
Hay mucho que saber sobre los namespaces en XML y MDN tiene una gran introducción al respecto. Basta con decir que el namespace proporciona contexto al navegador, informándole que el marcado es específico de SVG. La idea es que los namespaces ayuden a evitar conflictos cuando hay más de un tipo de XML en el mismo archivo, como SVG y XHTML. Este es un problema mucho menos común en los navegadores modernos, pero podría ayudar a explicar los problemas de renderizado de un SVG en navegadores más antiguos o navegadores como Gecko que son estrictos al definir tipos de documentos y namespaces.
La especificación SVG 2
no requiere namespaces cuando se utiliza la sintaxis HTML
. Pero es crucial si la compatibilidad con los navegadores anteriores es una prioridad, en esos casos no está de más agregarlo. De esa forma, cuando se define el atributo xmlns
del elemento <html>
, no entrará en conflicto en esos casos excepcionales.
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="700px" height="700px">
<!-- etc. -->
</svg>
</body>
</html>
Esto también es cierto cuando se usa SVG inline en CSS, como cuando lo usamos de background-image
. En el siguiente ejemplo, aparece un icono de checkmark en el input después de una validación exitosa. Así es como se ve el CSS:
textarea:valid {
background: white url('data:image/svg+xml,\
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26">\
<circle cx="13" cy="13" r="13" fill="%23abedd8"/>\
<path fill="none" stroke="white" stroke-width="2" d="M5 15.2l5 5 10-12"/>\
</svg>') no-repeat 98% 5px;
}
Cuando eliminamos el namespace dentro del SVG en la propiedad de background
, la imagen desaparece:
Otro prefijo de namespace común es xlink:href
. Lo usamos mucho cuando hacemos referencia a otras partes del SVG como: patterns, filtros, animaciones o gradientes. La recomendación es comenzar a reemplazarlo con href
ya que el otro está en desuso desde SVG 2
, pero puede haber problemas de compatibilidad con navegadores más antiguos. En ese caso, podemos usar ambos. Solo hay que recordar incluir el namespace xmlns:xlink=”http://www.w3.org/1999/xlink"
si todavía vamos a usar xlink:href
.
¡Seguir aprendiendo SVG!
Espero que estos consejos te ayuden a ahorrar mucho tiempo si te encuentras con problemas de renderizado de SVG inline. Estas son algunas de las cosas que busco. Tal vez tengas otras diferentes — si es así, ¡dímelo en los comentarios!
La conclusión es que vale la pena tener al menos una comprensión básica de las diversas formas en que se puede usar SVG. CodePen Challenges a menudo incorpora SVG y ofrece buenas prácticas. Aquí hay algunos recursos más para subir de nivel:
-
Using SVG with CSS3 and HTML5 (Amelia Bellamy-Royds, Kurt Cagle, Dudley Storey) —Este es para mí la Biblia SVG.
-
Lea Verou tiene un gran conocimiento de SVG y ha hablado bastante sobre el tema (como este video de Frontend United 2019).
-
SVG Animations (Sarah Drasner)
-
SVG Essentials (Amelia Bellamy-Royds, J. David Eisenberg)
-
Practical SVG (Chris Coyier)
Hay otras personas más que sugiero seguir por la cantidad de conocimiento e información que comparten relacionada con SVG:
Este artículo se publicó por primera vez en CSS-Tricks. Gracias a las ediciones de Geoff Graham ♥