Maple
⌘K
DOCUMENTATIONv2.0.17

Grid Layout

Maple's grid system provides high-level abstraction over CSS Grid via shorthand syntax for columns, rows, spanning, and named areas.

Columns

The cols-* utility defines the column structure of a grid container. It supports everything from simple equal-width distributions to complex, mixed-unit layouts using a smart slash syntax.

Equal Columns

To create equal-width columns, provide the number of columns to the cols-* utility. This number automatically resolves to equal fractional units (fr), ensuring the columns distribute available space perfectly.

1fr
1fr
1fr

<!-- Equal Columns -->
<div class="gr cols-3 g-6">
  <div>1fr</div>
  <div>1fr</div>
  <div>1fr</div>
</div>
  

Fractional Columns

Use the slash syntax to create columns with different fractional ratios. For example, cols-1/2/1 creates a three-column grid where the middle column is twice as wide as the outer ones.

1fr
2fr
1fr

<!-- Fractional Columns -->
<div class="gr cols-1/2/1 g-6">
  <div>1fr</div>
  <div>2fr</div>
  <div>1fr</div>
</div>
  

Mixed Units

You can mix percentages, fractional units, and pixel-based rems in a single shorthand. For example, cols-1/4_fr_20 resolves to 25%, 1fr, and 5rem simultaneously.

25%
1fr
5rem

<!-- Mixed Units -->
<div class="gr cols-1/4_fr_20 g-6">
  <div>25%</div>
  <div>1fr</div>
  <div>5rem</div>
</div>
  
Understanding the Slash
When combining units with an underscore _, Maple treats slashes as mathematical ratios (so 1/4 becomes 25%). However, when used on their own without underscores, slashes act as structural dividers between fractional columns (so cols-1/2/1 becomes 1fr 2fr 1fr).

Column Spanning

Use the col-* utility to make an element span multiple columns. You can also use the equal sign syntax col=1/-1 for explicit start and end lines.

col-2
1
1
col-2
col=1/-1

<!-- Column Spanning -->
<div class="gr cols-3 g-6">
  <div class="col-2">Spans 2 columns</div>
  <div>1</div>
  <div>1</div>
  <div class="col-2">Spans 2 columns</div>
  <div class="col=1/-1">Spans 3 columns</div>
</div>

Rows

The rows-* utility defines the row structure of a grid container. It supports everything from simple equal-height distributions to complex, mixed-unit layouts using a smart slash syntax.

Equal Rows

To create equal-height rows, provide the number of rows to the rows-* utility. This number automatically resolves to equal fractional units (fr), ensuring the rows distribute available space perfectly.

1fr
1fr
1fr

<!-- Equal Rows -->
<div class="gr rows-3 g-6 h-80">
  <div>1fr</div>
  <div>1fr</div>
  <div>1fr</div>
</div>

Fractional Rows

Use the slash syntax to create rows with different fractional ratios. For example, rows-1/2/1 creates a three-row grid where the middle row is twice as tall as the outer ones.

1fr
2fr
1fr

<!-- Fractional Rows -->
<div class="gr rows-1/2/1 g-6">
  <div>1fr</div>
  <div>2fr</div>
  <div>1fr</div>
</div>
  

Mixed Units

You can mix percentages, fractional units, and pixel-based rems in a single shorthand. For example, rows-1/4_fr_20 resolves to 25%, 1fr, and 5rem simultaneously. (Note: The same slash and underscore rules apply here as they do in columns).

25%
1fr
5rem

<!-- Mixed Units (Rows) -->
<div class="gr rows-1/4_fr_20 g-6 h-100">
  <div>25%</div>
  <div>1fr</div>
  <div>5rem</div>
</div>

Row Spanning

Use the row-* utility to make an element span multiple rows. You can also use the equal sign syntax row=1/-1 for explicit start and end lines. This is particularly useful for creating complex dashboard layouts where some widgets need more vertical space.

row=1/-1
row-2
1
1
1
1

<!-- Row Spanning -->
<div class="gr cols-3 rows-3 g-6 h-50">
  <div class="row=1/-1">Spans 3 rows</div>
  <div class="row-2">Spans 2 rows</div>
  <div>1</div>
  <div>1</div>
  <div>1</div>
  <div>1</div>
</div>

Areas

The areas-* utility defines named grid areas, providing a declarative way to describe the layout structure. Each string represents a row, with area names separated by underscores.

Named Areas

Assign names to grid cells and then use the area=* utility on child elements to place them. This makes layouts much easier to read and maintain than numerical spanning.

