Cards✨ Premium

Interactive Bento

Click a cell to expand it 2×2 within the grid — native CSS Grid, 500 ms back-ease transition, only one cell active at a time.

JSClickExpand

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Cards has 41 effects, including 6 free. Explore the category →

3 usage examples

Product dashboard — Expandable KPI tiles — Interactive Bento example 1

① Product dashboard — Expandable KPI tiles

WhenThe user explores performance metrics (revenue, active users, conversion rate) from a dashboard without leaving the current page.
WhyThe 2×2 expansion gives the tile room to show a mini chart or additional detail, replacing a navigation or modal.
SettingsGap 8 px for density, transition reduced to 0.3 s for a responsive UI, brand colors (#6366f1/#8b5cf6 → your colors).
SaaS landing page — Interactive feature grid — Interactive Bento example 2

② SaaS landing page — Interactive feature grid

WhenThe Features section of a product: blocks summarise capabilities; a click expands to reveal the full description or a screenshot.
WhyThe interactive grid invites exploration where bullet lists are passive — each click drives engagement and increases time on page.
Settings`--radius-lg: 1rem` for a premium card look, distinct accent color per category (design / dev / ops), gap 16 px for breathing room.
Creative portfolio — Clickable project gallery — Interactive Bento example 3

③ Creative portfolio — Clickable project gallery

WhenA designer or agency presents their work: each cell is a thumbnail preview, expanding to reveal title, discipline, and link.
WhyThe bento replaces a complex slider or masonry layout — pure CSS Grid, no lightbox library, each project gets a focal point on click.
SettingsCell background = `background-image` (CSS thumbnail), expanded cell = semi-transparent overlay + project metadata, gap 8 px, `repeat(3, 1fr)` grid for wider projects.

How it works

Expansion relies on a single CSS rule: when the expanded class is added to a cell, grid-area: span 2/span 2 !important makes it occupy two columns and two rows. CSS Grid reflows the remaining cells automatically — no JS position calculation, no absolute positioning.

The .5s cubic-bezier(.175, .885, .32, 1.275) transition produces a slight back-ease-out bounce at the end: the cell briefly overshoots its target size before settling. The colored drop shadow and indigo-violet gradient (linear-gradient(135deg, #6366f1 0, #8b5cf6 100%)) animate in the same pass.

The expandCell(e) function handles the toggle: if the clicked cell already carries expanded, it removes it (collapse); otherwise it sweeps all cells in the same parent via e.parentElement.querySelectorAll('.bento-cell') to remove expanded everywhere, then adds it to the clicked cell. Only one cell expanded at a time, with no global state — multiple grids coexist on the same page without conflict.

Accessibility

  • prefers-reduced-motion absent: the effect does not detect this system preference — 500 ms transitions play even if the OS requests reduced motion. Add @media (prefers-reduced-motion: reduce) { .bento-interactive .bento-cell { transition: none } } if your use case requires it.
  • Cells use onclick on <div> elements, not <button>not keyboard-accessible without tabindex or a keydown handler. Replace the divs with <button type="button"> for native behavior (tab + Enter/Space).
  • No aria-expanded attribute or role is declared on the cells — a screen reader does not announce the expanded/collapsed state.
  • Secondary text contrast (#a1a1aa at 70% opacity) on background #1a1a24 falls below the WCAG AA 4.5:1 threshold for small text; the expanded cell (white on indigo) passes the AA test.
  • The SVG icon inside each cell lacks aria-hidden="true" — screen readers may announce it as empty text. Add the attribute to hide it.

Browser compatibility

Requires CSS Grid with `grid-area: span N/span N` and CSS transitions — supported in all modern browsers since 2018.

Chrome 57+✓ Full
Firefox 52+✓ Full
Safari 10.1+✓ Full
Edge 16+✓ Full
Mobile iOS✓ Touch OK
Android Chrome✓ Full

Without JS, cells display normally in the grid with no expand behaviour — the page remains readable. Without CSS Grid (IE 11), the grid is not rendered; use a flexbox or table layout as a fallback.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="bento-container">
  <div class="bento-grid bento-interactive" id="interactiveBento">

    <div class="bento-cell" onclick="expandCell(this)">
      <div class="cell-content">
        <div class="expand-icon">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none"
               stroke="currentColor" stroke-width="2" aria-hidden="true">
            <path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"></path>
          </svg>
        </div>
        <span>Label</span>
      </div>
    </div>

    <!-- × 6 cells total (4-column × 3-row grid) -->

  </div>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
--bg-elevated #1a1a24 Background color of interactive cells at rest. Replace with your surface color.
--bg-card #12121a Background color of the overall container. Align with your page background.
--border rgba(255,255,255,0.08) Cell border. Raise the opacity (0.15–0.25) for a more visible grid on a light background.
--radius-lg 0.75rem Corner radius of each cell. 0 for square tiles, 1rem for a rounded card look.
gradient .bento-cell.expanded linear-gradient(135deg, #6366f1 0, #8b5cf6 100%) Gradient of the expanded cell. Replace the two hex values with your brand colors, or use a flat background instead.
gap .bento-grid 12px Spacing between cells. 8 px for density, 16 px for an airy premium card feel.
grid-template-columns .bento-interactive repeat(4, 1fr) Number of columns. Switch to repeat(3, 1fr) for larger cells or richer per-tile content.
transition .bento-interactive .bento-cell .5s cubic-bezier(.175, .885, .32, 1.275) Expansion duration and curve. Reduce to .25s ease-out for a tighter management UI, increase to .8s for a cinematic fluid feel.

FAQ

expandCell scopes its selection to e.parentElement.querySelectorAll('.bento-cell') — each grid manages its own cells with no global state. Two div.bento-grid.bento-interactive side by side work without conflict.
Replace each <div class="bento-cell" onclick="expandCell(this)"> with a <button type="button" class="bento-cell" onclick="expandCell(this)">: buttons are natively focusable and activatable with Enter/Space. Add aria-expanded dynamically inside expandCell to inform screen readers.
Add a hidden block inside each cell (display:none or opacity:0; height:0) and reveal it via CSS: .bento-cell.expanded .extra { display:block } — no JS changes needed. The content appears automatically on expansion and hides on collapse.