Saltar al contenido

Diseño

CSS Box-Shadow explicado: sintaxis, desenfoque, expansión y rendimiento

9 min de lectura

Copias una sombra de algún generador, la pegas en tu hoja de estilos y el resultado no se parece en nada a la vista previa que acabas de ver. El desenfoque es enorme, el elemento parece flotar diez píxeles sobre la página y añadir una segunda sombra hace que todo desaparezca. El problema no es que box-shadow sea difícil — es que la mayoría de los desarrolladores nunca han aprendido qué controla realmente cada uno de los cinco valores. Esta guía desmonta la propiedad, explica desenfoque contra expansión, muestra sombras en capas, cubre trampas de accesibilidad y oportunidades de rendimiento, y termina con una herramienta que elimina las conjeturas por completo.

Los cinco valores detrás de cada box-shadow

Una declaración completa de box-shadow se ve así:

box-shadow: 4px 6px 12px 0 rgba(0, 0, 0, 0.25);

Léelo de izquierda a derecha. 4px es el offset-x — cuánto se desplaza la sombra horizontalmente. 6px es el offset-y — cuánto se desplaza verticalmente. Estos dos son el mínimo: sin ellos la sombra queda justo detrás del elemento, perfectamente centrada, lo cual rara vez es útil. 12px es el blur-radius. Controla cuánto se suaviza la sombra — no la mueve, difumina los bordes. 0 es el spread-radius. Un valor positivo expande la sombra más allá de la caja del elemento; un valor negativo la encoge. Y rgba(0, 0, 0, 0.25) es el color de sombra con 25 % de opacidad.

Hay un valor sexto opcional: la palabra clave inset. Cuando está presente, la sombra se dibuja dentro del elemento en vez de fuera. Las sombras inset son la forma estándar de crear profundidad interna — campos de entrada, botones pulsados, tarjetas hundidas. Omite la palabra clave y todas las sombras caen hacia afuera por defecto.

Radio de desenfoque contra radio de expansión: la confusión que cuesta horas

Estos dos valores son los que más se intercambian, y la diferencia visual es dramática. El radio de desenfoque no hace la sombra más grande ni más pequeña — controla cuán nítidamente el borde de la sombra pasa a ser transparente. Un desenfoque de 0 produce una sombra de borde duro idéntica a la silueta del elemento. Un desenfoque de 20px crea un gradiente amplio y suave que se extiende mucho más allá del elemento. El navegador lo implementa como un desenfoque gaussiano sobre el mapa de bits de la sombra antes de componerlo bajo el elemento.

El radio de expansión, en cambio, es una operación geométrica directa. Infla o encoge el rectángulo de la sombra antes de aplicar cualquier desenfoque. Una expansión de 4px hace la sombra 4px más grande por cada lado; -4px la hace 4px más pequeña. El efecto práctico: la expansión controla cuán visible es la sombra en primer lugar, mientras que el desenfoque controla cuán suave se ve. Un truco habitual para una tarjeta sutilmente elevada es mantener el desenfoque moderado y la expansión en cero o ligeramente negativa — esto evita el "gran halo oscuro" que surge de un desenfoque grande sin ajuste de expansión.

La trampa del cuarto valor ausente

Cuando escribes tres valores — como box-shadow: 0 4px 8px rgba(0,0,0,0.15) — el tercer número es el desenfoque, no la expansión. La expansión es 0 por defecto. Si en realidad querías poner la expansión en 8px y el desenfoque en otro valor, la forma abreviada es incorrecta y la sombra no coincidirá con tu diseño. Verifica siempre el orden: offset-x, offset-y, blur, spread.

Sombras en capas: una propiedad, múltiples valores

CSS permite apilar múltiples sombras en el mismo elemento separándolas con comas. Cada capa se renderiza de primera a última — la primera sombra está arriba, y cada sombra subsiguiente se sitúa detrás. Así se construyen los efectos de profundidad realista: una sola sombra luce plana y artificial, pero dos o tres capas cuidadosamente ajustadas producen la sombreada sutil que nuestros ojos asocian con objetos reales.

.card {
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.07),
    0 4px 8px rgba(0, 0, 0, 0 12),
    0 12px 24px rgba(0, 0, 0, 0.08);
}

En este ejemplo, la primera sombra es un acento estrecho y de baja opacidad justo debajo de la tarjeta — simula la sombra de contacto donde la superficie toca la mesa. La segunda crea la sensación principal de elevación con una expansión suave de rango medio. La tercera es un velado amplio y tenue que implica la iluminación ambiental general. El resultado se lee como profundidad natural en lugar de una mancha gris plana.

Un segundo patrón habitual es combinar una sombra nítida con una difuminada. La capa nítida (desenfoque bajo o cero, expansión ligeramente negativa) crea un borde definido, mientras que la capa suave rellena la difusión ambiental. Material Design usa exactamente este enfoque: una sombra dura corta más una suave amplia produce el efecto de papel levantado que se ve correcto a cualquier nivel de zoom.

Errores comunes y cómo corregirlos