A
B
C
D

<!-- Named Areas -->
<div class="gr areas='a_b'_'c_d' g-6">
  <div class="area=a">A</div>
  <div class="area=b">B</div>
  <div class="area=c">C</div>
  <div class="area=d">D</div>
</div>

Area Spanning

To make an area span multiple columns or rows, simply repeat the area name in adjacent cells.

Header
Sidebar
Main

<!-- Area Spanning -->
<div class="gr areas='h_h'_'s_m' cols-1/4_fr g-6">
  <div class="area=h">Header</div>
  <div class="area=s">Sidebar</div>
  <div class="area=m">Main</div>
</div>

Subgrid

You can use the cols-subgrid (or cols=subgrid) and rows-subgrid (or rows=subgrid) utilities to allow nested grids to participate in the sizing of their parent grids.

1fr
Subgrid 1
Subgrid 2

<!-- Subgrid -->
<div class="gr cols-3 g-6">
  <div>1fr</div>
  <div class="gr cols-subgrid col-2">
    <div>Subgrid 1</div>
    <div>Subgrid 2</div>
  </div>
</div>

Practical Examples

The true power of Maple's grid engine lies in combining these utilities to build complex, responsive layouts with minimal markup. Here are three common UI patterns built entirely with utility classes.

Feature Cards

A standard grid of equal-width cards that responds to its container. This layout stacks cards in narrow containers and spreads them out into three columns when the container has enough room.

A

Feature A

Lorem ipsum dolor sit amet, consectetur elit.

B

Feature B

Sed do eiusmod tempor incididunt magna aliqua.

C

Feature C

Ut enim ad minim veniam, quis nostrud ullamco.

<div class="cnt">
  <div class="gr cols-1 sm:cols-3 g-6 --body=oklch(0.56_0.05_260)">
    <div class=" bgc-body-100/50 p-6 rad-5 fxcol-cs g-4">
      <div class="bgc-coral-150 c-coral-500 fxrow-cc square-12 rad-4 fs-6">A</div>
      <div>
        <h4 class="fs-4 fw-600 c-body-900 mb-0">Feature A</h4>
        <p class="fs-3 c-body-600 lh-5">
          Lorem ipsum dolor sit amet, consectetur elit.
        </p>
      </div>
    </div>

    <div class=" bgc-body-100/50 p-6 rad-5 fxcol-cs g-4">
      <div class="bgc-limegreen-150 c-limegreen-500 fxrow-cc square-12 rad-4 fs-6">B</div>
      <div>
        <h4 class="fs-4 fw-600 c-body-900 mb-0">Feature B</h4>
        <p class="fs-3 c-body-600 lh-5">
          Sed do eiusmod tempor incididunt magna aliqua.
        </p>
      </div>
    </div>

    <div class=" bgc-body-100/50 p-6 rad-5 fxcol-cs g-4">
      <div class="bgc-deepskyblue-150 c-deepskyblue-500 fxrow-cc square-12 rad-4 fs-6">C</div>
      <div>
        <h4 class="fs-4 fw-600 c-body-900 mb-0">Feature C</h4>
        <p class="fs-3 c-body-600 lh-5">
          Ut enim ad minim veniam, quis nostrud ullamco.
        </p>
      </div>
    </div>
  </div>
</div>

The Bento Dashboard

A modern, asymmetric layout perfect for dashboards or product showcases. This uses a mix of fractional columns and explicit spanning to create visual hierarchy.

