# CSS box-shadow: weiche, geschichtete Schatten, die echt wirken

[Canonical HTML page](https://gradiently.design/de/guide/css-box-shadow)

Ein einzelner grauer box-shadow ist der schnellste Weg, ein Interface wie eine Vorlage aussehen zu lassen. Echte Schatten sind mehrere Schatten zugleich, getönt und leiser, als du denkst.

## The short version

- Die CSS-Eigenschaft box-shadow nimmt ein optionales Schlüsselwort inset, zwei Versätze, einen Unschärferadius, einen Ausbreitungsradius und eine Farbe.
- Ein einzelner box-shadow wirkt künstlich, weil echte Objekte zugleich einen scharfen Kontaktschatten und einen breiten weichen Schatten werfen.
- Drei bis fünf Schatten zu schichten, jeder mit etwa doppeltem Versatz und doppelter Unschärfe des vorherigen und geringer Deckkraft, ergibt einen weichen, glaubwürdigen Schatten.
- Einen Schatten zum Farbton des Hintergrunds hin zu tönen wirkt auf farbigen oder warmen Flächen natürlicher als reines Schwarz.
- Eine Animation von box-shadow zeichnet in jedem Frame neu, blende stattdessen die Deckkraft eines Pseudo-Elements mit dem größeren Schatten ein.

Ein **CSS box-shadow** wird als `box-shadow: 0 4px 12px rgb(0 0 0 / 0.15)` geschrieben: ein horizontaler Versatz, ein vertikaler Versatz, ein Unschärferadius, eine optionale Ausbreitung und eine Farbe. Dieser einzelne Schatten reicht für einen schnellen Prototyp, wirkt aber selten echt. Die Schatten, die das Auge überzeugen, sind geschichtet: mehrere Schatten an einem Element, jeder größer und blasser als der vorige, passend zur Fläche darunter getönt.

## Syntax von box-shadow

```css
/* inset? | offset-x | offset-y | blur | spread | color */
.card { box-shadow: 0 4px 12px 0 rgb(0 0 0 / 0.15); }

/* Negative spread tucks the shadow under the box */
.card { box-shadow: 0 12px 24px -8px rgb(0 0 0 / 0.25); }

/* Inset: a shadow inside the box, like a pressed well */
.well { box-shadow: inset 0 2px 4px rgb(0 0 0 / 0.12); }

/* Spread only: a hairline that follows border-radius */
.chip { box-shadow: 0 0 0 1px rgb(15 23 42 / 0.08); }

/* Several shadows, comma separated, first on top */
.card { box-shadow: 0 1px 2px rgb(0 0 0 / 0.1), 0 8px 16px rgb(0 0 0 / 0.08); }
```

Der Schatten folgt immer `border-radius`, deshalb ergibt ein Schatten nur mit Ausbreitung eine saubere abgerundete Haarlinie, ohne das Layout zu ändern.

| Wert | Standard | Wirkung |
| --- | --- | --- |
| `inset` | Aus | Zeichnet den Schatten innerhalb des Rahmens statt außerhalb |
| Versatz x und y | Pflicht | Verschiebt den Schatten. Licht von oben heißt ein positives y |
| Unschärfe | 0 | Macht die Kante weich. Größere Werte ziehen den Verlauf breiter |
| Ausbreitung | 0 | Vergrößert oder verkleinert den Schatten vor der Unschärfe. Negativ zieht ihn ein |
| Farbe | `currentcolor` | Nutze eine Farbe mit Alpha; deckende Schatten wirken wie Aufkleber |

Die Ausbreitung lassen die meisten weg, dabei behebt sie am meisten. Eine kleine negative Ausbreitung verhindert, dass eine große Unschärfe an den Seiten herausläuft.

## Warum ein einzelner Schatten künstlich wirkt

Leg ein Buch auf einen Tisch und sieh dir seinen Schatten an. Direkt an der Kante, wo es aufliegt, ist der Schatten dunkel und scharf. Weiter draußen wird er breit und blass, weil Licht das Objekt aus vielen Richtungen umfließt. Ein `box-shadow` kann immer nur eines davon sein: eng und hart oder breit und verschwommen. So oder so merkt das Auge, dass etwas fehlt.

### Einzelner Schatten

- Eine mittlere Unschärfe in 25 Prozent Schwarz
- Grauer Hof rund um die Karte
- Schwer zu sagen, wie hoch die Karte schwebt
- Wirkt auf farbigen Hintergründen schmutzig

### Geschichteter Schatten

- Vier Schatten, jeder blasser und breiter
- Dicht an der Kante, luftig weiter weg
- Die Höhe ist auf einen Blick lesbar
- Getönt, damit er natürlich auf seiner Fläche sitzt

## So schichtest du box-shadows

Die Methode ist einfach: Fang klein und scharf an und verdopple dann Versatz und Unschärfe für jede weitere Ebene, wobei jede Ebene blass bleibt. Wo sich die Ebenen überlagern, addieren sich die Deckkräfte, daher können einzelne Werte überraschend niedrig sein.

1. **Beginne mit einem Kontaktschatten** `0 1px 1px` mit etwa 8 Prozent Deckkraft. Das ist die dunkle Linie direkt unter der Kante.
2. **Verdopple für jede Ebene** Dann `0 2px 2px`, `0 4px 4px`, `0 8px 8px`. Versatz und Unschärfe wachsen gemeinsam, so scheint das Licht von oben zu kommen.
3. **Halte jede Ebene blass** Jeweils zwischen 5 und 10 Prozent. Wirkt das Ergebnis schwer, entferne die größte Ebene, bevor du irgendetwas dunkler machst.
4. **Töne die Farbe** Ersetze Schwarz durch eine tiefe Version des Hintergrundtons, etwa Marineblau auf blauen Seiten oder Braun auf Creme.

```css
:root {
  /* Shadow colour as channels, so opacity can vary per layer */
  --shadow-color: 222 47% 11%;

  --shadow-sm:
    0 1px 1px hsl(var(--shadow-color) / 0.08),
    0 2px 2px hsl(var(--shadow-color) / 0.06);

  --shadow-md:
    0 1px 1px hsl(var(--shadow-color) / 0.08),
    0 2px 2px hsl(var(--shadow-color) / 0.07),
    0 4px 4px hsl(var(--shadow-color) / 0.06),
    0 8px 8px hsl(var(--shadow-color) / 0.05);

  --shadow-lg:
    0 1px 1px hsl(var(--shadow-color) / 0.07),
    0 2px 2px hsl(var(--shadow-color) / 0.07),
    0 4px 4px hsl(var(--shadow-color) / 0.06),
    0 8px 8px hsl(var(--shadow-color) / 0.06),
    0 16px 16px hsl(var(--shadow-color) / 0.05),
    0 32px 32px hsl(var(--shadow-color) / 0.04);
}

.card { box-shadow: var(--shadow-md); }
.dialog { box-shadow: var(--shadow-lg); }
```

Eine dreistufige Höhenskala als Custom Properties. Ändere `--shadow-color` einmal, und jeder Schatten im System folgt.

Schatten als Variablen zu speichern macht sie zu Design Tokens, was jede Karte, jedes Menü und jeden Dialog konsistent hält. [CSS-Variablen fürs Theming](https://gradiently.design/de/guide/css-custom-properties-theming) und [Design Tokens](https://gradiently.design/de/guide/design-tokens) zeigen, wie du sie in ein ganzes Theme einbindest.

## Eine Höhenskala für ein Interface

Schatten signalisiert Höhe, also sollte er überall dasselbe bedeuten. Wähle drei oder vier Stufen und weise sie Aufgaben zu. Alles, was höher schwebt, bekommt einen größeren, weicheren Schatten, niemals nur einen dunkleren.

| Stufe | Token | Nutze sie für |
| --- | --- | --- |
| 0 | keiner oder eine 1px-Haarlinie per Ausbreitung | Eingabefelder, Tabellenzeilen, flache Karten auf getönter Seite |
| 1 | `--shadow-sm` | Ruhende Karten, Buttons, die klickbar wirken sollen |
| 2 | `--shadow-md` | Karten im Hover, Dropdown-Menüs, Popover |
| 3 | `--shadow-lg` | Dialoge, Sheets, alles über einer abgedunkelten Seite |

Vier Stufen decken fast jedes Interface ab. Mehr, und niemand kann sie noch auseinanderhalten.

## Schatten auf farbigen und dunklen Hintergründen

Reinschwarze Schatten werden auf einer farbigen Fläche grau und trüb, so wie Schwarz in Farbe gemischt sie stumpf macht. Nimm die Schattenfarbe stattdessen aus dem Hintergrund: ein tiefer Petrolschatten auf einer Mintseite, ein dunkles Pflaume auf einer fliederfarbenen. Auf Verlaufshintergründen nimm den dunkelsten Farbstopp des Verlaufs und nutze ihn mit geringer Deckkraft.

- Mintseite: #f0fdfa
- Petrolschatten: #134e4a
- Fliederseite: #faf5ff
- Pflaumenschatten: #3b0764
- Cremeseite: #fdf6ec
- Umbraschatten: #451a03

Drei Seitenfarben, jede mit der passenden Schattenfarbe. Nutze die Schattentöne mit 5 bis 10 Prozent pro Ebene.

Im Dark Mode verschwinden Schatten fast, weil kaum Licht da ist, das sie blockieren könnten. Zeig Höhe stattdessen, indem du erhöhte Flächen etwas heller machst, und behalte eine feine Haarlinie an der Kante. [Dark-Mode-Design](https://gradiently.design/de/guide/dark-mode-design) geht die Flächenfarben durch. Für Panels über Bildern trennt ein [backdrop-filter](https://gradiently.design/de/guide/css-blur-background) Ebenen oft besser als ein schwererer Schatten.

## box-shadow ruckelfrei animieren

Ändert sich `box-shadow` beim Hover, muss der Browser den Schatten in jedem Frame des Übergangs neu zeichnen. Bei einem Button ist das kein Problem. Bei einem Raster aus fünfzig Karten ruckelt es. Die übliche Lösung: Leg den größeren Schatten auf ein Pseudo-Element und blende seine Deckkraft ein, was der Browser günstig compositen kann.

```css
.card {
  position: relative;
  box-shadow: var(--shadow-sm);
}

.card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transition: opacity 200ms ease-out;
  pointer-events: none;
}

.card:hover::after { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .card::after { transition: none; }
}
```

Beide Schatten werden einmal gezeichnet. Der Hover ändert nur die Deckkraft, daher wird während des Übergangs nichts neu gezeichnet.

Mehr dazu, was Zeichenzeit kostet, steht in [Performance von CSS-Verläufen](https://gradiently.design/de/guide/css-gradient-performance), und derselbe Schichtansatz passt zu Buttons in [Verlaufsbuttons in CSS](https://gradiently.design/de/guide/css-gradient-button).

## Wann du den Schatten weglässt

Schatten trennen eine Fläche von dem, was dahinter liegt. Ist der Hintergrund ein satter Verlauf oder ein Foto, kämpft ein starker Schatten gegen ihn. Oft tut ein ruhigerer Hintergrund mehr für die Karte als jeder Schatten. Gradiently Marks sind dafür gebaut: Jeder ist ein lebendiger Hintergrund mit eigenen Farben, eigenem Licht und eigener Körnung, und die Worte darauf bleiben lesbar, weil der Mark sich hinter ihnen beruhigt, ohne dass Kästen oder Schatten die Arbeit machen.

## FAQ

### Welche Werte hat CSS box-shadow?

Ein optionales `inset`, einen horizontalen Versatz, einen vertikalen Versatz, einen Unschärferadius, einen Ausbreitungsradius und eine Farbe, zum Beispiel `0 4px 12px 0 rgb(0 0 0 / 0.15)`.

### Wie mache ich in CSS einen weichen box-shadow?

Schichte drei bis fünf Schatten, verdopple jedes Mal Versatz und Unschärfe, mit jeweils 5 bis 10 Prozent Deckkraft. Töne sie zur Hintergrundfarbe hin.

### Wie füge ich mehr als einen box-shadow hinzu?

Trenne sie in einer `box-shadow`-Deklaration mit Kommas. Der zuerst genannte Schatten wird oben gezeichnet.

### Was bewirkt spread bei box-shadow?

Es vergrößert oder verkleinert den Schatten, bevor er unscharf wird. Ein negativer Wert verhindert, dass eine große Unschärfe an den Seiten der Box sichtbar wird.

### Ist das Animieren von box-shadow schlecht für die Performance?

Es zeichnet in jedem Frame neu. Leg den Hover-Schatten auf ein Pseudo-Element und animiere stattdessen dessen Deckkraft.
