Maple
⌘K
DOCUMENTATIONv2.0.17

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)operatorvalue
  • prefix[Optional]: Use @ for viewport @media queries. Any query targeting the viewport should start with @. Default is no prefix, which enables @container queries targeting the nearest parent container. See container breakpoints and viewport breakpoints sections for more information.
  • modifier[Optional]: Use not- 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:

  • xs for min-width: 480px
  • sm for min-width: 640px
  • md for min-width: 768px
  • lg for min-width: 1024px
  • xl for min-width: 1280px
  • 2xl for min-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
Container queries require a defined containment context on a parent element. In Maple, you can create a container using the 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:

  • mnw for min-width
  • mxw for max-width
  • mnh for min-height
  • mxh for max-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
When using 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:

  1. System Preference: Targets @media (prefers-color-scheme: dark) with a guard :root:not(.light) to allow manual overriding.
  2. Manual Override: Targets the .dark class 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
You can disable this hybrid behavior by adding 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:

  • browser for display-mode: browser
  • standalone for display-mode: standalone
  • fullscreen for display-mode: fullscreen
  • pip for display-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.

  1. base (No query) - Lowest priority
  2. mnw / mxw (Width breakpoints)
  3. mnh / mxh (Height breakpoints)
  4. orientation
  5. style
  6. scroll
  7. light / dark
  8. prefers
  9. supports
  10. static (print, screen) - Highest priority

Viewport queries @ receive a slight priority boost over container queries of the same type.

ESC

Start typing to search across the documentation.