R
Total Revenue
$128,430
U
Active Users
2,842
A
ACTIVITY
84%
Z
UPTIME
99.9%
CPU 14%
Memory 68%
System Online
Updated just now
View Logs
<div class="cnt">
  <div class="gr cols-2 sm:cols-4 sm:rows-3 g-4 --body=oklch(0.56_0.05_260)">
    <!-- Hero Stat -->
    <div class="col-2 row-2 bgc-body-100/50 p-6 rad-5 fxcol-ss g-3">
      <div class="bgc-coral-150 c-coral-500 fxrow-cc square-12 rad-4 fs-6">R</div>

      <div class="w-% mt-auto c-royalblue-500">
        <svg viewBox="0 0 100 25" class="w-% h-20" fill="none" stroke="currentColor" stroke-width="1" stroke-linejoin="bevel">
          <polyline points="0,24 15,23 30,18 45,19 60,14 80,12 100,1" />
        </svg>
      </div>

      <div class="fs-3 fw=600 c-body-400 mt-auto">Total Revenue</div>
      <div class="fs-8 fw=700 c-body-900">$128,430</div>
    </div>

    <!-- Activity -->
    <div class="col-2 bgc-body-100/50 p-6 rad-5 fxcol-ss">
      <div class="bgc-limegreen-150 c-limegreen-500 fxrow-cc square-10 rad-3 fs-5">U</div>
      <div class="fs-3 fw=600 c-body-400 mt-4">Active Users</div>
      <div class="fs-6 fw=700 c-body-900">2,842</div>
    </div>

    <!-- Small Stat 1 -->
    <div class=" bgc-body-100/50 p-6 rad-5 fxcol-ss g-2">
      <div class="bgc-deepskyblue-150 c-deepskyblue-500 fxrow-cc square-10 rad-3 fs-5">A</div>
      <div class="fs-2.5 fw=600 c-body-400 ls-0.1 mt-auto">ACTIVITY</div>
      <div class="fs-5 fw=700 c-body-900">84%</div>
    </div>

    <!-- Small Stat 2 -->
    <div class=" bgc-body-100/50 p-6 rad-5 fxcol-ss g-2">
      <div class="bgc-deepskyblue-150 c-deepskyblue-500 fxrow-cc square-10 rad-3 fs-5">Z</div>
      <div class="fs-2.5 fw=600 c-body-400 ls-0.1 mt-auto">UPTIME</div>
      <div class="fs-5 fw=700 c-body-900">99.9%</div>
    </div>

    <!-- Footer -->
    <div class="col=1/-1 bgc-body-100/50 p-6 rad-5 fxcol-ss">
      <div class="fxrow-cs g-8 w-%">
        <div class="w-% fxcol-sh g-3">
          <div class="fs-3">
            <span class="fw-600 c-body-600">CPU</span>
            <span class="fw-700 c-body-900">14%</span>
          </div>
          <div class="h-1.5 w-% bgc-body-200/20 rad-10 of=hidden">
            <div class="h-% w-14% bgc-limegreen-500 rad-10"></div>
          </div>
        </div>

        <div class="w-% fxcol-sh g-3">
          <div class="fs-3">
            <span class="fw-600 c-body-600">Memory</span>
            <span class="fw-700 c-body-900">68%</span>
          </div>
          <div class="h-1.5 w-% bgc-body-200/20 rad-10 of=hidden">
            <div class="h-% w-68% bgc-coral-500 rad-10"></div>
          </div>
        </div>
      </div>

      <div class="fxrow-cs g-4 pt-6 w-% mt-auto">
        <div class="bgc-limegreen-500 square-3 rad-%"></div>
        <div class="fxcol-ss g-2">
          <div class="fs-3.5 fw-600 c-body-800 lh-1.2">System Online</div>
          <div class="fs-2.5 fw-500 c-body-500">Updated just now</div>
        </div>
        
        <a class="bgc-body-900 c-body-50 px-4 py-2 rad-4 fs-3 fw-600 ml-auto cursor=pointer &:hover:o-80 tsdur-200">
          View Logs
        </a>
      </div>
    </div>
  </div>
</div>

Holy Grail Layout

The classic web application shell. This example demonstrates how beautifully areas-* handles complex structural shifts, moving from a stacked mobile view to a full desktop shell without touching a single media query breakpoint outside of the classes.

<div class="cnt">
  <div class="gr g-4 fs-3.5 --body=oklch(0.56_0.05_260)
    areas='header'_'nav'_'main'_'sidebar'_'footer' 
    xs:areas='header_header_header'_'nav_main_sidebar'_'footer_footer_footer'
    xs:cols-1/3/1"
  >
    
    <header class="area=header bgc-deepskyblue-100 c-deepskyblue-500 p-6 rad-4 fxrow-cc">Header</header>
    <nav class="area=nav bgc-coral-100 c-coral-500 p-6 rad-4 fxrow-cc">Navigation</nav>
    <main class="area=main bgc-limegreen-100 c-limegreen-500 p-6 rad-4 fxcol-cc">Main</main>
    <aside class="area=sidebar bgc-coral-100 c-coral-500 p-6 rad-4 fxrow-cc">Sidebar</aside>
    <footer class="area=footer bgc-deepskyblue-100 c-deepskyblue-500 p-6 rad-4 fxrow-cc">Footer</footer>
  </div>
</div>

Refer to the underlying CSS Grid properties for granular layout control.

Grid

Items

Spacing

ESC

Start typing to search across the documentation.