8pt

Media Bento Grid

Media Bento Grid•Cards
Overview

A six-tile capability bento: one wide image across two columns, one tall image across two rows, then two small and two wide tiles. Every tile is a full-bleed image with a bottom fade; on hover the image slowly zooms and the arrow after the title slides forward.

Taken from the page template Ranzhen AI Video Studio Home. Use it on its own, or combine it with the other components from the same template to rebuild the full page.

Plain HTML, CSS and a little vanilla JS, with no framework dependency. Copy the prompt into Claude Code, Cursor, Trae or Codex and the model adds Media Bento Grid to your project in your colors.

Where to use it

Sections that present information in groups: features, case studies and work, team members, article lists.

Install

With Builder, install it with the 8pt CLI or call it directly from an editor connected to 8pt MCP.

$ npm i -g @8pt-dev/cli && 8pt add media-bento-grid
mcp › Use 8pt MCP to call get_component("media-bento-grid")

Code

Source for Media Bento Grid. Motion uses only transform and opacity and respects the Reduce motion setting.

<div class="x-rzb"><div class="x-rzb__in" style="width:1000px;height:640px"><a class="x-rzb__c b1" href="#"><i style="background-image:url(https://8pt.dev/assets/tpl/ranzhen/m-product.webp)"></i><b>4K  quality visuals <span>›</span></b><small>Realistic light, crisp detail, and text that renders accurately.</small></a><a class="x-rzb__c b2" href="#"><i style="background-image:url(https://8pt.dev/assets/tpl/ranzhen/h2.webp)"></i><b>Reusable assets <span>›</span></b><small>The same product, scene and style stay consistent in every video.</small></a><a class="x-rzb__c b3" href="#"><i style="background-image:url(https://8pt.dev/assets/tpl/ranzhen/c2.webp)"></i><b>Cinematic camera moves <span>›</span></b><small>Real motion, rhythm and smooth camera moves.</small></a><a class="x-rzb__c b4" href="#"><i style="background-image:url(https://8pt.dev/assets/tpl/ranzhen/h6.webp)"></i><b>Lifelike characters <span>›</span></b><small>Natural expressions, voice and demeanor.</small></a><a class="x-rzb__c b5" href="#"><i style="background-image:url(https://8pt.dev/assets/tpl/ranzhen/h8.webp)"></i><b>Music, dialogue and sound effects <span>›</span></b><small>Shape every scene with sound.</small></a><a class="x-rzb__c b6" href="#"><i style="background-image:url(https://8pt.dev/assets/tpl/ranzhen/s4.webp)"></i><b>Endless styles <span>›</span></b><small>From photoreal to animation, there’s a look for you.</small></a></div></div>
.x-rzb{position:relative;flex:none}
.x-rzb__in{position:absolute;left:0;top:0;transform-origin:0 0;display:grid;grid-template-columns:repeat(6,1fr);grid-template-rows:repeat(3,1fr);gap:14px;font-family:var(--d-font,system-ui,sans-serif)}
.x-rzb__c{position:relative;display:flex;flex-direction:column;justify-content:flex-end;padding:20px;border-radius:18px;overflow:hidden;isolation:isolate;background:#111;color:#fff;text-decoration:none}
.x-rzb__c>i{position:absolute;inset:0;z-index:-2;background:center/cover no-repeat;transition:transform .8s cubic-bezier(.16,1,.3,1)}
.x-rzb__c::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(180deg,transparent 35%,rgba(0,0,0,.85))}
.x-rzb__c b{font-size:18px;font-weight:700}.x-rzb__c b span{display:inline-block;color:#FF8A3D;transition:transform .25s cubic-bezier(.16,1,.3,1)}
.x-rzb__c small{margin-top:4px;font-size:13px;color:#cfc9cc}
.x-rzb__c:hover>i,.x-rzb__c:focus-visible>i{transform:scale(1.06)}.x-rzb__c:hover b span,.x-rzb__c:focus-visible b span{transform:translateX(4px)}
.x-rzb__c:focus-visible{outline:2px solid #FF8A3D;outline-offset:2px}
.x-rzb__c.b1{grid-column:span 4}.x-rzb__c.b2{grid-column:span 2;grid-row:span 2}.x-rzb__c.b3,.x-rzb__c.b4{grid-column:span 2}.x-rzb__c.b5,.x-rzb__c.b6{grid-column:span 3}
@media (prefers-reduced-motion:reduce){.x-rzb__c>i,.x-rzb__c b span{transition:none}}
const init = (root) => {
  const fit = (box, W, H) => {
    const inner = box.firstElementChild;
    const run = () => {
      const cs = getComputedStyle(root);
      const aw = root.clientWidth - parseFloat(cs.paddingLeft) - parseFloat(cs.paddingRight);
      const ah = root.clientHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom);
      if (aw <= 0 || ah <= 0) return;
      const s = Math.max(0.2, Math.min(aw / W, ah / H, 1));
      box.style.width = W * s + 'px'; box.style.height = H * s + 'px'; inner.style.transform = `scale(${s})`;
    };
    const ro = new ResizeObserver(run); ro.observe(root); run();
…
Subscribe to Builder to see the full source.See pricing

Other components from this template

View all

AI Prompt Composer

Film Strip Carousel

Auto Tab Showcase

Agent Chat Window

Model Pill Marquee

Director Art Cards

More cards components

View all

Director Art Cards

Glass Folder

File Preview Cards

Spotlight Card

Card Stack

Bento Grid

Border Beam Card

Tilt Card

More components

View all

AI Prompt Composer

Film Strip Carousel

Auto Tab Showcase

Agent Chat Window

Model Pill Marquee

Mac File Window

Disk Cleanup Panel

Shortcut Keycaps

Keep exploring