MediaQuery
A reactive component that evaluates CSS media queries and provides the match state to its children.
Demo
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
dotnet add package SummitUIAnatomy
Import the component and provide a media query string:
<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.
<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.
@* 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.
<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.
<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.
@* 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.
@* 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
InitialValueto 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