Skip to content

Bento Grid Layouts in 2026: CSS Grid vs Elementor (What Actually Works)

Key Takeaways

  • grid-template-areas crea un mapa de diseño legible para un bento grid, y un área con el mismo nombre forma una sola región de celdas.
  • MDN exige que cada área nombrada sea un rectángulo; si una zona es en L, la declaración completa se invalida y el navegador vuelve al auto-flow.
  • Los puntos . crean celdas vacías a propósito, y varios puntos ayudan a alinear las cadenas en el editor.
  • Elementor Grid container usa Rows en Custom measurement para filas de distinto tamaño, con ejemplos como 200PX 1FR 400PX.
  • The Plus Addons for Elementor expone un campo Custom CSS en su panel Plus Extras, mientras Elementor solo ofrece Autoflow Row o Column y no un mapa de áreas nombradas.

I rebuilt a client’s features section three times last month before I worked out what was wrong. They wanted the layout every product page seems to have now: one big tile carrying the headline feature, a couple of medium ones, a few small ones, all locked into a tidy rectangle. I kept building it as a flex row with different widths, and it kept falling apart the moment the copy in one tile ran two lines longer than the others.

The layout has a name. It is a bento grid, after the Japanese lunchbox divided into compartments of different sizes that still add up to one neat box. And the reason my flex version kept breaking is that a bento grid is not a row of boxes. It is a grid where specific tiles deliberately claim more than one cell, and CSS has a property built for exactly that which almost nobody reaches for first.

 

Table Of Contents

 

What Makes a Grid “Bento” (and How It Differs From Masonry)

The two get confused constantly, and the difference is not cosmetic. It changes which CSS you write.

A masonry layout is automatic. You hand the browser a pile of items of unpredictable height and it packs them into columns as tightly as it can. You do not decide where any single item lands, and you do not want to, because the content changes.

A bento grid is the opposite. It is designed. The tile sizes carry meaning: the biggest tile is the most important feature, and you chose that. A bento grid has a fixed number of cells, and each tile is assigned to a specific region of it. If your content is genuinely unpredictable, you want masonry. If you are laying out six known features and one of them matters most, you want bento.

A four column, two row bento grid where the hero tile claims a 2x2 block, a secondary tile spans two columns, and two detail tiles span one each
Four columns, two rows, and one tile claiming a 2×2 block. The unequal sizes are the message: the biggest tile is the most important feature, chosen rather than auto-packed.

The Named Area Map: grid-template-areas

This is the property that makes bento layouts pleasant to write instead of fiddly. Rather than telling each tile which grid lines to sit between, you draw the layout as text on the parent and let each tile claim a name.

.bento {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 200px 200px 200px;
  gap: 14px;
  grid-template-areas:
    "hero  hero  feat  feat"
    "hero  hero  side  chip"
    "stats stats stats chip";
}

.hero  { grid-area: hero;  }
.feat  { grid-area: feat;  }
.side  { grid-area: side;  }
.chip  { grid-area: chip;  }
.stats { grid-area: stats; }
A grid-template-areas declaration written as three rows of named strings beside the bento layout it produces, with hero, feat, side, chip and stats tiles
The declaration on the left and the layout it produces on the right. Written this way the CSS is a picture of the design, and every tile just claims its name.

Read those three strings and you can see the finished page. The hero occupies a two by two block in the top left. The chip tile runs down the right edge across rows two and three. Nothing anywhere else in your stylesheet needs to know a single grid line number.

MDN describes the mechanic plainly: “Multiple cell tokens with the same name within and between rows create a single named grid area that spans the corresponding grid cells.”

Mdn web docs grid-template-areas reference page showing named area string syntax
MDN’s grid-template-areas reference documents the rule that breaks most bento attempts: a named area must form a rectangle or the whole declaration is invalid.

The Rectangle Rule That Silently Breaks It

Here is the one that costs people an afternoon. From MDN, immediately after the sentence above: “Unless those cells form a rectangle, the declaration is invalid.”

