Der vollständige CSS-Schatten-Guide: box-shadow, drop-shadow und text-shadow erklärt
Alle drei CSS-Schattentechniken meistern — Syntax, Parameter, Rendering-Unterschiede, Praxis-Patterns und Performance-Tipps.
Schatten gehören zu den einfachsten Werkzeugen in CSS, doch die meisten Tutorials kratzen nur an der Oberfläche. Dieser Guide behandelt alle drei Schattenmechanismen tiefgehend — Syntax, Parameter, Rendering-Unterschiede, reale Anwendungsfälle und Performance-Implikationen — damit du jedes Mal die richtige Technik wählst.
Warum hat CSS drei Schatten-Eigenschaften?
Jeder Schattenmechanismus löst ein anderes Problem. Sie entstanden zu verschiedenen Zeitpunkten in der CSS-Geschichte und adressieren grundlegend unterschiedliche Rendering-Ziele:
box-shadow— Schatten für rechteckige Boxen (das CSS Box-Modell). Seit CSS 2.1 verfügbar, in CSS3 standardisiert.filter: drop-shadow()— Schatten, die der tatsächlich sichtbaren Form eines Elements folgen, einschließlich Transparenz. Teil der CSS Filter Effects Level 1 Spezifikation.text-shadow— Schatten, die direkt auf Glyphen-Konturen angewendet werden. Technisch die älteste der drei, in CSS 2 eingeführt, kurz entfernt, dann in CSS3 re-standardisiert.
Die Verwirrung entsteht, weil alle drei das erzeugen, was das menschliche Auge als „Schatten" wahrnimmt, aber die Rendering-Engine sie in völlig verschiedenen Phasen der Painting-Pipeline verarbeitet.
Verwende box-shadow für UI-Elemente mit soliden Hintergründen. Verwende drop-shadow für PNGs, SVGs oder alles mit Transparenz. Verwende text-shadow ausschließlich auf Text.
box-shadow: das Arbeitstier
Zeichnet einen oder mehrere Schatten hinter (oder innerhalb) der Border-Box eines Elements — die vielseitigste und meistgenutzte Schatten-Eigenschaft.
Syntax
box-shadow: [inset] offset-x offset-y [blur-radius] [spread-radius] color; Jeder Wert erfüllt genau eine Aufgabe:
| Parameter | Standard | Was er steuert |
|---|---|---|
inset | weggelassen (außen) | Zeichnet den Schatten innerhalb statt hinter dem Element |
offset-x | erforderlich | Horizontaler Abstand. Positiv = rechts, negativ = links |
offset-y | erforderlich | Vertikaler Abstand. Positiv = unten, negativ = oben |
blur-radius | 0 | Gaussian-Blur-Stärke. Höher = weicher und breiter |
spread-radius | 0 | Erweitert (+) oder verkleinert (–) den Schatten vor dem Blur |
color | currentColor | Schattenfarbe — immer rgba() oder hsla() für Realismus verwenden |
Der Spread-Radius: der unterschätzte Parameter
Die meisten Entwickler nutzen Offset + Blur und hören dort auf. Der Spread-Radius erschließt eine völlig andere Klasse von Effekten. Bei spread: 0 und blur: 0 wird er zu einem perfekten, stapelbaren CSS-Rahmen ohne Layout-Auswirkungen:
/* 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); Mit einem negativen Spread kann ein unscharfer Schatten in einen gerichteten umgewandelt werden, der nur unterhalb eines Elements erscheint:
/* Shadow only at the bottom — more realistic */
box-shadow: 0 12px 24px -8px rgba(0,0,0,.6); Live-Beispiele
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 Mehrere Schatten: Die Reihenfolge zählt
Mit einer kommaseparierten Liste können beliebig viele Schatten gestapelt werden. Sie werden von vorne nach hinten gerendert — der erste Schatten liegt oben. So lassen sich Ambient- und Richtungsschatten für natürliche Tiefe in hellen und dunklen Themes kombinieren.
/* 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 */ Inset-Schatten: Tiefe und gedrückte Zustände
Das inset-Schlüsselwort verschiebt den Schatten innerhalb der Border-Kante des Elements. Die Offset-Richtung kehrt sich intuitiv um: ein positiver Y-Offset platziert den Schatten entlang der oberen Innenkante, als käme das Licht von oben. Unverzichtbar für gedrückte Buttons, geprägte Eingabefelder und Neumorphismus:
/* 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);
} Kostenloses Tool Box-Shadow-Generator Alle Parameter visuell anpassen und produktionsreifes CSS kopieren filter: drop-shadow() — formgebundene Schatten
filter: drop-shadow() ist keine Eigenschaft — es ist eine CSS-Filter-Funktion. Filter werden nach dem Painting angewendet und arbeiten auf den final gerenderten Pixeln eines Elements und seiner Nachfolger. Diese Unterscheidung hat zwei wesentliche Konsequenzen:
- Der Schatten folgt dem tatsächlich sichtbaren Umriss und respektiert Alpha-Transparenz in PNGs und die Form von SVG-Pfaden.
- Der Filter betrifft den gesamten Teilbaum, einschließlich aller Kinder. Das bedeutet, er funktioniert automatisch für Gruppen von Elementen.
Syntax
filter: drop-shadow(offset-x offset-y blur-radius color); Hinweis: kein spread-radius und kein inset-Schlüsselwort. Die Spezifikation hat sie bewusst ausgelassen. Für Spread bei formgebundenen Schatten zwei drop-shadow()-Aufrufe mit unterschiedlichen Blur-Radien stapeln.
Wo box-shadow versagt und drop-shadow glänzt
Stelle dir ein transparentes PNG-Logo auf einem farbigen Seitenhintergrund vor. Mit box-shadow entsteht ein rechteckiger Schatten um die unsichtbare Bounding-Box — der Schatten blutet in die transparenten Bereiche. Mit drop-shadow() schmiegt sich der Schatten an die tatsächliche Logo-Form.
Dieselbe Logik gilt für:
- SVG-Elemente — Pfade, Polygone, zusammengesetzte Formen
- CSS clip-path — der Schatten folgt der Clip-Grenze
- Rotierte oder transformierte Elemente — der Schatten folgt korrekt der Form nach der Transformation
- Komponentengruppen — ein Filter auf dem Parent beschattet alle Kinder als Einheit
/* 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));
} Der entscheidende Kompromiss: Stacking Context
Das Anwenden von filter erstellt einen neuen Stacking Context und einen neuen Compositing-Layer. Das ist meist in Ordnung, bedeutet aber, dass das Element nicht mehr korrekt über andere Compositing-Layer hinausgehen kann — was gelegentlich z-index-Probleme verursacht. Falls das auftritt, prüfen, ob box-shadow den Effekt annähern kann.
text-shadow: typografische Tiefe
text-shadow wird ausschließlich auf die Glyphen-Konturen von Text angewendet — nicht auf die Box des Elements. Es wird in derselben Phase wie der Text selbst gezeichnet, hinter den Glyphen, und ist die richtige Wahl, wenn Tiefe oder Lesbarkeit auf typografischen Elementen gewünscht wird.
Syntax
text-shadow: offset-x offset-y [blur-radius] color; Im Vergleich zu box-shadow gibt es keinen spread-radius und kein inset. Mehrere Schatten werden durch Kommas getrennt, mit derselben Vorne-nach-hinten-Reihenfolge.
Live-Beispiele
2px 2px 4px rgba(0,0,0,.8) 0 0 10px + 0 0 30px light + dark offset pair hard double offset Häufige Anwendungsfälle
Lesbarkeit über Bildern: Ein dezentes text-shadow: 0 1px 3px rgba(0,0,0,.6) macht weißen Text über heller Fotografie lesbar, ohne ein dunkles Overlay zu benötigen.
Neon/Glow-Typografie: Zwei Null-Offset-Schatten mit zunehmenden Blur-Radien stapeln. Der innere Schatten erzeugt den intensiven Kern, der äußere den atmosphärischen Schimmer:
.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 / Prägung: Einen hellen Schatten oben-links mit einem dunklen unten-rechts kombinieren. Die Richtung bestimmt, ob der Text erhaben oder vertieft erscheint:
/* 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); Harter Drop Shadow (Retro/Comic-Stil): Kein Blur, größerer Offset, gestapelte harte Schatten:
.retro {
text-shadow: 3px 3px 0 #7a5c38, 6px 6px 0 rgba(0,0,0,.25);
} Kostenloses Tool Text-Shadow-Generator Text-Shadow-Effekte mit Live-Vorschau gestalten und exportieren Direkter Vergleich
| Eigenschaft | box-shadow | drop-shadow() | text-shadow |
|---|---|---|---|
| Ziel | Element-Box-Modell | Gerenderter Pixel-Umriss | Text-Glyphen-Konturen |
| Respektiert Transparenz | Nein — ignoriert Alpha | Ja — formgebunden | N/A (nur Text) |
| spread-radius | Ja | Nein | Nein |
| inset-Schlüsselwort | Ja | Nein | Nein |
| Mehrere Layer | Ja, kommasepariert | Ja, verkettete Funktionen | Ja, kommasepariert |
| Stacking Context | Kein neuer Context | Erstellt neuen Context | Kein neuer Context |
| Gilt für Kinder | Nein | Ja (gesamter Teilbaum) | Nein |
| Funktioniert auf SVG | Nur Bounding Box | Ja, pro Pfad | N/A |
| CSS-Animation | Animierbar | Animierbar | Animierbar |
| GPU-Compositing | Oft, auf geförderten Layern | Ja, immer | Selten |
Die eine Frage, die die Wahl bestimmt
Frage dich: Hat das Element einen rechteckigen, opaken Hintergrund? Wenn ja, verwende box-shadow — einfacher zu handhaben und ohne Stacking-Context-Nebeneffekte. Wenn nein (transparentes PNG, SVG, unregelmäßige Form, clip-path), verwende drop-shadow(). Wenn das Ziel Text ist, verwende text-shadow.
Produktions-Rezepte und Patterns
Elevations-System (Material-Stil)
Statt Schatten-Werte im gesamten Codebase hartzucodieren, eine Elevations-Skala als CSS Custom Properties definieren. Das macht globale Tiefe konsistent und einfach aktualisierbar:
: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); } Farbige Schatten
Eine der am meisten unterschätzten Techniken: Statt schwarzer Schatten den Schatten mit der dominanten Farbe des Elements tönen. Das wirkt in hellen und dunklen Themes natürlicher und erzeugt eine Glow-ähnliche Qualität ohne aggressiv zu wirken:
/* 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);
} Glassmorphismus mit Schatten
Glassmorphismus erfordert ein sorgfältig kalibriertes Zusammenspiel von backdrop-filter, transluzentem Hintergrund, semi-transparentem Rahmen und box-shadow, um die Karte vom Hintergrund zu trennen:
.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 exportiert vollständige CSS inklusive Vendor-Prefixes exportiert.
Focus-Ringe mit box-shadow
Den Standard-Browser-outline durch box-shadow ersetzen gibt volle Kontrolle über den Stil bei erhaltener Barrierefreiheit. Der Trick ist ein rein spread-basierter Schatten bei 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 */
} Neumorphismus
Neumorphismus verwendet gepaarte Inset- und Outer-Schatten in hellen und dunklen Varianten, die von der Hintergrundfarbe abgeleitet werden. Element, Schatten und Hintergrund müssen eng verwandte Töne verwenden — extremer Kontrast bricht die Illusion:
/* 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;
} Performance-Überlegungen
Schatten gehören zu den Rendering-Operationen, über die Entwickler sich am meisten sorgen, oft ohne Grund. Hier ist, was tatsächlich passiert:
✓ Schnelle Pfade
box-shadow auf GPU-Compositing-Layern (position:fixed, will-change:transform). filter: drop-shadow() ist immer GPU-beschleunigt. box-shadow via CSS-Transitions auf geförderten Elementen animieren.
✗ Langsame Pfade
box-shadow auf nicht geförderten Elementen animieren löst bei jedem Frame Layout + Paint aus. Große Blur-Radien bei filter: drop-shadow() sind teuer. text-shadow mit sehr großem Blur auf vielen Elementen.
Schatten animieren
Das sicherste Pattern für animierte Schatten (Hover-Elevationen, Ladezustände) ist, das Element zuerst zu fördern und dann den Schatten zu transitionieren:
.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 */
} will-change nicht pauschal anwenden — jeder geförderte Layer verbraucht GPU-Speicher. Nur auf Elementen verwenden, die tatsächlich animiert werden, und nach Ende der Animation entfernen, wenn per JavaScript hinzugefügt.
Performance: blur-radius vs. spread-radius
blur-radius zu erhöhen ist teurer als spread-radius, weil Blur eine Gauß-Faltung erfordert, die mit der Pixelfläche skaliert. Ein Schatten mit spread: 10px, blur: 2px ist günstiger als spread: 0, blur: 12px bei gleichem visuellen Fußabdruck.
Interaktive Schatten-Generatoren auf PixCode.io
Alle drei Schattentechniken haben dedizierte interaktive Generatoren auf PixCode — Parameter mit Slidern anpassen, Ergebnis live sehen und produktionsbereites CSS mit einem Klick kopieren.