30 CSS Grid Layouts09 / 30

Pure CSSMIT licensed

Bento Box

The Apple-keynote bento: a dark grid of feature tiles where one 2×2 hero anchors the composition and satellites of varied spans orbit it. Each tile owns a different oklch accent glow, hover lifts are compositor-only, and the whole board reflows to a clean 2-column stack on phones.

Published Updated

Live Demo
Try it

The code

<section class="cgl-09" aria-label="Bento box grid demo">
  <div class="cgl-09__board">
    <article class="cgl-09__tile cgl-09__tile--hero" style="--glow:oklch(0.7 0.19 300)">
      <h3>One grid.<br>Every tile.</h3><p>The 2×2 hero anchors the bento; satellites auto-place around it.</p>
    </article>
    <article class="cgl-09__tile" style="--glow:oklch(0.78 0.16 200)"><h4>Auto rows</h4><p>minmax(96px, auto) — floors, not ceilings.</p></article>
    <article class="cgl-09__tile" style="--glow:oklch(0.8 0.17 140)"><h4>Spans</h4><p>span 2 wide, span 2 tall.</p></article>
    <article class="cgl-09__tile cgl-09__tile--tall" style="--glow:oklch(0.75 0.17 60)"><h4>Tall satellite</h4><p>grid-row: span 2 gives vertical rhythm without fixed heights.</p></article>
    <article class="cgl-09__tile cgl-09__tile--wide" style="--glow:oklch(0.68 0.2 20)"><h4>Wide satellite</h4><p>grid-column: span 2 — stats, charts, marquees.</p></article>
    <article class="cgl-09__tile" style="--glow:oklch(0.72 0.15 250)"><h4>Theming</h4><p>One --glow variable per tile.</p></article>
  </div>
</section>
.cgl-09,
.cgl-09 *,
.cgl-09 *::before,
.cgl-09 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cgl-09 {
  width: 100%;
  min-height: 100vh;
  --bg: oklch(0.14 0.015 290);
  --txt: oklch(0.95 0.01 290);
  --dim: oklch(0.68 0.02 290);
  font-family: system-ui,sans-serif;
  background: var(--bg);
  padding: 1.4rem;
}

.cgl-09 .cgl-09__board {
  display: grid;
  grid-template-columns: repeat(4,minmax(0,1fr));
  grid-auto-rows: minmax(96px,auto);
  gap: 12px;
}

.cgl-09 .cgl-09__tile {
  --glow: oklch(0.7 0.15 290);
  position: relative;
  border-radius: 16px;
  padding: 1.1rem;
  color: var(--txt);
  background: radial-gradient(140% 120% at 15% 0%,color-mix(in oklab,var(--glow) 16%,transparent),transparent 55%),oklch(0.19 0.02 290);
  border: 1px solid color-mix(in oklab,var(--glow) 28%,oklch(0.3 0.02 290));
  display: flex;
  flex-direction: column;
  gap: .45rem;
  justify-content: flex-end;
  transition: translate .25s ease,box-shadow .25s ease;
}

.cgl-09 .cgl-09__tile:hover {
  translate: 0 -3px;
  box-shadow: 0 18px 36px -18px color-mix(in oklab,var(--glow) 45%,transparent);
}

.cgl-09 .cgl-09__tile--hero {
  grid-column: span 2;
  grid-row: span 2;
  justify-content: center;
}

.cgl-09 .cgl-09__tile--wide {
  grid-column: span 2;
}

.cgl-09 .cgl-09__tile--tall {
  grid-row: span 2;
}

.cgl-09 h3 {
  font-size: clamp(1.3rem,3vw,1.8rem);
  line-height: 1.15;
  color: color-mix(in oklab,var(--glow) 70%,white);
}

.cgl-09 h4 {
  font-size: .95rem;
  color: color-mix(in oklab,var(--glow) 70%,white);
}

.cgl-09 p {
  font-size: .78rem;
  line-height: 1.55;
  color: var(--dim);
}

