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
<usar>
Opción 2: 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!
Soluciones | Todas las formas | Código simple | Bordes suavizados | Fondo 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 ♥