Mediaquery
Utility

MediaQuery

A reactive component that evaluates CSS media queries and provides the match state to its children.

Demo

Viewport is less than 800px
Viewport is less than 1024px (mobile/tablet)
Orientation: Portrait
Input device: No hover (touch)

Try resizing your browser window to see the values update in real-time.

Features

  • Reactive updates when viewport or media features change
  • Supports any valid CSS media query
  • SSR-friendly with configurable initial value
  • No wrapper element - renders child content directly
  • OnChange callback for side effects
  • Automatic cleanup of event listeners

Installation

bash
dotnet add package SummitUI

Anatomy

Import the component and provide a media query string:

razor
<MediaQuery Query="(min-width: 800px)" Context="IsLarge">
    @if (IsLarge)
    {
        <DesktopLayout />
    }
    else
    {
        <MobileLayout />
    }
</MediaQuery>

API Reference

MediaQuery

Property Type Default Description
Queryrequired string - CSS media query string to evaluate (e.g., "(min-width: 800px)")
ChildContent RenderFragment<bool>? - Child content receiving the match state as a boolean via Context
OnChange EventCallback<bool> - Callback invoked when the media query match state changes
InitialValue bool false Initial value before JavaScript evaluates (for SSR)

Examples

Responsive Layout

Show different content based on viewport width.

razor
<MediaQuery Query="(min-width: 800px)" Context="IsDesktop">
    @if (IsDesktop)
    {
        <div class="grid grid-cols-3 gap-4">
            <Sidebar />
            <MainContent class="col-span-2" />
        </div>
    }
    else
    {
        <div class="flex flex-col gap-4">
            <MobileNav />
            <MainContent />
        </div>
    }
</MediaQuery>

OS Dark Mode Detection

Detect the user's operating system color scheme preference. Note: This detects the OS setting, not website theme toggles.

razor
@* Detects OS color scheme, not website theme toggles *@
<MediaQuery Query="(prefers-color-scheme: dark)" Context="IsDarkMode">
    <div class="@(IsDarkMode ? "dark-theme" : "light-theme")">
        <p>OS prefers: @(IsDarkMode ? "Dark" : "Light")</p>
    </div>
</MediaQuery>

With OnChange Callback

Execute side effects when the media query match changes.

razor
<MediaQuery Query="(min-width: 1024px)" Context="IsLarge" OnChange="HandleBreakpointChange">
    <p>Large screen: @IsLarge</p>
</MediaQuery>

@code {
    private void HandleBreakpointChange(bool isLarge)
    {
        if (isLarge)
        {
            // Close mobile menu when switching to desktop
            isMobileMenuOpen = false;
        }

        Console.WriteLine($"Breakpoint changed: {(isLarge ? "large" : "small")}");
    }
}

Multiple Breakpoints

Combine multiple MediaQuery components for complex responsive layouts.

razor
<MediaQuery Query="(min-width: 1024px)" Context="IsLarge">
    <MediaQuery Query="(min-width: 768px)" Context="IsMedium">
        @if (IsLarge)
        {
            <p>Desktop layout (3 columns)</p>
        }
        else if (IsMedium)
        {
            <p>Tablet layout (2 columns)</p>
        }
        else
        {
            <p>Mobile layout (1 column)</p>
        }
    </MediaQuery>
</MediaQuery>

SSR Initial Value

Provide an initial value for server-side rendering before JavaScript evaluates.

razor
@* Set InitialValue to true if most users are on desktop *@
<MediaQuery Query="(min-width: 800px)" Context="IsDesktop" InitialValue="true">
    @if (IsDesktop)
    {
        <DesktopNav />
    }
    else
    {
        <MobileNav />
    }
</MediaQuery>

Other Media Features

Use any valid CSS media query, not just viewport width.

razor
@* Detect reduced motion preference *@
<MediaQuery Query="(prefers-reduced-motion: reduce)" Context="PrefersReducedMotion">
    <div class="@(PrefersReducedMotion ? "" : "animate-bounce")">
        Animated element
    </div>
</MediaQuery>

@* Detect touch device *@
<MediaQuery Query="(pointer: coarse)" Context="IsTouchDevice">
    @if (IsTouchDevice)
    {
        <p>Tap to interact</p>
    }
    else
    {
        <p>Click to interact</p>
    }
</MediaQuery>

@* Detect high contrast preference *@
<MediaQuery Query="(prefers-contrast: more)" Context="PrefersHighContrast">
    <div class="@(PrefersHighContrast ? "border-4 border-black" : "border")">
        High contrast aware element
    </div>
</MediaQuery>

Common Media Queries

Here are some commonly used media queries you can use with this component:

Query Description
(min-width: 640px) Small screens and up (sm breakpoint)
(min-width: 768px) Medium screens and up (md breakpoint)
(min-width: 1024px) Large screens and up (lg breakpoint)
(min-width: 1280px) Extra large screens and up (xl breakpoint)
(prefers-color-scheme: dark) User prefers dark color scheme
(prefers-color-scheme: light) User prefers light color scheme
(prefers-reduced-motion: reduce) User prefers reduced motion
(orientation: portrait) Device is in portrait orientation
(orientation: landscape) Device is in landscape orientation
(hover: hover) Primary input supports hover
(pointer: coarse) Primary input is touch/coarse pointer
(pointer: fine) Primary input is mouse/fine pointer

SSR Considerations

During server-side rendering, JavaScript is not available to evaluate media queries. The component will use the InitialValue parameter (default: false) until the page becomes interactive and JavaScript can evaluate the actual match state.

This means there may be a brief flash of content when the actual value differs from the initial value. Consider:

  • 1. Setting InitialValue to match your most common user scenario
  • 2. Using CSS media queries for critical layout styles
  • 3. Adding loading states or transitions to smooth the experience
An unhandled error has occurred. Reload X