El error más frecuente es usar un valor de desenfoque demasiado grande para el tamaño del elemento. Un botón de 36px de alto no debería tener un desenfoque de 60px — el resultado es una nube difusa que despega el elemento de la superficie por completo. Como regla práctica, mantén el desenfoque entre 0,5× y 2× la dimensión más corta del elemento para una elevación con aspecto natural.

El segundo error es olvidar la segunda capa implícita. Cuando un diseño llama a "la sombra del diseño", a menudo se ve así porque el diseñador apiló dos o tres box-shadows en Figma o Sketch. Copiar solo la sombra visible superior produce una sombra demasiado nítida o demasiado oscura. Comprueba siempre si el mockup usa sombras en capas — casi siempre lo hace.

Una trampa más es usar filter: drop-shadow() como sinónimo de box-shadow. No son lo mismo. Box-shadow sigue el borde rectangular del elemento, mientras que drop-shadow respeta la transparencia alfa — un elemento con fondo transparente y un icono SVG redondeado recibirá una sombra que traza la forma del icono. Pero drop-shadow no admite radio de expansión, ni inset, y rinde peor en listas largas.

  • Desenfoque arbitrario enorme: mantén el desenfoque proporcional al tamaño del elemento; 4px–16px cubre la mayoría de tarjetas UI.
  • Planitud de una sola capa: apila al menos dos sombras — una capa de contacto estrecha y una capa ambient amplia.
  • Desplazamiento demasiado grande: desplazamientos superiores a 8–10px hacen el elemento despegado; para elevación realista mantenlos pequeños.
  • Olvidar inset: botones pulsados y campos de entrada casi siempre necesitan sombras inset, no externas.

Accesibilidad: texto con sombra y contraste

Box-shadow en un contenedor generalmente es seguro para la accesibilidad — no afecta las ratios de contraste del texto. Pero text-shadow, que funciona de forma similar, puede reducir la legibilidad cuando se abusa de él. WCAG 2.1 no regula text-shadow directamente, pero el requisito de contraste entre el texto y su fondo adyacente sigue siendo aplicable. Un text-shadow del mismo color que el fondo crea un efecto de halo que puede difuminar las formas de las letras para usuarios con baja visión.

La regla práctica: mantén el desenfoque de text-shadow pequeño (1px–2px), usa opacidad baja (menos del 30 %) y nunca dependas únicamente de una sombra para separar el texto de un fondo con imágenes. Si el fondo es una imagen o degradado, la sombra es decorativa — entre el color del texto y el tono subyacente más oscuro/más claro del fondo siempre debe haber contraste suficiente. En caso de duda, pasa el elemento por un verificador de contraste con el fondo visible detrás de la sombra.

Sombras en elementos interactivos

Los estados hover y focus que aumentan la intensidad de la sombra (más desenfoque u opacidad más alta) mejoran la percepción para usuarios que dependen de la retroalimentación visual. WCAG no lo exige estrictamente, pero es una práctica ampliamente recomendada que también beneficia la navegación por teclado: la sombra crece cuando el elemento recibe :focus-visible, ofreciendo una señal clara sin depender solo del contorno del navegador.

Rendimiento: box-shadow contra filtro contra imágenes

Box-shadow es una propiedad CSS que los navegadores rasterizan al pintar la capa del elemento. En hardware moderno, unas pocas box-shadows tienen coste despreciable. La preocupación de rendimiento aparece en dos escenarios: listas largas con decenas de elementos con sombra, y sombras en elementos con muchos hijos que activan repintados frecuentes durante la animación.

TécnicaSoporte de expansiónSoporte de insetRespeta alfaAmigable con GPUMejor uso
box-shadowSíSíNo (pinta border-box)BuenoTarjetas, botones, contenedores
filter: drop-shadow()NoNoSí (sigue alfa)ModeradoIconos, imágenes con fondo transparente
PNG pre-renderizadoVía imagenN/ASíN/A (raster)Sombras decorativas complejas en elementos estáticos
text-shadowNoN/ASíBuenoBrillo de titular, profundidad sutil de texto

La guía general: usa box-shadow para componentes de UI, filter: drop-shadow() cuando necesites sombras con trazado alfa en imágenes o iconos, y evita imágenes de sombra prerenderizadas a menos que el visual sea realmente complejo y estático. Animar box-shadow es posible pero activa un repintado por cada frame; para animación fluida a 60fps, considera combinar transform: translateZ(0) o will-change: transform para promover el elemento a su propia capa del compositor, o coloca la sombra en un pseudo-elemento que se promueva independientemente.

El generador de box-shadow en Convrs

Convrs ofrece un generador de box-shadow que elimina las conjeturas de la creación de sombras. Ajusta offset-x, offset-y, desenfoque, expansión y color con deslizadores mientras ves una vista previa en vivo del resultado sobre diferentes colores de fondo. Añade y reordena capas para construir profundidad realista. Cada cambio actualiza la salida de CSS al instante — cópiala directamente en tu hoja de estilos. La herramienta funciona enteramente en tu navegador; ningún valor de sombra ni vista previa se envía a ningún servidor.

Buy me a coffee