Guía completa de sombras CSS: box-shadow, drop-shadow y text-shadow explicados

Domina las tres técnicas de sombra CSS — sintaxis, parámetros, diferencias de renderizado, patrones reales e implicaciones de rendimiento.

~15 min de lectura Feb 2025

Las sombras son una de las herramientas más simples en CSS, pero la mayoría de los tutoriales apenas arañan la superficie. Esta guía cubre los tres mecanismos en profundidad — su sintaxis, parámetros, diferencias de renderizado, casos de uso reales e implicaciones de rendimiento — para que siempre elijas la técnica correcta.

¿Por qué CSS tiene tres propiedades de sombra?

Cada mecanismo de sombra existe para resolver un problema diferente. Surgieron en distintos momentos de la historia de CSS y apuntan a objetivos de renderizado fundamentalmente distintos:

  • box-shadow — sombras para cajas rectangulares (el box model de CSS). Disponible desde CSS 2.1, estandarizado en CSS3.
  • filter: drop-shadow() — sombras que siguen la forma visible real de un elemento, incluyendo la transparencia. Parte de la especificación CSS Filter Effects Level 1.
  • text-shadow — sombras aplicadas directamente a los contornos de glifos. Técnicamente la más antigua de las tres, introducida en CSS 2, eliminada brevemente y re-estandarizada en CSS3.

La confusión surge porque las tres producen lo que el ojo humano percibe como "una sombra", pero el motor de renderizado las gestiona en fases completamente diferentes de la pipeline de pintado.

⚡ Regla práctica

Usa box-shadow para elementos UI con fondos sólidos. Usa drop-shadow para PNGs, SVGs o cualquier cosa con transparencia. Usa text-shadow exclusivamente en texto.

box-shadow: el caballo de batalla

Dibuja una o más sombras detrás (o dentro) del border box de un elemento — la propiedad de sombra más versátil y utilizada.

Sintaxis

box-shadow: [inset] offset-x offset-y [blur-radius] [spread-radius] color;

Cada valor hace exactamente una cosa:

Parámetro Por defecto Qué controla
insetomitido (exterior)Dibuja la sombra dentro del elemento en lugar de detrás
offset-xobligatorioDistancia horizontal. Positivo = derecha, negativo = izquierda
offset-yobligatorioDistancia vertical. Positivo = abajo, negativo = arriba
blur-radius0Cantidad de desenfoque gaussiano. Mayor = más suave y difuso
spread-radius0Expande (+) o contrae (–) la sombra antes del desenfoque
colorcurrentColorColor de sombra — usa siempre rgba() o hsla() para realismo

El spread radius: el parámetro infrautilizado

La mayoría de los desarrolladores usan offset + blur y se detienen ahí. El spread radius desbloquea una clase de efectos completamente diferente. Con spread: 0 y blur: 0 se convierte en un borde CSS perfecto y apilable que no afecta el layout:

/* Layered outline rings — no layout impact */
box-shadow:
  0 0 0 4px rgba(201,184,154,.4),
  0 0 0 8px rgba(201,184,154,.1);

Con un spread negativo puedes convertir una sombra difusa en una direccional que solo aparece debajo de un elemento:

/* Shadow only at the bottom — more realistic */
box-shadow: 0 12px 24px -8px rgba(0,0,0,.6);

Ejemplos en vivo

4px 4px 8px rgba(0,0,0,.7)
0 0 0 4px accent
inset 0 4px 12px
0 2px 4px + 0 8px 24px + ring
0 0 24px + 0 0 48px
light + dark inset pair
backdrop-blur + shadow

Sombras múltiples: el orden importa

Puedes apilar un número ilimitado de sombras con una lista separada por comas. Se renderizan de adelante hacia atrás — la primera sombra de la lista está encima. Esto permite capas de sombras ambientales y direccionales para profundidad natural en temas claros y oscuros.

/* Three-layer system used in serious design systems */
box-shadow:
  0 1px 2px rgba(0,0,0,.3),    /* close shadow: sharp, small */
  0 4px 16px rgba(0,0,0,.25),  /* mid shadow: soft ambient */
  0 0 0 1px rgba(255,255,255,.05); /* subtle highlight ring */

Sombras inset: profundidad y estados presionados

La palabra clave inset mueve la sombra al interior del borde del elemento. La dirección del offset se invierte intuitivamente: un offset Y positivo coloca la sombra a lo largo del borde interno superior, como si la luz viniera de arriba. Esencial para botones presionados, inputs en relieve y neumorfismo:

