03/04/2017
En el vasto universo del diseño web y el desarrollo de interfaces, los detalles marcan la diferencia entre una experiencia de usuario plana y una que es inmersiva, intuitiva y visualmente atractiva. Uno de los recursos más poderosos y a la vez sutiles para lograrlo son las sombras. Lejos de ser un mero adorno, las sombras aportan profundidad, definen jerarquías y guían la atención del usuario, simulando un entorno tridimensional en una pantalla bidimensional. Desde la sombra de una tarjeta de producto hasta los efectos dinámicos en un juego basado en navegador, dominar su implementación es una habilidad crucial. En este artículo, exploraremos a fondo las diferentes técnicas para crear y manipular sombras, abarcando desde el clásico box-shadow de CSS hasta las capacidades dinámicas del HTML Canvas y la potente función drop-shadow.

El Estándar de Oro: Creando Profundidad con box-shadow en CSS
Cuando pensamos en sombras en CSS, la propiedad box-shadow es, sin duda, la primera que nos viene a la mente. Esta propiedad es increíblemente versátil y nos permite aplicar una o más sombras al cuadro de un elemento. Su sintaxis es sencilla de aprender pero difícil de dominar, ofreciendo un control granular sobre el aspecto final de la sombra.
La sintaxis básica se compone de varios valores:
- Desplazamiento Horizontal (offset-x): Un valor positivo desplaza la sombra hacia la derecha, mientras que uno negativo la mueve hacia la izquierda.
- Desplazamiento Vertical (offset-y): Un valor positivo desplaza la sombra hacia abajo, y uno negativo, hacia arriba.
- Radio de Desenfoque (blur-radius): Un valor mayor crea una sombra más borrosa y difuminada. Un valor de 0 produce una sombra nítida y sin desenfoque. Este valor es opcional.
- Radio de Extensión (spread-radius): Un valor positivo hace que la sombra se expanda y sea más grande que el elemento, mientras que uno negativo la contrae. Es opcional.
- Color: Define el color de la sombra. Se puede usar cualquier formato de color CSS, como hexadecimal, RGB, RGBA o HSL.
- Inset (opcional): Si se incluye esta palabra clave, la sombra se proyectará hacia el interior del elemento en lugar de hacia afuera.
Veamos un ejemplo práctico:
.mi-tarjeta { width: 200px; height: 150px; background-color: #fff; /* Sombra sutil y moderna */ box-shadow: 5px 10px 15px 0px rgba(0, 0, 0, 0.1); }Una de las grandes ventajas de box-shadow es la capacidad de apilar múltiples sombras separándolas por comas. Esto permite crear efectos de profundidad mucho más realistas y complejos.
.elemento-complejo { box-shadow: 0 1px 1px rgba(0,0,0,0.12), 0 2px 2px rgba(0,0,0,0.12), 0 4px 4px rgba(0,0,0,0.12), 0 8px 8px rgba(0,0,0,0.12), 0 16px 16px rgba(0,0,0,0.12); }Sombras Vivas: Dibujando con el Contexto 2D de Canvas
Mientras que CSS es ideal para elementos estáticos de la interfaz, el HTML Canvas brilla cuando necesitamos control dinámico y programático sobre los gráficos, como en juegos, animaciones o visualizaciones de datos. El API de renderizado 2D de Canvas también tiene su propio conjunto de propiedades para generar sombras.
Para añadir una sombra a una forma dibujada en Canvas, debemos configurar las propiedades de sombra en el contexto de renderizado (comúnmente llamado ctx) antes de dibujar la forma. Las propiedades clave son:
ctx.shadowColor: Un string que representa el color de la sombra, similar a CSS.ctx.shadowBlur: Un número que indica el nivel de desenfoque.ctx.shadowOffsetX: El desplazamiento horizontal de la sombra.ctx.shadowOffsetY: El desplazamiento vertical de la sombra.
Un punto crucial a entender es cómo interactúa la opacidad. La transparencia de la sombra se ve afectada por el nivel de transparencia del objeto al que se aplica. Por ejemplo, si la sombra tiene una opacidad del 80% (rgba(255, 0, 0, 0.8)) y se aplica a un relleno con una opacidad del 20% (rgba(0, 255, 0, 0.2)), el valor alfa resultante de la sombra será el producto de ambos: 0.8 * 0.2 = 0.16. Esto ofrece un control muy fino sobre el resultado final.

Aquí tienes un ejemplo práctico que dibuja un rectángulo relleno y otro con solo un borde, ambos con la misma sombra:
<canvas id="canvas"></canvas> <script> const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); // Configuración de la Sombra ctx.shadowColor = "rgb(255 0 0 / 80%)"; // Rojo con 80% de opacidad ctx.shadowBlur = 8; ctx.shadowOffsetX = 30; ctx.shadowOffsetY = 20; // Rectángulo relleno con un color translúcido ctx.fillStyle = "rgb(0 255 0 / 20%)"; // Verde con 20% de opacidad ctx.fillRect(10, 10, 150, 100); // Rectángulo con borde translúcido ctx.lineWidth = 10; ctx.strokeStyle = "rgb(0 0 255 / 60%)"; // Azul con 60% de opacidad ctx.strokeRect(10, 10, 150, 100); </script>En este código, la sombra del relleno verde será mucho más transparente que la sombra del borde azul, demostrando cómo la opacidad del elemento padre influye directamente en la visibilidad de la sombra.
El Duelo de las Sombras: `box-shadow` vs. `filter: drop-shadow()`
Durante mucho tiempo, box-shadow fue la única opción para sombrear elementos. Sin embargo, tiene una limitación fundamental: siempre se aplica al cuadro delimitador rectangular del elemento, ignorando cualquier transparencia dentro de él. Esto es un problema cuando queremos aplicar una sombra a una forma no rectangular, como un logo en formato PNG con fondo transparente.
Aquí es donde entra en juego la función drop-shadow() de la propiedad filter de CSS. A diferencia de box-shadow, drop-shadow actúa como una máscara alfa, lo que significa que la sombra se proyecta desde los píxeles opacos del elemento, respetando su forma real y su transparencia.
Para ilustrar la diferencia, imagina aplicar una sombra a una imagen de una estrella con fondo transparente. Con box-shadow, obtendrías una sombra cuadrada detrás de la estrella. Con drop-shadow, obtendrías una sombra con la forma perfecta de la estrella.

