Una box-shadow es una copia de la caja del elemento, pintada detrás de ella: desplazada por dos offsets, suavizada por un blur, agrandada o encogida por un spread y rellena con un solo color plano. Ese es todo el modelo. box-shadow: 0 8px 24px -6px rgba(16, 18, 42, 0.16); se lee como ningún desplazamiento horizontal, 8 px hacia abajo, un borde suave de 24 px, una forma encogida 6 px por cada lado, en un índigo oscuro al 16% de opacidad. La sombra no ocupa espacio en el layout: nada en la página se mueve para hacerle espacio.
Qué hace cada valor, en orden
Las longitudes se leen por posición, así que no puedes cambiarlas de lugar. El color es la excepción: puede ir en cualquiera de los dos extremos, así que rgba(0, 0, 0, 0.2) 0 4px 8px es tan válido como la misma lista con el color al final.
- Offset X: positivo mueve la sombra a la derecha, negativo a la izquierda.
- Offset Y: positivo la mueve hacia abajo, negativo hacia arriba. Este es el valor que decide dónde está tu luz imaginaria.
- Blur: qué tan ancho es el borde suave. Opcional, vale 0 por defecto y no puede ser negativo.
- Spread: cuánto más grande o más pequeña es la forma de la sombra respecto de la caja. Opcional, vale 0 por defecto y sí puede ser negativo. Como las longitudes son posicionales, no puedes escribir un spread sin escribir antes un blur, aunque ese blur sea 0.
- Color: opcional. Si lo omites, el navegador usa el color de texto del propio elemento, que casi nunca es lo que querías.
Las longitudes aceptan cualquier unidad de longitud de CSS —px, rem, em— pero no porcentajes. Un porcentaje invalida la declaración entera y el navegador la descarta, que es una de las razones más silenciosas por las que una sombra "no hace nada".
El blur no es cuánto se aleja la sombra
Este es el valor que casi todo el mundo interpreta mal. El radio de blur no empuja la sombra más lejos. Describe qué tan ancha es la transición de sólido a transparente, y esa transición está centrada en el borde que la sombra habría tenido. Pon 24 px de blur y la transición abarca unos 24 px: más o menos la mitad cae por fuera de la forma y la otra mitad avanza hacia dentro. La especificación define el resultado como una aproximación a un desenfoque gaussiano con una desviación estándar de la mitad del radio de blur.
De ahí se siguen dos cosas. Un blur grande sin spread se escapa por los lados y por arriba, y por eso una sombra pensada para quedar debajo de una tarjeta termina rodeándola como un halo. Y una sombra con blur pero sin offset se ve por los cuatro lados, porque la mitad de la transición se escapa en todas las direcciones. Eso es un resplandor, no una sombra. Útil para un focus ring, inútil para dar profundidad.
Para qué sirve el spread en realidad
El spread redimensiona el rectángulo de la sombra, y solo después se difumina el resultado. El orden importa: primero inflar, después suavizar.
El spread negativo es la solución al escape de arriba. 0 18px 36px -14px encoge la forma 14 px antes de difuminarla, así que casi nada se escapa hacia los lados y lo que sobrevive se lee como un charco de sombra debajo del elemento en lugar de una niebla a su alrededor. La mayoría de las sombras que se ven bien en una interfaz real tienen un spread negativo en su capa más grande.
El spread es también la forma de conseguir sombra en un solo lado. Hazlo negativo y cercano al valor del blur, y después desplaza en la dirección que quieras: 0 10px 8px -8px pone sombra debajo de un elemento y en ningún otro lugar. Y en una capa inset la dirección se invierte: un spread positivo engrosa la sombra interior, porque la forma crece hacia dentro.
Por qué una sola sombra siempre parece falsa
La luz real hace dos cosas a la vez. Donde un objeto toca una superficie hay una sombra de contacto pequeña, oscura y nítida. Más lejos hay otra mucho más grande, mucho más tenue y difusa. Una sola sombra de CSS puede ser cerrada o suave, nunca las dos, así que se lee como una calcomanía pegada sobre la página en vez de un objeto posado por encima de ella.
La solución es apilar capas. Sepáralas por comas dentro de una misma declaración; la primera de la lista se pinta encima: box-shadow: 0 1px 2px rgba(16, 18, 42, 0.08), 0 8px 24px -12px rgba(16, 18, 42, 0.16);. La capa pequeña y cerrada hace el contacto, la grande y suave hace la luz ambiente, y cada una es lo bastante tenue por su cuenta como para que la suma siga siendo sutil.
Ajustar eso a mano significa editar seis números y recargar entre cada intento, y ahí es donde un generador de sombras con vista previa en vivo se paga solo: mantiene hasta cuatro capas a la vez, te deja editar cada una por separado e imprime la declaración terminada. Con dos capas suele bastar. Dos advertencias: la vista previa es una caja sobre un fondo plano, no tu página, y no escribe text-shadow, que lleva dos o tres longitudes y un color —sin spread y sin inset—, así que el truco del spread negativo de arriba no sirve para el texto.
Por qué tu sombra se ve gris y sucia
Porque es negro puro. Componer negro sobre un color escala todos los canales hacia cero. El tono sobrevive, pero la intensidad del color baja junto con la luminosidad, así que la franja sombreada sobre un fondo cálido queda plana y gris al lado de la superficie que la rodea. La sombra real no hace eso: se rellena con la luz que rebota en todo lo demás, así que conserva un tinte. Usa en su lugar una versión muy oscura del tono de la propia superficie: un azul marino profundo bajo una página gris fría, un marrón oscuro bajo un crema. La geometría no cambia en absoluto, y el resultado deja de leerse como mugre.
Los colores de sombra casi siempre se escriben con rgba(), así que necesitas los valores de canal de ese tinte oscuro y no el hex con el que diseñaste. Un conversor de hex a RGB te lleva ahí en un paso, y además genera los tonos si antes necesitas oscurecer un color de marca. Si lo que se te atraganta es la notación en sí, qué describe cada uno de hex, RGB y HSL es la lectura de base.
Dónde se pintan las sombras inset
Agrega inset a una capa y se dibuja dentro de la caja de padding: encima del fondo, debajo del contenido y recortada por el radio de las esquinas, así que sigue las esquinas redondeadas sin que hagas nada. Eso es lo que hace que un input se vea hundido o que un botón se vea presionado mientras lo mantienes apretado.
Las capas inset y las de fuera pueden convivir en la misma lista separada por comas. Son independientes y se pintan en orden, la primera encima. Las capas de fuera siguen la caja del borde y las inset la caja de padding, y las dos se recortan con el radio de las esquinas, así que el radio y la forma de la sombra están atados: cambias uno y la otra se reforma con él, algo que conviene saber antes de pelearte con cualquiera de los dos. Cómo se comporta border-radius de verdad cubre la mitad que sorprende a la gente.
¿box-shadow o filter: drop-shadow?
box-shadow sigue la caja del borde, siempre. Si tu elemento es un PNG transparente, un ícono SVG o una forma recortada con clip-path, igual te sale un rectángulo flotando detrás. filter: drop-shadow() sigue el canal alfa visible y te da el contorno que en realidad querías.
La contrapartida: drop-shadow cuesta más de renderizar, no acepta ningún valor de spread —así que el truco del spread negativo de arriba no está disponible— y se aplica al elemento y a todo lo que hay dentro, hijos incluidos. Usa box-shadow para rectángulos y rectángulos redondeados, que es la mayor parte de una interfaz, y drop-shadow cuando lo que importa es la silueta.
Qué rompe una sombra que se veía bien
- overflow: hidden la recorta. Una sombra no ocupa espacio en el layout, así que un ancestro que oculta el overflow la corta como a cualquier otra cosa que sobresalga. Agrega padding al padre, o mueve la sombra a un elemento fuera del área recortada.
- Una segunda regla box-shadow reemplaza a la primera. Es una sola propiedad, no una lista a la que se le van agregando cosas. Si una regla posterior define
box-shadow, tus capas anteriores desaparecen: pon todas las capas en la misma declaración. - Animar el blur o el spread repinta cada frame. Eso se vuelve caro rápido en elementos grandes. Pon la sombra en un pseudoelemento y anima la opacidad de ese elemento; la opacidad es barata, volver a difuminar no.
- Las interfaces oscuras casi no la muestran. Negro al 14% sobre una superficie casi negra es casi invisible. Los temas oscuros suelen separar las superficies con un borde claro y tenue, o haciendo más clara la superficie elevada, en lugar de reutilizar los valores de sombra del modo claro.
Una última cosa: prueba sobre el fondo que vas a publicar de verdad. Una sombra afinada sobre blanco puede desaparecer sobre una fotografía o un degradado, y esa es la razón más común de que una tarjeta se vea convincente en el archivo de diseño y plana en la página en vivo.
La versión por capas es genuinamente engorrosa de escribir a mano, así que el generador de box shadow de aquí mantiene cuatro capas vivas a la vez y actualiza el CSS mientras arrastras: cambia el fondo de su vista previa a oscuro antes de darlo por terminado, porque ahí es donde la mayoría de las sombras se caen a pedazos. Si con lo que sigues peleando es el color y no la geometría, construir una paleta de color que aguante explica cómo derivar el tinte oscuro que tu sombra debería haber usado desde el principio.
Preguntas frecuentes
¿Cómo funciona box-shadow en CSS?
El navegador dibuja una copia de la caja del elemento detrás de ella, desplazada por los offsets horizontal y vertical, redimensionada por el spread, suavizada por el blur y rellena con un solo color plano. La forma sigue la caja del borde, incluido cualquier border-radius. Se pinta, no entra en el layout, así que nunca mueve los demás elementos.
¿Qué significan los cuatro números de box-shadow?
En orden: desplazamiento horizontal, desplazamiento vertical, radio de blur y radio de spread. Los dos últimos son opcionales y valen cero por defecto, y el color se puede escribir antes o después de las longitudes. Los porcentajes no se permiten en ninguno de ellos.
¿Cómo hago una sombra en un solo lado?
Dale a la sombra un spread negativo cercano a su valor de blur y después desplázala hacia el lado que quieras. Algo como 0 10px 8px -8px evita que la transición se escape a la izquierda, a la derecha y hacia arriba, así que solo el borde inferior muestra sombra.
¿Por qué no aparece mi box-shadow?
Las causas habituales son un ancestro con overflow: hidden que la recorta, una regla CSS posterior que sobrescribe toda la propiedad box-shadow, o una opacidad tan baja que desaparece contra el fondo. Un porcentaje en una de las longitudes también invalida la declaración entera.
¿Se puede animar un box-shadow?
Sí, box-shadow es animable, pero cambiar el blur o el spread obliga al navegador a repintar la sombra en cada frame y eso es lento en elementos grandes. El truco habitual es poner la sombra en un pseudoelemento ::after y hacer la transición de la opacidad de ese elemento entre dos estados.
Última actualización 19 de septiembre de 2026