/* Input focus state — depth without a visible border */
input:focus {
  box-shadow:
    inset 0 2px 6px rgba(0,0,0,.5),
    0 0 0 2px rgba(201,184,154,.4);
}
Herramienta gratuita Generador Box Shadow Ajusta los parámetros visualmente y copia el CSS listo para producción

filter: drop-shadow() — sombras que siguen la forma

filter: drop-shadow() no es una propiedad — es una función de filtro CSS. Los filtros se aplican después del pintado, operando sobre los píxeles finalmente renderizados de un elemento y sus descendientes. Esta distinción tiene dos consecuencias principales:

  • La sombra sigue el contorno visible real, respetando la transparencia alpha en PNGs y la forma de los trazados SVG.
  • El filtro afecta a todo el subárbol, incluidos los hijos. Esto significa que funciona automáticamente en grupos de elementos.

Sintaxis

filter: drop-shadow(offset-x offset-y blur-radius color);

Atención: no hay spread-radius ni palabra clave inset. La especificación los omitió deliberadamente. Si necesitas spread en una sombra que siga la forma, apila dos llamadas drop-shadow() con radios de desenfoque diferentes.

Dónde falla box-shadow y brilla drop-shadow

Imagina un logo PNG transparente sobre un fondo de página con color. Aplica box-shadow y obtendrás una sombra rectangular alrededor del bounding box invisible — la sombra se filtra en las áreas transparentes. Aplica drop-shadow() y la sombra abraza la forma visible real del logo.

La misma lógica aplica a:

  • Elementos SVG — trazados, polígonos, formas compuestas
  • CSS clip-path — la sombra sigue el límite del clip
  • Elementos rotados o transformados — la sombra sigue correctamente la forma post-transformación
  • Grupos de componentes — un filtro en el padre sombrea todos los hijos como unidad
/* SVG icon with proper shadow */
.icon-wrapper {
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.6));
}

/* PNG logo — shadow follows logo shape, not its bounding box */
.logo {
  filter: drop-shadow(2px 4px 12px rgba(0,0,0,.5));
}

/* Stacked for a glow effect on an irregular shape */
.neon-svg {
  filter:
    drop-shadow(0 0 6px rgba(201,184,154,.8))
    drop-shadow(0 0 20px rgba(201,184,154,.4));
}

El compromiso clave: contexto de apilamiento

Aplicar filter crea un nuevo contexto de apilamiento y una nueva capa de composición. Normalmente está bien, pero significa que el elemento ya no puede superponerse correctamente sobre otras capas de composición — lo que ocasionalmente causa problemas de z-index. Si lo encuentras, considera si box-shadow puede aproximar el efecto.

Herramienta gratuita Generador de Filtros CSS Combina drop-shadow con blur, brillo y saturación — vista previa en vivo

text-shadow: profundidad tipográfica

text-shadow se aplica exclusivamente a los contornos de glifos del texto — no al box del elemento. Se pinta en la misma fase que el texto, detrás de los glifos, siendo la elección correcta cuando se quiere profundidad o legibilidad en elementos tipográficos.

Sintaxis

text-shadow: offset-x offset-y [blur-radius] color;

Comparado con box-shadow, no hay spread-radius ni inset. Las sombras múltiples se separan con comas, con el mismo orden de adelante hacia atrás.

Ejemplos en vivo

Heading
2px 2px 4px rgba(0,0,0,.8)
Neon
0 0 10px + 0 0 30px
Emboss
light + dark offset pair
Retro
hard double offset

Casos de uso comunes

Legibilidad sobre imágenes: Un sutil text-shadow: 0 1px 3px rgba(0,0,0,.6) hace legible el texto blanco sobre fotografías brillantes sin necesitar un overlay oscuro.

Tipografía neón/glow: Apila dos sombras de offset cero con radios de desenfoque crecientes. La sombra interior crea el núcleo intenso, la exterior crea el destello atmosférico:

.neon {
  color: #c9b89a;
  text-shadow:
    0 0 8px rgba(201,184,154,.9),
    0 0 24px rgba(201,184,154,.5),
    0 0 60px rgba(201,184,154,.2);
}

Letterpress / relieve: Combina una sombra clara arriba-izquierda con una oscura abajo-derecha. La dirección determina si el texto aparece en relieve o hundido:

/* Raised (light = up-left, dark = down-right) */
text-shadow: -1px -1px 0 rgba(255,255,255,.15), 1px 1px 0 rgba(0,0,0,.6);

/* Recessed (reversed) */
text-shadow:  1px  1px 0 rgba(255,255,255,.1), -1px -1px 0 rgba(0,0,0,.5);