A continuación, una tabla comparativa para aclarar sus diferencias:
| Característica | box-shadow | filter: drop-shadow() |
|---|---|---|
| Forma de la Sombra | Rectangular, basada en el cuadro del elemento (border-box). | Sigue el contorno de los píxeles visibles del elemento (máscara alfa). |
| Sintaxis | Propiedad independiente: box-shadow: X Y Blur Color; | Función dentro de la propiedad filter: filter: drop-shadow(X Y Blur Color); |
| Parámetro `spread` | Sí, permite expandir o contraer la sombra. | No, no tiene un parámetro equivalente. |
| Parámetro `inset` | Sí, permite crear sombras internas. | No, solo crea sombras externas. |
| Aceleración por hardware | Generalmente bien optimizada por los navegadores. | Puede ser más intensiva para el rendimiento, ya que requiere un análisis a nivel de píxel. |
Preguntas Frecuentes (FAQ)
¿Cuándo debería usar box-shadow y cuándo drop-shadow?
Usa box-shadow para la mayoría de los elementos de la interfaz, como botones, tarjetas, modales y contenedores. Es más versátil para el diseño de UI gracias a sus parámetros `spread` e `inset`. Reserva drop-shadow para cuando necesites que la sombra se ajuste a la forma de un contenido no rectangular, como imágenes con transparencia (PNGs, SVGs) o texto complejo.
¿Es posible animar las sombras en CSS?
¡Sí! Tanto box-shadow como filter son propiedades que se pueden animar utilizando transition para cambios de estado (como en un :hover) o con @keyframes para animaciones más complejas. Sin embargo, ten en cuenta que animar sombras puede ser costoso en términos de rendimiento, especialmente en dispositivos de baja potencia. Es recomendable animar principalmente el `offset` y la opacidad en lugar del `blur` para obtener animaciones más fluidas.
¿Por qué mi `drop-shadow` no funciona en elementos con fondo?
Recuerda que drop-shadow funciona sobre la base de la transparencia. Si aplicas esta propiedad a un `div` con un `background-color` sólido, el resultado será visualmente idéntico a un box-shadow, ya que todo el cuadro del `div` es opaco. Su verdadero poder se revela en elementos que tienen partes transparentes.
¿Cómo puedo optimizar el rendimiento de las sombras?
Para optimizar, utiliza sombras sutiles y evita valores de desenfoque (`blur`) excesivamente grandes. Si es posible, aplana las sombras en una imagen de fondo para elementos estáticos. Al animar, intenta usar la propiedad `transform` para mover un pseudo-elemento con la sombra en lugar de animar la propiedad `box-shadow` directamente, ya que esto suele ser más eficiente para el navegador.
Si quieres conocer otros artículos parecidos a Domina las Sombras en la Web: CSS y Canvas puedes visitar la categoría Juegos.