An L-shaped tile is not possible. If you write this, hoping for a tile that wraps a corner:

/* INVALID: area "a" is an L, not a rectangle */
grid-template-areas:
  "a a b"
  "a c c";
A valid grid-template-areas value where area a forms a 2x2 rectangle, beside an invalid l-shaped area where the browser drops the whole declaration and falls back to auto-flow
The failure is silent and total. On the right, area “a” forms an L, so the browser discards the entire grid-template-areas value and the tiles fall back to plain auto-flow at equal size.

The browser does not fix it, warn you visually, or lay out the parts that were valid. It throws away the entire grid-template-areas value. Your tiles fall back to plain auto placement, every cell the same size, and the page looks like you forgot to write the CSS at all. If your bento suddenly renders as a boring uniform grid, count the corners of every named area before you look at anything else.

Leaving Cells Empty on Purpose

Bento layouts often need breathing room, and there is a token for it. MDN: “A null cell token is a sequence of one or more . (U+002E FULL STOP) characters, e.g., ., ..., or ..... etc. A null cell token can be used to create empty spaces in the grid.”

grid-template-areas:
  "hero hero ."
  "hero hero chip"
  ".    stats stats";

Using several dots instead of one is worth doing purely so your strings line up in the editor. The alignment is what makes the map readable, and a map you can read is the entire reason to use this property.

The Span Approach, and When to Prefer It

The other route skips names and puts the instruction on each tile:

.bento { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }

.hero { grid-column: span 2; grid-row: span 2; }
.feat { grid-column: span 2; }
.chip { grid-row: span 2; }

This is shorter, and it is the better choice when tiles come out of a loop and you do not know how many there will be. You can style “every fourth card is wide” with :nth-child(4n) and never write a map at all. If those tiles are coming from a query, Elementor Loop Grid in the V4 atomic era is worth reading first, because dynamic item styling has its own failure modes.

The trade is legibility. With spans, the layout exists only in your head, assembled from rules scattered across several selectors. With a named map, the layout is one block of text you can hand to a designer. For a fixed marketing section, use the map. For a dynamic feed, use spans.

Responsive Bento Is One Re-Drawn Map

This is where the named-area approach pulls decisively ahead, and it is the argument that usually settles it. To reflow a bento grid for mobile, you redraw the picture. You do not touch a single tile.

@media (max-width: 767px) {
  .bento {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: auto auto auto;
    grid-template-areas:
      "hero  hero"
      "feat  side"
      "stats stats";
  }
}
The same bento layout at desktop and mobile, with the grid-template-areas value re-declared inside a media query so every tile follows the new map
The same five tiles at both breakpoints. Only the map inside the media query changed; no tile was edited, because each one references a name rather than a position.

The chip tile is not in that map, so it simply is not placed by name any more. Every other tile moves because the map moved. Compare that with the span approach, where the same change means editing grid-column and grid-row on four or five separate selectors and hoping you caught them all.

One caution: on mobile, tile order becomes reading order. A tile that sat in a visually obvious spot on desktop can end up buried on a phone. Decide what the mobile sequence should be first, then write the map to produce it.

Building a Bento Grid in Elementor

Elementor’s Grid container can do this, which is a genuinely different answer from some other CSS trends where the builder simply cannot reach the effect. It is worth being precise about what it does and does not give you.

Unequal Tracks via Custom Measurement

By default a Grid container is uniform. Elementor’s own documentation says the Grid option “is created with an equal number of symmetric rows and columns,” and the Columns and Rows sliders measure in fractions.

Uniform is the opposite of bento, so the control you need is the measurement dropdown next to Rows. Elementor documents it directly: “Custom measurement is also used to create different size rows. This is done by selecting custom measurement and entering a value for each row. For example, for three rows you could enter the values 200PX 1FR 400PX.” That is grid-template-rows with a friendlier label, and it is what gets you tracks of different sizes.

Column Span and Row Span