@media (max-width: 560px) {
  .cgl-09 .cgl-09__board {
    grid-template-columns: repeat(2,minmax(0,1fr));
  }

  .cgl-09 .cgl-09__tile--hero {
    grid-column: span 2;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cgl-09 .cgl-09__tile {
    transition: none;
  }
}
/* No JavaScript — span geometry builds the bento; each tile re-themes through a single --glow custom property. */
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Grid Layout from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Bento Box
Source: https://codefronts.com/layouts/css-grid-layouts/bento-box/

The Apple-keynote bento: a dark grid of feature tiles where one 2×2 hero anchors the composition and satellites of varied spans orbit it. Each tile owns a different oklch accent glow, hover lifts are compositor-only, and the whole board reflows to a clean 2-column stack on phones.
## HTML
```html
<section class="cgl-09" aria-label="Bento box grid demo">
  <div class="cgl-09__board">
    <article class="cgl-09__tile cgl-09__tile--hero" style="--glow:oklch(0.7 0.19 300)">
      <h3>One grid.<br>Every tile.</h3><p>The 2×2 hero anchors the bento; satellites auto-place around it.</p>
    </article>
    <article class="cgl-09__tile" style="--glow:oklch(0.78 0.16 200)"><h4>Auto rows</h4><p>minmax(96px, auto) — floors, not ceilings.</p></article>
    <article class="cgl-09__tile" style="--glow:oklch(0.8 0.17 140)"><h4>Spans</h4><p>span 2 wide, span 2 tall.</p></article>
    <article class="cgl-09__tile cgl-09__tile--tall" style="--glow:oklch(0.75 0.17 60)"><h4>Tall satellite</h4><p>grid-row: span 2 gives vertical rhythm without fixed heights.</p></article>
    <article class="cgl-09__tile cgl-09__tile--wide" style="--glow:oklch(0.68 0.2 20)"><h4>Wide satellite</h4><p>grid-column: span 2 — stats, charts, marquees.</p></article>
    <article class="cgl-09__tile" style="--glow:oklch(0.72 0.15 250)"><h4>Theming</h4><p>One --glow variable per tile.</p></article>
  </div>
</section>
```
## CSS
```css
.cgl-09,
.cgl-09 *,
.cgl-09 *::before,
.cgl-09 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cgl-09 {
  width: 100%;
  min-height: 100vh;
  --bg: oklch(0.14 0.015 290);
  --txt: oklch(0.95 0.01 290);
  --dim: oklch(0.68 0.02 290);
  font-family: system-ui,sans-serif;
  background: var(--bg);
  padding: 1.4rem;
}

.cgl-09 .cgl-09__board {
  display: grid;
  grid-template-columns: repeat(4,minmax(0,1fr));
  grid-auto-rows: minmax(96px,auto);
  gap: 12px;
}

.cgl-09 .cgl-09__tile {
  --glow: oklch(0.7 0.15 290);
  position: relative;
  border-radius: 16px;
  padding: 1.1rem;
  color: var(--txt);
  background: radial-gradient(140% 120% at 15% 0%,color-mix(in oklab,var(--glow) 16%,transparent),transparent 55%),oklch(0.19 0.02 290);
  border: 1px solid color-mix(in oklab,var(--glow) 28%,oklch(0.3 0.02 290));
  display: flex;
  flex-direction: column;
  gap: .45rem;
  justify-content: flex-end;
  transition: translate .25s ease,box-shadow .25s ease;
}

.cgl-09 .cgl-09__tile:hover {
  translate: 0 -3px;
  box-shadow: 0 18px 36px -18px color-mix(in oklab,var(--glow) 45%,transparent);
}

.cgl-09 .cgl-09__tile--hero {
  grid-column: span 2;
  grid-row: span 2;
  justify-content: center;
}

.cgl-09 .cgl-09__tile--wide {
  grid-column: span 2;
}

.cgl-09 .cgl-09__tile--tall {
  grid-row: span 2;
}

.cgl-09 h3 {
  font-size: clamp(1.3rem,3vw,1.8rem);
  line-height: 1.15;
  color: color-mix(in oklab,var(--glow) 70%,white);
}

.cgl-09 h4 {
  font-size: .95rem;
  color: color-mix(in oklab,var(--glow) 70%,white);
}

.cgl-09 p {
  font-size: .78rem;
  line-height: 1.55;
  color: var(--dim);
}

@media (max-width: 560px) {
  .cgl-09 .cgl-09__board {
    grid-template-columns: repeat(2,minmax(0,1fr));
  }

  .cgl-09 .cgl-09__tile--hero {
    grid-column: span 2;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cgl-09 .cgl-09__tile {
    transition: none;
  }
}
```

## JavaScript
```js
/* No JavaScript — span geometry builds the bento; each tile re-themes through a single --glow custom property. */
```

How this works

The board is grid-template-columns: repeat(4, minmax(0,1fr)) with grid-auto-rows: minmax(96px, auto). The hero pins itself with grid-column: span 2; grid-row: span 2; wide tiles span 2 columns, tall tiles span 2 rows. Because auto-rows have a floor but no ceiling, tiles grow with content instead of clipping it — the difference between a bento and a broken masonry.

Each tile's glow is one custom property: --glow feeds both a radial-gradient wash and the border tint via color-mix(), so re-theming a tile is a single line. Hover raises tiles with translate + shadow (transform-only, GPU-composited) and the reduced-motion query stills everything.

Make it yours

  • Re-anchor the hero anywhere with explicit lines (grid-column: 3 / 5) instead of spans.
  • Add tiles freely — auto-placement fills the board; add grid-auto-flow: dense if holes appear.
  • Set each tile's personality by changing only its --glow hue.
  • Tighten the board with a smaller auto-row floor (96px → 80px) for denser bentos.

Gotchas — read before shipping

  • Give the board minmax(0,1fr) columns or one long unbreakable string distorts every tile in that track.
  • Span-2 tiles need the 4-column board to stay 4 columns — the mobile query must also shrink spans (included) or you get horizontal scroll.
  • Keep glows under ~20% alpha; bento charm dies when tiles turn into neon signs.

Browser support

ChromeSafariFirefoxEdge
111+16.4+113+111+

oklch + color-mix drive the theming (2023 evergreens); the span geometry itself is original-grid and runs anywhere.

Techniques used in this demo

Search CodeFronts

Loading…