RSS 11 April 2021

Agregar doble borde a formas SVG

Explorando 7 formas diferentes con sintaxis CSS y SVG.

#svg#tutorial#espanol

Supongamos que alguien te pide que agregues un borde doble a algunas formas geométricas en SVG aleatorias. Por algun motivo, no podes usar ningún editor gráfico, deben generarse en tiempo de ejecución, por lo que tenes que resolverlo con CSS o dentro de la sintaxis SVG.

Tu primera pregunta podría ser: ¿Hay algo como stroke-style: double en SVG? La respuesta es aún no y tampoco es tan fácil. Pero voy a hacer el intento de todos modos para ver qué métodos puedo descubrir. Voy a explorar las posibilidades de tres formas básicas diferentes: círculo, rectángulo y polígono. Señalando las que pueden mantener un color transparente en medio de las dos líneas.

Alerta de spoiler: todos los resultados tienen sus desventajas, al menos con CSS y SVG, pero les muestro mis intentos.

Las soluciones simples

Estos no funcionan con todas las formas, pero son las soluciones más fáciles.

outline y box-shadow

Las propiedades CSS outline y box-shadow solo se aplican al bounding box de la forma o SVG, por lo que ambas son excelentes soluciones solo para cuadrados y rectángulos. También permiten colores flexibles usando custom properties.

Solo se necesitan dos líneas de CSS con "outline", además de que mantiene el color de fondo visible a través de la forma.

  • 🙁 Solución solo para una forma.
  • ✅ Código sencillo
  • ✅ Los bordes son suaves
  • ✅ Fondo transparente

box-shadow solo necesita una línea de CSS, pero tenemos que asegurarnos de que cada forma tenga su propio SVG ya que no podemos aplicar box-shadow directamente a las formas. Otra cosa a tener en cuenta es que tenemos que aplicar el color del fondo en la declaración.

  • 🙁 Solución solo para una forma
  • ✅ Código sencillo
  • ✅ Los bordes son suaves
  • 🙁 Sin fondo transparente

Gradientes SVG

Los degradados radiales SVG solo funcionan en círculos ☺️. Podemos aplicar directamente el degradado en el stroke o trazo, pero es mejor usar variables ya que tenemos que declarar los colores muchas veces en el código.

  • 🙁 Solución solo para una forma
  • ✅ Código sencillo
  • 🙁 Los bordes son suaves
  • 🙁 Sin fondo transparente

Soluciones para todas las formas

Estos funcionarán con todas las formas, pero el código podría volverse engorroso o complejo.

filter: drop-shadow()

¡Finalmente, una solución para todas las formas! Debemos tener cada forma en su propio <svg> ya que el filtro no se aplicará directamente a las formas. Estamos usando una declaración en CSS y tenemos colores flexibles usando variables. ¿Lo malo? Los bordes no se ven muy suaves.

  • ✅ Una solución para todas las formas
  • ✅ Código sencillo
  • 🙁 Los bordes se ven pixelados
  • 🙁 Sin fondo transparente

SVG filters

Esta es una solución muy flexible. Podemos crear un filtro y agregarlo a las formas a través del atributo filter de SVG. La parte complicada acá es el filtro en sí. Necesitaremos tres paints, una para el borde exterior, otra para rellenar el fondo y la última para pintar la forma en el frente. El resultado se ve mejor que usar drop-shadow, pero los bordes aún se ven pixelados.

  • ✅ Una solución para todas las formas
  • 🙁 Código complejo
  • 🙁 Los bordes se ven pixelados
  • 🙁 Sin fondo transparente

Reusando formas

Hay un par de opciones posibles aquí.

Opción 1: Transformaciones

Esta solución requiere transformaciones. Colocamos una figura sobre la otra, donde la figura principal tiene un color de relleno y un color de trazo, y la otra figura no tiene relleno, un trazo rojo, y se escala y reposiciona en el centro. Definimos nuestras formas en <defs>. El truco es traducir la mitad del viewBox al espacio negativo para que, cuando los escalemos, podamos hacerlo desde el centro de la figura.

  • ✅ Una solución para todas las formas
  • 🙁 Código duplicado
  • ✅ Los bordes son suaves
  • ✅ Fondo transparente

Opción 2: <usar>

Encontré una solución inteligente en la [lista de correo de www-svg](https://lists.w3.org/Archives/Public/www- svg/2013Jan/0005.html) de Doug Schepers que usa SVG <use>. Nuevamente, requiere definir las formas una vez y referirse a ellas dos veces usando <use>. Esta vez la forma principal tiene un trazo más grande. La segunda forma tiene la mitad del trazo de la forma principal, sin relleno y un trazo que coincide con el color de fondo.

  • ✅ Una solución para todas las formas
  • 🙁 Código duplicado
  • ✅ Los bordes son suaves
  • 🙁 Sin fondo transparente

¡Acá están los resultados completos!

Solo para que los tengas todos en un solo lugar. ¡Avísame si se te ocurren otras posibles soluciones!

SolucionesTodas las formasCódigo simpleBordes suavizadosFondo transparente
outline🙁
box-shadow🙁🙁
SVG gradients🙁🙁🙁
filter: drop-shadow()🙁🙁
SVG filters🙁🙁🙁
Reusando formas:
Tranforms
🙁
Reusing shapes:
<use>
🙁🙁

Este artículo se publicó por primera vez en CSS-Tricks con ediciones de Chris Coyier y Geoff Graham

Let's stay in touch.

mbeldi@gmail.com