Tile spanning lives on the tile, not the container. Select the widget, open the Advanced tab, and find the Grid Item section. Elementor is candid about why the feature exists: “Grid containers are great for creating a symmetrical design, but they can be somewhat constrictive. The span content feature gives you greater flexibility.”

Column Span and Row Span are dropdowns of plain numbers, plus a Custom option. Custom takes the line-based syntax: per the docs, “1 / 3: Span from the first line to the third line” and “2 / 5: Span from the second line to the fifth line.” Pick Custom whenever you need a tile to start somewhere other than where auto-flow would have put it.

Elementor help documentation showing the column span and row span controls in the grid item section of the advanced tab
Elementor documents Column Span and Row Span in the Grid Item section of the Advanced tab, including a Custom field that accepts line-based values such as 1 / 3.

Two behaviours from the same doc are worth knowing before you start dragging. First, “all cells in a grid are the same size,” so widening one tile changes the cell size for the whole grid rather than just that tile. Second, “Normally with a grid, you can’t have blank cells, but custom spanning allows this,” which is how you get the deliberate gaps a bento layout usually needs.

What Elementor’s Grid Does Not Give You

Two real gaps, both worth knowing up front rather than discovering at the responsive stage.

There is no named-area map. Nothing in the Grid container UI corresponds to grid-template-areas. Your layout lives as span settings distributed across individual widgets, so reflowing for mobile means visiting each tile and changing its spans per breakpoint, rather than rewriting one block of text.

There is also no dense packing. Elementor’s Autoflow dropdown offers exactly two choices, Row or Column. CSS has a third setting, grid-auto-flow: row dense, which backfills gaps left by larger tiles. If you want dense behaviour, that is a custom CSS line. The rundown of how to add custom CSS in Elementor covers where to put it, and The Plus Addons for Elementor exposes a Custom CSS field in its Plus Extras panel if you are on Elementor Free.

CSS Grid vs Elementor: Which Should You Use

Hand-written CSS GridElementor Grid container
Unequal tracksgrid-template-rows: 200px 1fr 400pxYes, Rows measurement dropdown set to Custom
Tile spanninggrid-column: span 2Yes, Advanced then Grid Item then Column/Row Span
Start at a specific linegrid-column: 1 / 3Yes, via the Custom field
Named area mapYes, grid-template-areasNo UI equivalent
Dense backfillYes, grid-auto-flow: row denseNo, Autoflow is Row or Column only
Responsive reflowRedraw one map per breakpointEdit spans per tile per breakpoint
Best forFixed sections, many breakpointsVisual iteration, client hand-off

The honest split: if the section is a fixed marketing layout you will refine across three or four breakpoints, hand-written CSS with a named map will cost you less over time. If someone non-technical needs to reposition tiles later without touching code, build it in the Grid container and accept the per-tile span work.

The Accessibility Trap: Dense Packing and Reading Order

This is the part that gets skipped, and it is a real defect rather than a nitpick.

Bento grids tend to leave gaps, and the tempting fix is grid-auto-flow: dense. MDN explains what it actually does: the dense algorithm “attempts to fill in holes earlier in the grid, if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.”

Out of order visually, but not in the DOM. Keyboard focus and screen reader order follow the document, not the painted grid. So a keyboard user tabs through your tiles in a sequence that does not match what a sighted user sees, and the focus ring appears to jump around the section at random. The default sparse algorithm exists precisely to avoid this: MDN notes it “ensures that all of the auto-placed items appear in order, even if this leaves holes.”

The rule worth adopting: if your tiles contain links or buttons, do not use dense. Reorder the markup, or design the map so there are no holes to fill. Save dense for non-interactive tiles like images and stats.

One more, cheap to do and easy to forget: a bento grid is a set of sibling regions, not a list. If each tile is a distinct feature, give the section a heading and let each tile carry its own heading level, so the structure survives being read linearly.

Where Bento Works and Where It Does Not

It works when you have a small, known set of things and one of them deserves to be bigger. Product feature sections, a stats block, a homepage “what we do” area, an integrations showcase, a pricing comparison. Six to nine tiles is the sweet spot.

