Maple
⌘K
DOCUMENTATIONv2.0.17

Configuration

Maple does not use configuration files. Runtime options are passed through the script URL, so the same engine can be tuned for custom breakpoints, reference caching, class merging, and dark mode behavior without adding a build step.

Script Query String

Add configuration parameters to the Maple script src as a standard query string. Boolean options only need the parameter name, while breakpoint options use name=value.


<script src="maple.js?refs&nomerge&md=680px&4xl=1920px"></script>
  
Parameter
Effect
Use When
refs

Enables global reference variables for generated values.

Large pages or applications reuse many of the same utilities.

nomerge

Disables runtime utility conflict cleanup.

Your class strings are already clean and you want less runtime work.

nohybrid

Disables hybrid dark mode rule generation.

You want @dark: to generate media-query rules only.

{breakpoint}={value}

Overrides or adds a named breakpoint.

Your design system needs different responsive thresholds.

Load Order Still Matters
Keep Maple as a blocking script in the document <head>. Do not add async, defer, or type="module", because the browser may render elements before Maple has generated their styles.

Custom Breakpoints

Breakpoint parameters let you override Maple's defaults or introduce new names. The configured name becomes available anywhere a Maple breakpoint can be used, including container queries and viewport queries.


<!-- Override defaults and add a custom 4xl breakpoint -->
<script src="maple.js?sm=480px&md=680px&lg=960px&4xl=1920px"></script>

<!-- Use the configured breakpoint -->
<div class="@4xl:cols-4">
  4 columns at 1920px and above
</div>
  

After configuration, the breakpoint name is used exactly like any other media prefix. For example, @4xl:cols-4 targets a viewport at 1920px and above, while 4xl:cols-4 targets the nearest container at that same threshold.

Container First
Maple breakpoints are container queries by default. Add the @ prefix when you want a viewport media query instead of a container query.

Nomerge Mode

Utility classes often have the same specificity. When two classes target the same CSS property, the browser does not use the order of the classes in the class attribute to decide the winner. It uses the order of the generated CSS rules. Maple's merger keeps the class string as the source of truth by resolving conflicts in class order before those equal-specificity rules can become ambiguous.

For example, p-4 p-8 expresses a clear intent: p-8 should win because it comes later. By default, Maple applies that last-one-wins behavior and removes the overridden utility from the DOM.


<!-- Disable conflict cleanup -->
<script src="maple.js?nomerge"></script>

<!-- With default merging, p-4 is removed and p-8 wins always. -->
<div class="p-4 p-8">
  With nomerge, both classes stay in the DOM.
  The browser uses CSS rule order, not this class order.
  For example, if .p-8 is generated previously by another element, .p-4 wins.
</div>
  
Mode
Behavior
Consequence
Default

Maple calculates utility conflicts, applies last-one-wins behavior, and cleans overridden classes from the element.

Specificity stays predictable because the class string order decides conflicts between equivalent utilities.

nomerge

Maple leaves class attributes untouched and skips the conflict cleanup pass.

Conflicting utilities remain in place, so the browser cascade may choose based on CSS generation order instead of class string order.

Use nomerge when your class strings are generated in a controlled way and you are confident they do not contain conflicting utilities. It can reduce initial runtime work, but the cost is that Maple no longer protects you from equal-specificity conflicts, duplicated utilities, or class lists whose visible order does not match the final style.

Reference Mode

By default, Maple prepares the full fallback chain for each generated utility rule. This keeps every utility locally scoped, but complex values such as colors require Maple to assemble the same OKLCH fallback logic again whenever an equivalent utility is generated.


/* Without refs: the full fallback chain lives in each rule */
.c-red {
  color: oklch(
    from var(--c-red, var(--color-red, var(--red, red)))
      calc(l * var(--c-red-l-scale, var(--red-l-scale, var(--c-l-scale, var(--l-scale, 1)))))
      calc(c * var(--c-red-c-scale, var(--red-c-scale, var(--c-c-scale, var(--c-scale, 1)))))
      calc(h + var(--c-red-h-rotate, var(--red-h-rotate, var(--c-h-rotate, var(--h-rotate, 0))))) /
      alpha
  );
}
  

With refs enabled, Maple generates that fallback chain once as a global reference variable. Later utilities can point to the reference instead of rebuilding the same chain. The purpose is runtime efficiency: less repeated generation work in Maple, and in some cases less repeated variable math for the browser when referenced values are recalculated.


/* With refs: the calculation is cached once and reused */
:root {
  --ref-c-red: oklch(from var(--c-red, var(--color-red, var(--red, red))) calc(...) calc(...) calc(...) / alpha);
}

.c-red {
  color: var(--ref-c-red);
}

.bgc-red {
  background-color: var(--ref-bgc-red);
}
  

Trade-offs

Reference mode is a runtime caching strategy, not a CSS file size optimization. It can make large pages cheaper to generate, but it introduces specific trade-offs to consider:

  • Referenced utilities read from global :root variables, so local overrides no longer affect those utilities by default. See the local override section below if you need to override a specific utility when refs mode is enabled.

  • Browser DevTools may also become harder to navigate in large applications with many ref definitions, as every selected element lists the generated :root reference variables.

Local Overrides with Refs

Prefix a utility with $ when refs is enabled and that one utility should keep its full fallback chain. This lets the class respond to local CSS variables while the rest of the page still benefits from reference caching.


<script src="maple.js?refs"></script>

<!-- Uses the global reference cache -->
<div class="p-4">
  Cached spacing
</div>

<!-- Skips the cache for this utility, so the local variable can win -->
<div class="$p-4 --p-4=2rem">
  Locally overridden spacing
</div>
  
Choosing Reference Mode
Enable refs for large applications with stable global tokens. Leave it off for component libraries or heavily scoped themes where local variable overrides are part of the public API.

Disabling Hybrid Dark Mode

Maple's dark mode prefixes normally generate rules for both system preferences and manual dark or light classes on the <html> element. Add nohybrid when you only want the system preference media query.


<!-- Disable hybrid dark mode generation -->
<script src="maple.js?nohybrid"></script>

<div class="@dark:bgc-gray-950 @dark:c-white">
  System dark mode only
</div>
  

With nohybrid, @dark: generates @media (prefers-color-scheme: dark) only. Manual root classes are no longer included in the generated selector behavior.

ESC

Start typing to search across the documentation.