Sombra dura (estilo retro/cómic): Sin blur, offset mayor, sombras duras apiladas:

.retro {
  text-shadow: 3px 3px 0 #7a5c38, 6px 6px 0 rgba(0,0,0,.25);
}
Herramienta gratuita Generador Text Shadow Diseña y exporta efectos text-shadow con vista previa en vivo

Comparación directa

Característicabox-shadowdrop-shadow()text-shadow
ObjetivoBox model del elementoForma de píxeles renderizadosContornos de glifos de texto
Respeta transparenciaNo — ignora alphaSí — sigue la formaN/A (solo texto)
spread-radiusNoNo
Palabra clave insetNoNo
Capas múltiplesSí, separadas por comaSí, funciones encadenadasSí, separadas por coma
Contexto de apilamientoSin nuevo contextoCrea nuevo contextoSin nuevo contexto
Aplica a hijosNoSí (subárbol completo)No
Funciona en SVGSolo bounding boxSí, por trazadoN/A
Animación CSSAnimableAnimableAnimable
Composición GPUA menudo, en capas promovidasSí, siempreRaramente

La pregunta que determina cuál usar

Pregúntate: ¿tiene el elemento un fondo rectangular y opaco? Si sí, usa box-shadow — es más fácil de razonar y no tiene efectos secundarios en el contexto de apilamiento. Si no (PNG transparente, SVG, forma irregular, clip-path), usa drop-shadow(). Si el objetivo es texto, usa text-shadow.

Recetas y patrones para producción

Sistema de elevación (estilo Material)

En lugar de hardcodear valores de sombra en todo el codebase, define una escala de elevación como propiedades CSS personalizadas. Esto hace que la profundidad global sea consistente y fácil de actualizar:

:root {
  --shadow-1: 0 1px 2px rgba(0,0,0,.4);
  --shadow-2: 0 2px 6px rgba(0,0,0,.35), 0 1px 2px rgba(0,0,0,.3);
  --shadow-3: 0 4px 16px rgba(0,0,0,.3), 0 2px 4px rgba(0,0,0,.3);
  --shadow-4: 0 8px 32px rgba(0,0,0,.28), 0 4px 8px rgba(0,0,0,.25);
  --shadow-5: 0 16px 48px rgba(0,0,0,.25), 0 8px 16px rgba(0,0,0,.2);
}

.card      { box-shadow: var(--shadow-2); }
.card:hover { box-shadow: var(--shadow-4); transition: box-shadow .2s ease; }
.modal     { box-shadow: var(--shadow-5); }

Sombras de color

Una de las técnicas más infrautilizadas: en lugar de sombras negras, tinta la sombra con el color dominante del elemento. Se integra mejor en temas claros y oscuros y crea una calidad similar al glow sin resultar agresiva:

/* Button with colored shadow matching brand color */
.btn-primary {
  background: #c9b89a;
  box-shadow: 0 4px 20px rgba(201,184,154,.4), 0 2px 6px rgba(201,184,154,.3);
}
.btn-primary:hover {
  box-shadow: 0 6px 28px rgba(201,184,154,.55), 0 3px 8px rgba(201,184,154,.4);
}

Glassmorfismo con sombra

El glassmorfismo requiere una interacción cuidadosamente calibrada entre backdrop-filter, fondo traslúcido, borde semi-transparente y box-shadow para separar la card del fondo:

.glass-card {
  background: rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(16px) saturate(1.2);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 16px;
  box-shadow:
    0 8px 32px rgba(0,0,0,.4),    /* ambient depth */
    inset 0 1px 0 rgba(255,255,255,.08); /* top highlight */
}
🔧

PixCode Glassmorphism Generator exporta el CSS completo incluyendo prefijos vendor.

Anillos de foco con box-shadow

Reemplazar el outline predeterminado del navegador con box-shadow da control total sobre el estilo manteniendo la accesibilidad. El truco es usar una sombra solo de spread con blur 0:

:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--bg),         /* gap between element and ring */
    0 0 0 4px rgba(201,184,154,.7); /* visible ring */
}

Neumorfismo

El neumorfismo usa pares de sombras inset y outer derivadas del color de fondo. El elemento, la sombra y el fondo deben usar tonos estrechamente relacionados — el contraste extremo rompe la ilusión:

/* Element bg = slightly lighter than page bg */
.neumorphic {
  background: #1c1c1c;
  border-radius: 16px;
  box-shadow:
     8px  8px 16px #0a0a0a,   /* dark shadow: down-right */
    -8px -8px 16px #2e2e2e;   /* light shadow: up-left */
}
.neumorphic.pressed {
  box-shadow:
    inset  4px  4px 10px #0a0a0a,
    inset -4px -4px 10px #2e2e2e;
}