It fails when the tile sizes do not mean anything. If the biggest tile is big because the grid needed filling rather than because that feature matters most, you have decoration pretending to be hierarchy, and visitors read the emphasis you did not intend. The size is the message.

It also fails past roughly a dozen tiles. Beyond that the eye stops perceiving a composition and starts seeing a wall, and you would be better served by a uniform grid or a proper masonry layout. And if the tile contents are genuinely variable in height, this is the wrong tool: fixed rows will either clip your longest tile or leave the short ones half empty.

Frequently Asked Questions

What Is a Bento Grid Layout?

A grid layout where tiles deliberately occupy different numbers of cells, so the composition has a clear visual hierarchy. It is named after the Japanese bento box, which divides a meal into compartments of different sizes that still form one tidy rectangle.

Is a Bento Grid the Same as Masonry?

No. Masonry auto-packs items of unpredictable height and you do not control placement. A bento grid has a fixed cell structure and every tile is assigned a specific region on purpose. Masonry is automatic, bento is designed.

Can Elementor Build a Bento Grid?

Yes. Use a Grid container, set the Rows measurement to Custom for unequal track sizes, then set Column Span and Row Span per widget in the Grid Item section of the Advanced tab. The two things you cannot do from the UI are a named area map and dense auto-flow.

Why Did My grid-template-areas Stop Working?

Almost always because one named area is not a rectangle. An L or T shape makes the entire declaration invalid, and the browser discards all of it rather than part of it, so the grid falls back to uniform auto placement. Check that every repeated name forms a clean block, and that every row string has the same number of tokens.

How Do I Make a Bento Grid Responsive?

Re-declare grid-template-columns and grid-template-areas inside a media query. Every tile follows the new map automatically because tiles reference names, not positions. Decide the mobile reading order before you write the map, since on a narrow screen tile order becomes reading order.

Suggested Reading

Related Frequently Asked Questions

Why does a bento grid break when one tile is taller than the others?

A bento grid only works when each tile fits a planned rectangle, because the layout is built from fixed cells and deliberate spans. If one tile grows in an uncontrolled way, the whole composition stops reading like a designed grid and starts behaving like a broken row. The page’s key point is that bento is for known content with meaning attached to size, while unpredictable heights belong in masonry.

What is the difference between a bento grid and masonry?

Masonry auto-packs items of unpredictable height into columns, so you do not control where each item lands. A bento grid is designed in advance, with tiles assigned to specific regions and sizes that signal importance. That difference matters because masonry fits variable content, while bento fits fixed marketing sections where one feature should be visually larger than the rest.

Why does grid-template-areas fail when I try to make an L-shaped tile?

Because every named area has to form a rectangle. If a repeated name makes an L or T shape, the browser treats the entire grid-template-areas value as invalid and drops it. The result is not a partial layout fix, it falls back to plain auto placement with equal-sized cells. That is why a broken bento often looks like uniform boxes instead of a partially working grid.

How do I make empty space in a CSS bento grid on purpose?

Use null cell tokens, which are dots inside grid-template-areas. The page shows that one or more dots can create empty spaces in the map, and using several dots helps keep the strings aligned and readable. That matters because bento layouts often need breathing room, and the map stays easier to maintain when the empty cells line up cleanly in the editor.

Should I build a bento grid with CSS Grid or Elementor Grid container?

CSS Grid is better when the section is fixed and you want one named map that you can redraw per breakpoint. Elementor Grid container is better when someone non-technical needs to adjust tiles later without touching code. The tradeoff is control versus convenience: CSS gives you grid-template-areas and dense backfill, while Elementor gives you span controls per widget but no named-area map.

Is dense packing safe for interactive bento grids?

Dense packing is risky when tiles contain links or buttons, because it can change visual order without changing DOM order. MDN’s dense algorithm fills holes earlier in the grid if smaller items come later, which can make keyboard focus jump around in a way that does not match what sighted users see. For interactive sections, sparse order or a gap-free map is safer.

Last reviewed: September 2, 2026