FreeFeaturedAnimated

Bento Grid

Editorial bento layout for benefits, features, or value props.

#bento#grid#features#editorial#blocks

Live preview

See it in action.

Fully interactive, drag, click, scroll inside the frame, toggle to mobile.

About this section

Apple-style bento with three cell sizes (1/3, 2/3, full row), optional background image per cell, and graceful single-column collapse on mobile. Block-driven.

Install in 90 seconds

  1. 01

    Create /sections/modblo-bento-grid.liquid.

  2. 02

    Paste the code and save.

  3. 03

    Add the section, then add Tile blocks. Choose a size per tile.

The Liquid

modblo-bento-grid.liquid
{%- comment -%} modblo. Bento Grid {%- endcomment -%}
<section class="modblo-bento" data-section-id="{{ section.id }}"
  style="--modblo-bg: {{ section.settings.bg }}; --modblo-fg: {{ section.settings.fg }};">
  <div class="modblo-bento__inner page-width">
    {%- if section.settings.heading != blank -%}
      <h2 class="modblo-bento__heading">{{ section.settings.heading }}</h2>
    {%- endif -%}
    {%- if section.settings.subheading != blank -%}
      <p class="modblo-bento__sub">{{ section.settings.subheading }}</p>
    {%- endif -%}

    <div class="modblo-bento__grid">
      {%- for block in section.blocks -%}
        <article class="modblo-bento__cell modblo-bento__cell--{{ block.settings.size }}" {{ block.shopify_attributes }}
          {%- if block.settings.bg %} style="--modblo-cell: {{ block.settings.bg }}"{% endif %}>
          {%- if block.settings.image != blank -%}
            {{ block.settings.image | image_url: width: 1200 | image_tag:
              loading: 'lazy', widths: '400,800,1200', class: 'modblo-bento__img' }}
          {%- endif -%}
          <div class="modblo-bento__body">
            {%- if block.settings.eyebrow != blank -%}
              <p class="modblo-bento__eyebrow">{{ block.settings.eyebrow }}</p>
            {%- endif -%}
            <h3>{{ block.settings.title }}</h3>
            {%- if block.settings.text != blank -%}
              <p>{{ block.settings.text }}</p>
            {%- endif -%}
            {%- if block.settings.cta_label != blank -%}
              <a href="{{ block.settings.cta_link }}" class="modblo-bento__cta">
                {{ block.settings.cta_label }} →
              </a>
            {%- endif -%}
          </div>
        </article>
      {%- endfor -%}
    </div>
  </div>
</section>

<style>
  .modblo-bento { background: var(--modblo-bg, #fafafa); color: var(--modblo-fg, #0b0b0c); padding: clamp(64px,10vw,128px) 0; }
  .modblo-bento__inner { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
  .modblo-bento__heading { font-size: clamp(28px,4vw,44px); letter-spacing: -.025em; margin: 0 0 12px; max-width: 640px; }
  .modblo-bento__sub { font-size: 17px; opacity: .72; max-width: 560px; margin: 0 0 36px; }
  .modblo-bento__grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    grid-auto-rows: minmax(180px, auto);
    gap: 16px;
  }
  .modblo-bento__cell {
    background: var(--modblo-cell, color-mix(in oklab, var(--modblo-fg) 4%, var(--modblo-bg)));
    border: 1px solid color-mix(in oklab, var(--modblo-fg) 8%, transparent);
    border-radius: 20px; padding: 24px;
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; justify-content: flex-end;
    transition: transform .35s cubic-bezier(.16,1,.3,1), border-color .25s;
    grid-column: span 2;
  }
  .modblo-bento__cell:hover { transform: translateY(-3px); border-color: color-mix(in oklab, var(--modblo-fg) 16%, transparent); }
  .modblo-bento__cell--lg { grid-column: span 4; }
  .modblo-bento__cell--xl { grid-column: span 6; }
  .modblo-bento__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .9; }
  .modblo-bento__body { position: relative; z-index: 1; }
  .modblo-bento__cell:has(.modblo-bento__img) .modblo-bento__body {
    color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.3);
  }
  .modblo-bento__eyebrow { text-transform: uppercase; letter-spacing: .14em; font-size: 11px; opacity: .65; margin: 0 0 6px; font-weight: 600; }
  .modblo-bento__cell h3 { font-size: 20px; letter-spacing: -.015em; margin: 0; }
  .modblo-bento__cell p { font-size: 14px; opacity: .8; line-height: 1.5; margin: 8px 0 0; }
  .modblo-bento__cta { display: inline-block; margin-top: 14px; font-size: 13px; font-weight: 600; color: inherit; text-decoration: none; }

  @media (max-width: 768px) {
    .modblo-bento__grid { grid-template-columns: 1fr; }
    .modblo-bento__cell, .modblo-bento__cell--lg, .modblo-bento__cell--xl { grid-column: span 1; }
  }
</style>

{% schema %}
{
  "name": "Bento Grid",
  "tag": "section",
  "settings": [
    { "type": "text", "id": "heading", "label": "Heading", "default": "Built for the way modern brands ship." },
    { "type": "textarea", "id": "subheading", "label": "Subheading" },
    { "type": "color", "id": "bg", "label": "Background", "default": "#fafafa" },
    { "type": "color", "id": "fg", "label": "Foreground", "default": "#0b0b0c" }
  ],
  "blocks": [{
    "type": "tile",
    "name": "Tile",
    "settings": [
      { "type": "select", "id": "size", "label": "Size",
        "options": [
          { "value": "sm", "label": "Small (1/3)" },
          { "value": "lg", "label": "Wide (2/3)" },
          { "value": "xl", "label": "Full row" }
        ], "default": "sm" },
      { "type": "text", "id": "eyebrow", "label": "Eyebrow" },
      { "type": "text", "id": "title", "label": "Title", "default": "Performance-first" },
      { "type": "textarea", "id": "text", "label": "Text" },
      { "type": "image_picker", "id": "image", "label": "Background image (optional)" },
      { "type": "color", "id": "bg", "label": "Cell background" },
      { "type": "text", "id": "cta_label", "label": "CTA label" },
      { "type": "url", "id": "cta_link", "label": "CTA link" }
    ]
  }],
  "max_blocks": 12,
  "presets": [{
    "name": "Bento Grid",
    "blocks": [
      { "type": "tile", "settings": { "size": "lg", "title": "One marketplace, every section." } },
      { "type": "tile", "settings": { "size": "sm", "title": "99 Lighthouse" } },
      { "type": "tile", "settings": { "size": "sm", "title": "Native Liquid" } },
      { "type": "tile", "settings": { "size": "sm", "title": "Mobile-first" } },
      { "type": "tile", "settings": { "size": "lg", "title": "Built by ex-Shopify devs." } }
    ]
  }]
}
{% endschema %}

Theme editor settings

SettingTypeDefault

Heading

heading

text,

Subheading

subheading

textarea,

Background

bg

color,

Foreground

fg

color,

SEO & accessibility notes

  • Each tile is a real <article> with semantic <h3>.
  • :has() selector toggles overlay text styling when an image is present, no JS.