Consideraciones de rendimiento

Las sombras son una de las operaciones de renderizado que más preocupan a los desarrolladores, a menudo sin razón. Esto es lo que ocurre realmente:

✓ Rutas rápidas

box-shadow en capas de composición GPU (position:fixed, will-change:transform). filter: drop-shadow() siempre está acelerado por GPU. Animar box-shadow via transiciones CSS en elementos promovidos.

✗ Rutas lentas

Animar box-shadow en elementos no promovidos desencadena layout + paint en cada frame. Radios de blur grandes en filter: drop-shadow() son costosos. text-shadow con blur muy grande en muchos elementos.

Al animar sombras

El patrón más seguro para sombras animadas (elevaciones hover, estados de carga) es promover primero el elemento y luego transicionar la sombra:

.card {
  will-change: transform;         /* promote to compositing layer */
  transform: translateZ(0);       /* trigger layer in older browsers */
  transition: box-shadow .2s ease, transform .2s ease;
  box-shadow: var(--shadow-2);
}
.card:hover {
  transform: translateY(-2px);    /* move on GPU — free */
  box-shadow: var(--shadow-4);    /* re-composite — also fast */
}
⚠️ Precaución

No apliques will-change indiscriminadamente — cada capa promovida consume memoria GPU. Úsalo solo en elementos que realmente se van a animar, y elimínalo una vez terminada la animación si se añadió via JavaScript.

Rendimiento: blur-radius vs spread-radius

Aumentar blur-radius es más costoso que aumentar spread-radius, porque el blur requiere una convolución gaussiana que escala con el área en píxeles. Una sombra con spread: 10px, blur: 2px es más barata que spread: 0, blur: 12px para la misma huella visual.

Generadores de sombras interactivos en PixCode.io

Las tres técnicas de sombra tienen generadores interactivos dedicados en PixCode — ajusta parámetros con sliders, ve el resultado en vivo y copia el CSS listo para producción con un clic.

Haufig gestellte Fragen

Was ist CSS box-shadow? +
CSS box-shadow fugt einen rechteckigen Schatten hinter einem Element hinzu: offset-x offset-y blur-radius spread-radius color. Sie konnen mehrere Schatten mit Kommas stapeln und das Schlusselwort inset verwenden, um den Schatten innerhalb des Elements zu rendern.
Wie unterscheidet sich filter drop-shadow von box-shadow? +
box-shadow folgt dem rechteckigen Begrenzungsrahmen und ignoriert transparente Pixel. filter drop-shadow verfolgt die tatsachlich sichtbare Form — unverzichtbar fur PNGs mit Transparenz, SVGs und unregelmasige Formen.
Kann man CSS-Schatten ohne Leistungseinbusen animieren? +
Ja, aber vorsichtig. Das Animieren von box-shadow lost Layout und Paint auf nicht-kompositierten Elementen aus. Das sicherste Muster ist die Opazitats-Animation zwischen zwei Pseudo-Elementen mit den Schatten.
Was ist der spread-radius-Parameter in box-shadow? +
Der spread-radius ist der vierte Wert in box-shadow. Ein positiver Wert erweitert den Schatten uber den Unscharbereich hinaus; ein negativer Wert verkleinert ihn. Ein Spread von 0 bedeutet, dass der Schatten genau so gros ist wie das Element vor der Unscharfe.
Wann sollte ich text-shadow statt drop-shadow verwenden? +
Verwenden Sie text-shadow fur typografische Effekte — Lesbarkeit, Leuchteffekte, erhabener Text und Retro-Stile. Verwenden Sie filter drop-shadow auf Elementen, die einer nicht-rechteckigen Grenze folgen mussen.
Wie erstelle ich eine neumorphische Karte mit box-shadow? +
Neumorphismus erfordert zwei Schatten: einen heller als der Hintergrund (oben links) und einen dunkler (unten rechts). Beispiel: box-shadow: 8px 8px 16px #0a0a0a, -8px -8px 16px #2e2e2e auf einer #1c1c1c-Karte uber einem #0e0e0e-Hintergrund.
Welche Browser unterstutzen box-shadow und CSS filter? +
box-shadow wird seit 2011 in allen Browsern unterstutzt (IE 9). filter drop-shadow wird seit 2013 in allen modernen Browsern unterstutzt. Internet Explorer unterstutzt filter nicht.