By Tim King · Updated
Bento Grid CSS Generator
CSS Grid Layout with Spanning Tiles
OneTask is free, with no sign-up, and built by one person.
If this tool saved you time, a coffee helps keep new ones coming.
How the Bento Grid Builder works
This bento grid CSS generator lets you lay one out by spanning tiles. A bento grid is a dashboard-style layout where tiles of different sizes fit together like compartments in a lunch box. Pick a pattern, tune the gap, row height and corners, and copy a CSS Grid snippet where the spans are already worked out and a mobile breakpoint is included.
A bento grid packs tiles of different sizes into one tidy rectangle, like the compartments of a Japanese lunch box. Apple's product launch slides made it famous around 2022, and it has since become the default layout for SaaS feature sections, portfolio home pages and dashboards. The appeal is hierarchy without chaos: the most important item gets a big tile, supporting items get small ones, and everything still shares the same gutters and edges.
How the bento grid CSS works
Under the look there is nothing exotic, just CSS Grid and a few span rules.
- Four equal columns. The container uses
grid-template-columns: repeat(4, 1fr), so every column shares the width equally, whatever the container size. - Fixed-height rows.
grid-auto-rowssets every row to your row height. A tile that spans two rows is exactly two rows tall plus one gap, and that arithmetic is what makes the edges line up. - Spans on
nth-child. Tiles are one cell by default. The generator writes a rule only for tiles that need more, such asgrid-column: span 2on.bento-tile:nth-child(1). The markup carries no layout classes, so reordering the HTML moves content in and out of the big slot. - Dense packing.
grid-auto-flow: denselets a later small tile move up and fill a hole left by a tall one, instead of leaving an empty cell.
The four patterns
Each pattern fills exactly twelve cells, three full rows of four, so the grid always ends square. Uniform is the exception, with eight single cells in two rows.
| Pattern | Featured tile | Other tiles | Good for |
|---|---|---|---|
| Feature left | 2 × 2 | four 1 × 1, two 2 × 1 | Product pages, a hero plus supporting points |
| Feature top | 3 × 1 banner | one 1 × 2, one 1 × 1, three 2 × 1 | Announcement, then detail |
| Mosaic | 2 × 1 | tall, wide and square mixed | Editorial pages and portfolios |
| Uniform | none bigger | eight 1 × 1 | A clean start to place your own spans |
The preview labels every tile with its size, such as "2 × 1", so you can see which spans the CSS
produced. The first tile in every pattern gets the is-featured class, the accent gradient and
a larger heading.
Choosing the numbers
- Row height is the main design lever. Between 140 and 200 px suits a tile holding an icon, a heading and one line of copy. Lower it for a dense dashboard and raise it for screenshots.
- Gap usually works best between 12 and 24 px. Keep it smaller than the tile padding, or the gutters start to compete with the content.
- Radius. Match the rest of your interface. Large radii of 20 px or more read as friendly and consumer; 8 to 12 px read as a tool. Keep the radius at least as large as the gap, or the corners look cramped.
- Tile and featured colours. Keep the plain tiles quiet so the featured tile stands out. The featured tile uses white text on your accent colour, so check the pair in the contrast checker; a mid-tone accent often fails.
Where it breaks, and how to fix it
- Text overflow. Fixed rows do not grow. If a tile might hold more text than fits, change
the rule to
grid-auto-rows: minmax(160px, auto)so a row stretches when it needs to, at the cost of perfectly equal heights. - Source order and focus. Dense packing can move a tile visually without moving it in the HTML, and keyboard users tab in source order. Keep the most important content first in the markup, which the patterns already do.
- Small screens. The included media query switches to two columns below 720 px, resets
every tile to a single cell, and lets the featured tile span both columns. On a very narrow
phone, change
repeat(2, 1fr)to1frfor a single stack. - Too many tiles. Past eight or nine tiles a bento stops reading as a hierarchy and turns into a wall. Split the content into two sections instead.
Using the code
Copy the HTML and CSS together. The HTML is a <section class="bento"> holding one <article>
per tile with an h3 and a p. Replace the placeholder text with your own, and put an icon or
screenshot above the heading; tiles align content to the bottom with
justify-content: flex-end, so an image sits naturally at the top. If you add tiles beyond the
pattern, they become single cells and dense packing fits them in.
For a grid of equal-width columns with items of varying height, use the masonry grid instead. To place tiles by name rather than by span, try the grid areas builder, and for plain rows and columns the CSS grid generator.
FAQ
How do I change which tile is featured?
The featured styling is on the .is-featured class and the size is on
.bento-tile:nth-child(1). Move the class to another article and update the nth-child
selector to match its position, or replace the nth-child rules with explicit classes such as
.span-2 if you prefer to control layout from the markup.
Why do some tiles jump out of order?
That is grid-auto-flow: dense backfilling empty cells with later items. It keeps the grid free
of holes but can move a tile visually ahead of one that comes before it in the HTML. Remove the
dense keyword if strict source order matters more to you than a gap-free layout.
Can the tiles grow to fit their content?
Yes. Replace the fixed grid-auto-rows value with minmax(120px, auto). Rows will then be at
least 120px but stretch when a tile needs more room. The spanning tiles keep their proportions
relative to whatever the rows become.
How do I add more tiles?
Append more <article class="bento-tile"> elements. New tiles default to one cell each and flow
into the next available slot. Add an nth-child rule with a span if you want any of them to be
larger; the grid creates as many rows as it needs.
Does this work without the mobile media query?
It renders, but on a narrow phone four columns become very thin and the featured tile's text will wrap badly. The breakpoint is three lines and it is the difference between a layout that works on mobile and one that only looks good in a desktop screenshot.
See also: all Layout & Spacing tools, Shadows & Motion, Shapes & SVG, UI Components, Forms & Inputs, Colour.
Related tools
Breakpoint Helper
Media query and container query boilerplate from a breakpoint.
Feature Grid Builder
Responsive icon-title-description feature grids for landing pages.
Masonry Grid Builder
Pinterest-style masonry layouts in pure CSS.
:has() Selector Builder
Pick a :has() pattern, see it work live and copy the HTML and CSS.
Cascade Layers Generator
Set your @layer order and get the blocks or imports to paste.