Media Queries
Maple is a container-first CSS engine. By default, all responsive modifiers target the nearest parent container. Viewport-based media queries can be activated using the @ prefix.
Media Query Format
The syntax for media and container queries follows a predictable structure that allows for modifiers, names, and operators:
prefixmodifierquery(container-name)operatorvalueprefix[Optional]: Use@for viewport@mediaqueries. Any query targeting the viewport should start with@. Default is no prefix, which enables@containerqueries targeting the nearest parent container. See container breakpoints and viewport breakpoints sections for more information.modifier[Optional]: Usenot-to negate the query. Default is no modf.query: The specific media query key (e.g.,md,dark,mnw,style).container-name[Optional]: For container queries, specify the name in parentheses before the colon, e.g.,md(sidebar).operator[Optional]:=for equality,!=for inequality.value[Optional]: The value for the query.
Container Breakpoints
Use predefined breakpoints to target container widths. These are the standard units for building responsive layouts:
xsformin-width: 480pxsmformin-width: 640pxmdformin-width: 768pxlgformin-width: 1024pxxlformin-width: 1280px2xlformin-width: 1536px
<div class="md:bgc-red">
Red background when in a container which width
is equal or greater than 768px
</div>
<div class="lg:bgc-blue">
Blue background when in a container which width
is equal or greater than 1024px
</div>
<div class="md(sidebar):bgc-green">
Green background when in a container which width
is equal or greater than 768px and it's name is sidebar
</div>Important: Containment Context
cnt utility. Do not add this to <body> or <html>; instead, wrap your application in an element having cnt class. You can define as many containers as you want, even with specific names. Children will resolve against the nearest matching ancestor.
<body>
<div class="cnt">
<div class="cnt=sidebar/inline-size">
<div class="md(sidebar):bgc-green">
Green background when sidebar's width
is equal or greater than 768px
</div>
</div>
</div>
</body> Viewport Breakpoints
The same predefined breakpoints used for container queries are also available for viewport media queries. To target the viewport you need to add @ prefix to the breakpoint.
<div class="@md:bgc-red">
Red background when the viewport width
is equal or greater than 768px
</div>
<div class="@lg:bgc-blue">
Blue background when the viewport width
is equal or greater than 1024px
</div> Breakpoint Configuration
Maple's runtime allows you to override or extend default breakpoints via the script's query string. See Configuration for more details.
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@f12io/maple/dist/maple.js?md=680px&xxl=1920px"></script>
</head>
<body>
<!-- md is overridden to 680px; xxl added at 1920px -->
<div class="@md:bgc-red">
Red background when the viewport width is equal or greater than 680px
</div>
<div class="@xxl:bgc-blue">
Blue background when the viewport width is equal or greater than 1920px
</div>
</body>
</html> Dimensions
Target specific constraints using dimension keys. These work for both container and viewport queries:
mnwformin-widthmxwformax-widthmnhformin-heightmxhformax-height
<div class="mnw=300px:bgc-red">
Red background when in a container which
width is equal or greater than 300px
</div>
<div class="@mxh=800px:bgc-red">
Red background when the viewport height is less than 800px
</div>
<div class="mnw!=500px:bgc-red">
Red background when in a container which width is less than 500px
</div>
<div class="not-mnw=500px:bgc-red">
Red background when in a container which width is less than 500px
</div>Pro Tip: Inverting Breakpoints
mxw or mxh with a predefined breakpoint like mxw-md, Maple generates a not (min-width: ...) query, effectively targeting the range below that breakpoint. Orientation
Query the orientation of a container or the viewport using the landscape and portrait keys.
<div class="landscape:bgc-red">
Red background when in a container which orientation is landscape
</div>
<div class="landscape(sidebar):bgc-red">
Red background when in a container called sidebar
which orientation is landscape
</div>
<div class="portrait:bgc-red">
Red background when in a container which orientation is portrait
</div>
<div class="portrait(sidebar):bgc-red">
Red background when in a container called sidebar
which orientation is portrait
</div>
<div class="@landscape:bgc-red">
Red background when the viewport orientation is landscape
</div>
<div class="@portrait:bgc-red">
Red background when the viewport orientation is portrait
</div> Color Scheme
Use @dark and @light keys to target the user's preferred color scheme. Maple employs a unique "Hybrid" Dark Mode Architecture that automatically supports both system preferences and manual toggles without writing extra CSS.
<div class="@dark:bgc-black @dark:c-white">
Black background and white text in dark mode
</div>
<div class="@light:bgc-white @light:c-black">
White background and black text in light mode
</div>
<div class="@not-dark:bgc-white">
White background when user does not prefer dark mode
</div>How It Works
When you use @dark, Maple generates dual CSS rules:
- System Preference: Targets
@media (prefers-color-scheme: dark)with a guard:root:not(.light)to allow manual overriding. - Manual Override: Targets the
.darkclass on the root element.
This means you can rely on the user's system preference by default. If you need to force a mode, simply add the dark or light class to the <html> element.
- System Mode (Default): No class on
<html>. Follows OS setting. - Force Dark:
<html class="dark">. Ignores system preference. - Force Light:
<html class="light">. Ignores system preference.
Pro Tip
nohybrid to the script query string. In that case, @dark will only generate @media (prefers-color-scheme: dark) rule. See Configuration for more details. Reduced Motion
Use motion-reduce and motion-safe keys to target the user's motion preferences. These are viewport-only queries.
<div class="@motion-reduce:tsdur-0">
Transition duration is 0 when user prefers reduced motion
</div>
<div class="@motion-safe:tsdur-300">
Transition duration is 300ms when user has no motion preference
</div> Display Modes
Target specific application display contexts, particularly useful for Progressive Web Apps (PWAs). These are viewport-only queries:
browserfordisplay-mode: browserstandalonefordisplay-mode: standalonefullscreenfordisplay-mode: fullscreenpipfordisplay-mode: picture-in-picture
<div class="@standalone:p-4">
Padding is 1rem when the app is in standalone mode (PWA)
</div>
<div class="@fullscreen:bgc-black">
Black background when the app is in fullscreen mode
</div>
<div class="@pip:o-80">
Opacity is 0.8 when the app is in picture-in-picture mode
</div>
<div class="@browser:none @standalone:block">
Hidden in browser but visible when installed as PWA
</div> You can also use the explicit display-mode=value syntax:
<div class="@display-mode=fullscreen:bgc-black">
Black background when the app is in fullscreen mode
</div>
@supports Queries
Detect CSS feature support using viewport-only queries. You can perform direct utility checks or custom feature queries:
1. Direct Utility Checks
The @supports key without a value checks if the browser supports the utility being applied.
<div class="@supports:bdblur-4">
<!-- Apply backdrop blur if browser supports it -->
</div>
<div class="@supports:rows=subgrid">
<!-- Use subgrid if browser supports it -->
</div>2. Custom Checks
Use @supports=[query] to check for any CSS feature support.
<div class="@supports=[backdrop-filter:blur(1px)]:bdblur-4">
<!-- Apply backdrop blur with fallback if browser supports it -->
</div>
<div class="@supports=[container-type:inline-size]:cnt">
<!-- Enable container queries if browser supports it -->
</div>
<div class="@supports=[selector(:has(*))]:^.card:has(.error):bgc-red">
<!-- Use :has() selector if browser supports it -->
</div> Style Queries
Use style= to query the computed style of a container. Style queries are exclusive to container context:
<div class="cnt --theme=dark">
<div class="style=[--theme:dark]:bgc-gray-900">
<!-- Dark theme styles applied when container has --theme:dark -->
</div>
</div>
<div class="cnt=card --variant=outlined">
<div
class="style(card)=[--variant:outlined]:br style(card)=[--variant:outlined]:brc-gray-300"
>
<!-- Outlined card variant with border styles -->
</div>
</div>
<div class="cnt --is-expanded=true">
<div
class="style=[--is-expanded:true]:h-auto not-style=[--is-expanded:true]:h-0"
>
<!-- Toggle height based on --is-expanded state -->
</div>
</div> Scroll-State Queries
You can query the scroll state of a container using stuck=, scrollable=, and snapped= keys. These only work with container queries:
1. Stuck
Query whether an element is stuck due to position: sticky.
<div class="stuck=top:bgc-red">
Red background when stuck to the top
</div>
<div class="stuck=bottom:bgc-blue">
Blue background when stuck to the bottom
</div>2. Scrollable
Query whether a container is scrollable in a given direction.
<div class="scrollable=top:bgc-red">
Red background when scrollable from the top
</div>
<div class="scrollable=bottom:bgc-blue">
Blue background when scrollable from the bottom
</div>3. Snapped
Query whether an element is snapped to a scroll snap position.
<div class="snapped=x:bgc-red">
Red background when snapped on the x-axis
</div>
<div class="snapped=y:bgc-blue">
Blue background when snapped on the y-axis
</div>
<div class="snapped(snap-container)=y:bgc-green">
Green background when snapped on the y-axis in the snap-container
</div> Custom Media Queries
Write any custom media query using the key=value format for both viewport and container contexts:
<div class="@prefers-contrast=more:c-black">
Black text when user prefers more contrast
</div>
<div class="@not-prefers-contrast=more:c-gray">
Gray text when user does NOT prefer more contrast
</div> Static Media Types
You can use standard CSS static media types directly in your queries, such as print or screen:
<div class="@print:none">Hidden when printing</div>
<div class="@not-print:block">Visible when NOT printing</div>
<div class="@screen:block">Visible on screen</div> Nested Queries
Combine multiple conditions by chaining them with colons. Maple automatically nests the rules based on their priority order:
<div class="@md:@dark:bgc-gray-900">
Background is gray-900 on medium screens in dark mode
</div>
<div class="@print:md:none">
Hidden when printing on containers wider than 768px
</div>
<div class="md:@xl:o-0">
Opacity is 0 when container is >= 768px AND viewport is >= 1280px
</div>
<div class="@supports=[opacity:0]:@dark:@md:o-0">
Complex nested query: supports opacity + dark mode + medium viewport
</div>Priority Order
When nesting queries, Maple automatically determines the order based on query type priority. The query with the highest priority becomes the outermost wrapper, and others are nested inside in their original order.
base(No query)- Lowest prioritymnw / mxw(Width breakpoints)mnh / mxh(Height breakpoints)orientationstylescrolllight / darkpreferssupportsstatic(print, screen)- Highest priority
Viewport queries @ receive a slight priority boost over container queries of the same type.