Start · Sprachen · JavaScript · Referenz · Window.matchMedia()

Window.matchMedia()

Methode

Wertet eine Media-Query-Zeichenfolge aus und gibt ein <code>MediaQueryList</code>-Objekt zurück, das angibt, ob das Dokument aktuell darauf passt, und Änderungen melden kann.

seit JavaScript Baseline: alle Browser (seit 2012) Kategorie: webapi

Signatur

Window.prototype.matchMedia(mediaQueryString)

Beschreibung

window.matchMedia() ist das JavaScript-Gegenstück zu CSS-@media-Regeln. Die Methode nimmt eine Media Query wie "(max-width: 600px)" oder "(prefers-color-scheme: dark)" entgegen und gibt ein MediaQueryList-Objekt zurück. Dessen Eigenschaft matches sagt, ob die Bedingung jetzt gerade erfüllt ist.

Richtig nützlich wird das durch das change-Event der MediaQueryList: Es feuert nur dann, wenn sich das Ergebnis der Abfrage ändert, also zum Beispiel beim Überschreiten eines Breakpoints oder wenn der Nutzer das Farbschema des Systems umstellt. Das ist deutlich sparsamer als ein resize-Listener, der bei jedem Pixel feuert und in dem man selbst innerWidth vergleichen muss.

Typische Einsatzfälle:

  • Responsives Verhalten in JavaScript, etwa ein mobiles Menü oder unterschiedliche Komponenten je nach Breakpoint
  • Benutzereinstellungen abfragen: prefers-color-scheme, prefers-reduced-motion, prefers-contrast
  • Geräteeigenschaften erkennen: (pointer: coarse), (hover: hover), (orientation: portrait), print

Breakpoints sollten in CSS und JavaScript identisch sein, sonst weichen Layout und Skriptlogik voneinander ab. Wenn es rein um Styling geht, ist CSS mit @media fast immer die bessere Wahl. matchMedia() braucht man nur, wenn Logik davon abhängt.

Parameter

Name Typ Default Beschreibung
$mediaQueryString Pflicht string Eine Media Query in CSS-Syntax, z. B. "(min-width: 768px)", "screen and (orientation: landscape)" oder "(prefers-reduced-motion: reduce)". Mehrere Abfragen lassen sich mit Komma trennen (logisches ODER).

Rückgabewert

Typ
MediaQueryList
Beschreibung
Ein neues MediaQueryList-Objekt mit den Eigenschaften matches (boolean) und media (normalisierte Abfrage als string) sowie dem Event change. Bei einer ungültigen Abfrage wird kein Fehler geworfen: media ist dann "not all" und matches ist false.

Beispiele

Einmalig prüfen, ob ein mobiler Viewport vorliegt

const mobileQuery = window.matchMedia('(max-width: 600px)');

if (mobileQuery.matches) {
  console.log('Mobile Ansicht aktiv');
} else {
  console.log('Desktop-Ansicht aktiv');
}

console.log(mobileQuery.media);
Desktop-Ansicht aktiv (max-width: 600px)

Auf Breakpoint-Wechsel reagieren (change-Event)

const desktopQuery = window.matchMedia('(min-width: 1024px)');

const handleLayout = (event) => {
  document.body.classList.toggle('layout-desktop', event.matches);
  console.log(event.matches ? 'Desktop-Layout' : 'Kompaktes Layout');
};

// Initialzustand setzen – change feuert nicht beim Registrieren
handleLayout(desktopQuery);

desktopQuery.addEventListener('change', handleLayout);

// Später, z. B. beim Entfernen einer Komponente:
// desktopQuery.removeEventListener('change', handleLayout);
Desktop-Layout

Dark Mode des Systems übernehmen und live verfolgen

const darkQuery = window.matchMedia('(prefers-color-scheme: dark)');

const applyTheme = (isDark) => {
  document.documentElement.dataset.theme = isDark ? 'dark' : 'light';
  console.log(`Theme: ${document.documentElement.dataset.theme}`);
};

applyTheme(darkQuery.matches);
darkQuery.addEventListener('change', (e) => applyTheme(e.matches));
Theme: dark

Animationen bei reduzierter Bewegung abschalten (mit AbortController)

const controller = new AbortController();
const motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');

const scrollToTop = () => {
  window.scrollTo({
    top: 0,
    behavior: motionQuery.matches ? 'auto' : 'smooth'
  });
};

motionQuery.addEventListener(
  'change',
  (e) => console.log('Reduzierte Bewegung:', e.matches),
  { signal: controller.signal }
);

scrollToTop();
// Alle Listener auf einmal entfernen:
// controller.abort();

// Wichtig · Fallstricke

  • Kein Initial-Event: change feuert nur bei einer Änderung. Den Anfangszustand muss man selbst über matches auswerten.
  • Veraltete API: MediaQueryList.addListener() und removeListener() gelten als veraltet. Verwende addEventListener('change', …). Das ältere Safari vor Version 14 kennt nur addListener(). Wer das noch unterstützen muss, prüft vorher typeof mql.addEventListener === 'function'.
  • Ungültige Abfragen scheitern stumm: Ein Tippfehler wie "max-width: 600px" ohne Klammern wirft keinen Fehler, sondern liefert media === "not all" und matches === false. Zum Debuggen mql.media prüfen.
  • Einheiten: px in Media Queries bezieht sich auf CSS-Pixel, nicht auf Gerätepixel. em richtet sich nach der Standard-Schriftgröße des Browsers, nicht nach dem Root-Element.
  • Speicherlecks vermeiden: In Single-Page-Apps und Frameworks Listener beim Unmount entfernen, zum Beispiel über removeEventListener oder ein AbortSignal. Das MediaQueryList-Objekt am besten einmal erzeugen und wiederverwenden.
  • Server-Side Rendering: In Node.js und beim SSR gibt es kein window. Den Zugriff deshalb absichern: typeof window !== 'undefined'.
  • Datenschutz: Einige Browser verallgemeinern bestimmte Media Features (z. B. resolution) gegen Fingerprinting. Die Ergebnisse können daher ungenauer sein.