Zum Inhalt springen

Responsiveness & Dark Mode

Mit @media könnt ihr CSS-Regeln nur unter bestimmten Bedingungen gelten lassen. Am häufigsten: ab einer bestimmten Fensterbreite.

.sidebar {
display: none; /* auf kleinen Bildschirmen erstmal ausblenden */
}
@media (min-width: 768px) {
.sidebar {
display: block; /* ab 768px wieder einblenden */
}
}
  • min-width - Regel gilt ab dieser Breite (mobile-first: erst für schmal stylen, dann für breiter ergänzen)
  • max-width - Regel gilt bis zu dieser Breite
  • Typische Breakpoints: 480px (Handy), 768px (Tablet), 1024px+ (Desktop) - aber richtet euch nach eurem Inhalt, nicht nach starren Geräte-Größen!

@media kann auch auf andere Eigenschaften reagieren, nicht nur auf die Fensterbreite:

/* Extra-Styles nur für den Ausdruck */
@media print {
nav, .btn { display: none; } /* Navigation/Buttons braucht niemand auf Papier */
body { color: black; }
}
/* Nutzer*in hat "reduzierte Bewegung" aktiviert */
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; }
}

Das Problem mit Media Queries: sie kennen nur den Viewport

Abschnitt betitelt „Das Problem mit Media Queries: sie kennen nur den Viewport“
@media (min-width: 600px) {
.card { display: flex; }
}

Diese Regel greift, wenn das Browserfenster mindestens 600px breit ist. Aber was, wenn dieselbe .card mal in einer breiten Hauptspalte und mal in einer schmalen Sidebar liegt?

<div class="sidebar"> <!-- 250px breit -->
<article class="card">…</article> <!-- soll SCHMAL aussehen -->
</div>
<div class="main"> <!-- 900px breit -->
<article class="card">…</article> <!-- soll BREIT aussehen -->
</div>

→ Media Queries können das nicht unterscheiden - beide .card-Elemente bekommen dieselbe Regel, obwohl sie in völlig unterschiedlich breiten Containern stecken.

Container Queries reagieren nicht auf den Viewport, sondern auf die Breite des Eltern-Containers. Zwei Schritte sind nötig:

/* 1. Ein Element zum "Container" erklären */
.sidebar, .main {
container-type: inline-size;
container-name: layout;
}
/* 2. Die Regel gilt jetzt relativ zu DIESEM Container */
@container layout (min-width: 600px) {
.card {
display: flex;
}
}
  • container-type: inline-size - der Container „meldet” jetzt seine Breite nach unten weiter
  • container-name ist optional, aber hilfreich, wenn mehrere verschachtelte Container existieren
  • @container verhält sich sonst genau wie @media - gleiche Syntax für min-width/max-width

Praxisbeispiel: eine Card, die sich selbst anpasst

Abschnitt betitelt „Praxisbeispiel: eine Card, die sich selbst anpasst“
.card-container {
container-type: inline-size;
}
.card {
display: grid;
gap: 0.5rem;
}
/* Ab 400px Container-Breite: Bild und Text nebeneinander */
@container (min-width: 400px) {
.card {
grid-template-columns: 120px 1fr;
}
}

→ Dieselbe .card-Komponente ordnet sich automatisch neu, egal ob sie in einer breiten Hauptspalte oder einer schmalen Sidebar landet - ganz ohne zu wissen, wie breit der Bildschirm insgesamt ist.

Noch kompakter: eine CSS-Funktion, die automatisch den passenden Wert wählt.

:root {
color-scheme: light dark; /* sagt dem Browser: "wir unterstützen beides" */
--color-bg: light-dark(white, #111827);
--color-text: light-dark(#1f2937, #f3f4f6);
}
body {
background-color: var(--color-bg);
color: var(--color-text);
}
  • light-dark(wert-hell, wert-dunkel) - der Browser entscheidet automatisch anhand der Systemeinstellung
  • color-scheme: light dark im :root ist notwendig, damit light-dark() funktioniert
  • Neuere CSS-Funktion (Baseline seit 2024) - in modernen Browsern gut unterstützt

Früher/veraltete Schreibweise: prefers-color-scheme

Abschnitt betitelt „Früher/veraltete Schreibweise: prefers-color-scheme“

Nutzer*innen stellen an ihrem Gerät “Dark Mode” oder “Light Mode” ein. CSS kann das erkennen:

/* Standard = Light Mode */
:root {
--color-bg: white;
--color-text: #1f2937;
}
/* Wenn das System Dark Mode eingestellt hat */
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #111827;
--color-text: #f3f4f6;
}
}
body {
background-color: var(--color-bg);
color: var(--color-text);
}

→ Kein JavaScript nötig! Rein mit CSS + Variablen umsetzbar.

:root {
color-scheme: light dark;
--color-bg: light-dark(#ffffff, #1f2937);
--color-surface: light-dark(#f9fafb, #111827);
--color-text: light-dark(#1f2937, #f3f4f6);
--color-border: light-dark(#e5e7eb, #374151);
}
body {
background-color: var(--color-bg);
color: var(--color-text);
}
.card {
background-color: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 16px;
}