← Back to all hooks

useMediaQuery

Track CSS media query matches in real-time. Perfect for responsive design, dark mode detection, and device-specific features.

Live Demo

Resize your browser, change system theme, or rotate your device to see real-time updates.

🖥️

Unknown

Resize your browser window to see it change

🎨 Theme Preference

☀️Light Mode

Based on your system preference

📐 Orientation

📱
Portrait
📱
Landscape

⚙️ Other Preferences

Reduced Motion:❌ Disabled
High Resolution:❌ Standard

💡 Try This:

  • Resize your browser window to see device type change
  • Change your system theme (dark/light) to see preference update
  • Rotate your device to see orientation change

Code Examples

Dark Mode Detection

import { useMediaQuery } from "@uiblock/hooks";

export default function ThemeAware() {
  const isDark = useMediaQuery('(prefers-color-scheme: dark)');

  return (
    <div style={{ 
      background: isDark ? '#1a1a1a' : '#ffffff',
      color: isDark ? '#ffffff' : '#000000'
    }}>
      <h1>Current theme: {isDark ? 'Dark' : 'Light'}</h1>
    </div>
  );
}

Responsive Design

import { useMediaQuery } from "@uiblock/hooks";

export default function ResponsiveLayout() {
  const isMobile = useMediaQuery('(max-width: 768px)');
  const isTablet = useMediaQuery('(min-width: 769px) and (max-width: 1024px)');
  const isDesktop = useMediaQuery('(min-width: 1025px)');

  return (
    <div>
      {isMobile && <MobileNav />}
      {isTablet && <TabletNav />}
      {isDesktop && <DesktopNav />}
    </div>
  );
}

Orientation Detection

import { useMediaQuery } from "@uiblock/hooks";

export default function OrientationAware() {
  const isPortrait = useMediaQuery('(orientation: portrait)');

  return (
    <div>
      {isPortrait ? (
        <p>Please rotate your device to landscape</p>
      ) : (
        <VideoPlayer />
      )}
    </div>
  );
}

Accessibility - Reduced Motion

import { useMediaQuery } from "@uiblock/hooks";

export default function AnimatedComponent() {
  const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');

  return (
    <div 
      className={prefersReducedMotion ? 'no-animation' : 'with-animation'}
    >
      Content
    </div>
  );
}

How It Works

Here's the implementation:

import { useState, useEffect } from 'react'

export function useMediaQuery(query: string): boolean {
  const [matches, setMatches] = useState(false)

  useEffect(() => {
    if (typeof window === 'undefined') return

    const media = window.matchMedia(query)
    
    // Set initial value
    setMatches(media.matches)

    // Create event listener
    const listener = (e) => setMatches(e.matches)
    
    // Add listener
    media.addEventListener('change', listener)

    // Cleanup
    return () => {
      media.removeEventListener('change', listener)
    }
  }, [query])

  return matches
}

Common Media Queries

Device Sizes

  • (max-width: 768px) - Mobile devices
  • (min-width: 769px) and (max-width: 1024px) - Tablets
  • (min-width: 1025px) - Desktop

Theme

  • (prefers-color-scheme: dark) - Dark mode
  • (prefers-color-scheme: light) - Light mode

Orientation

  • (orientation: portrait) - Portrait mode
  • (orientation: landscape) - Landscape mode

Accessibility

  • (prefers-reduced-motion: reduce) - Reduced motion
  • (prefers-contrast: high) - High contrast

Display

  • (min-resolution: 2dppx) - Retina/High DPI
  • (display-mode: standalone) - PWA installed

API Reference

Parameters

query: string

CSS media query string (e.g., "(max-width: 768px)")

Returns

boolean - true if the media query matches, false otherwise

💡 Use Cases

  • Responsive navigation (mobile menu vs desktop menu)
  • Dark mode / light mode theming
  • Device-specific features (touch vs mouse)
  • Orientation-based layouts (video players, games)
  • Accessibility preferences (reduced motion, high contrast)
  • Print styles detection
  • PWA detection (standalone mode)
  • Retina display optimization