> Markdown version of [/magazine/682-building-a-bento-grid-layout-with-modern-css-grid](https://www.wearedevelopers.com/magazine/682-building-a-bento-grid-layout-with-modern-css-grid). Every page supports `.md` or `Accept: text/markdown`. Links point to the HTML versions so they work for humans too. Agent guide: [/agents.md](https://www.wearedevelopers.com/agents.md). --- # Building a Bento Grid Layout with Modern CSS Grid **By:** [Daniel Cranney](https://www.wearedevelopers.com/@daniel-cranney) **Published:** January 29, 2026 Even if you haven’t heard the term _bento_ before, you’ve almost certainly seen a bento layout on the web in recent years. The name, taken from traditional Japanese bento meals where different dishes are neatly separated into compartments, reflects how bento layouts are made up of distinct sections arranged in boxes of varying sizes, with dense yet aesthetically appealing grids. They seem complex, but CSS grid makes building them surprisingly simple, and in this article we’ll explore some of the features and syntax that make it so powerful. There are two demos for this article, and you can find [all of the code featured over on our GitHub](https://github.com/WeAreDevelopers-com/bento-with-css-grid). In the first example, we’ll use the `span` keyword with utility classes and let gvrid’s auto-placement handle positioning. In the second example, we’ll use explicit line positioning (`1 / 7` syntax) to precisely control where each tile appears. Both demonstrate different CSS Grid techniques for achieving the same result. ## Setting Up the Grid Both approaches start with the same foundation, a 12-column grid system. To start with, we’ll set up the basic rules of our grid: It’s a grid, with 1rem of spacing between items, with twelve equal columns, and a minimum row height: .bento { display: grid; gap: 1rem; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-auto-rows: 90px; } The trickiest part here is `grid-template-columns...`, which creates 12 equal-width columns, gives each column 1/12th of the total width with `1fr` and lets it shrink below its content size down to `0`. Wrapping this in the `repeat(12, ...)` function applies this same sizing rule to all 12 columns. ## Approach 1: Auto-placement with `grid-auto-flow` ![Bento grid with auto-placement](https://wearedevelopers.imgix.net//magazine/articles/682/images/content/bkLvjLURqKzIIccGtknk-1769614958.png?w=984&auto=compress,format) Our [first approach](https://github.com/WeAreDevelopers-com/bento-with-css-grid/tree/main/demo1) uses utility classes to create tiles of varying sizes. We use `span` keyword to specify how many columns or rows a tile occupies without calculating grid line numbers, and then use `grid-auto-flow: dense`, to automatically place tiles and fill gaps. First, we set default sizing on the base `.tile` class: .tile { /* ...styling above here - padding, border-radius and background-color */ grid-column: span 3; grid-row: span 1; } Now, rather than defining the position of each tile, we’ll use one line of CSS magic to do it automatically With this, we can lay out the tiles and fill gaps with smaller ones that fit, even if they appear earlier in the HTML. _Note: We only recommend this if you do not require the tiles to be in a specific order._ .bento { grid-auto-flow: dense; } Next, we create utility classes that override the default sizing. Here’s an example: .tile-6x2 { grid-column: span 6; grid-row: span 2; background: #ec4899; } The `span` keyword makes it easy to control sizing: `grid-column: span 6` means “span 6 columns of 12” without needing to know the exact grid line numbers. When you add these utility classes to tiles (e.g., `class="tile tile-6x2"`), they override the default sizing, and grid’s auto-placement handles the rest. Our HTML looks like this: <article class="tile tile-6x2"> <h2>6 Cols × 2 Rows</h2> <p>Class: tile-6x2</p> </article> <article class="tile"> <h2>3 Cols × 1 Row</h2> <p>Default tile size</p> </article> You can create as many utility classes as needed, `.tile-6x1`, `.tile-3x2`, `.tile-9x1` and `dense` will make them fit as efficiently as possible. Finally, [see this approach in action](https://wearedevelopers-com.github.io/bento-with-css-grid/demo1/index.html). ## Approach 2: Specific Positioning with `grid-column` and `grid-row` In [our second approach](https://github.com/WeAreDevelopers-com/bento-with-css-grid/tree/main/demo2), we don’t use `dense`, and instead we pre-define the exact layout in our CSS using the `:nth-child()` pseudo-class. This positions tiles based on their order in the HTML, and gives us maximum control: .tile:nth-child(1) { grid-column: 1 / 7; grid-row: 1 / 3; } /* ... */ Here, `grid-column: 1 / 7` uses explicit line numbers, starting at grid line 1 and end at grid line 7 (spanning 6 columns), with the same approach for rows. This approach gives you complete control over the layout, but it’s less flexible: if you add or remove tiles, you might need to update the `:nth-child()` selectors, but it’s great when you want to fix your bento layout in place. Now, [check out this approach](https://wearedevelopers-com.github.io/bento-with-css-grid/demo2/index.html) on our demo page. ## Conclusion Both approaches create beautiful bento layouts while showcasing different CSS Grid techniques. With `grid-auto-rows` you can automatically-create layouts by combining it with utility classes, and define complex layouts with `grid-column` and `:nth-child`. Be sure to take a look at the GitHub, you can see how we made this responsive so that your complex bento adapts beautifully to different screen sizes. ## Related Articles - [The Overflow: 5 CSS Generators and Visual Design Tools](https://www.wearedevelopers.com/magazine/708-the-overflow-5-css-generators-and-visual-design-tools) - [Declarative Design and a fresh take on collaboration with developers](https://www.wearedevelopers.com/magazine/595-declarative-design-and-a-fresh-take-on-collaboration-with-developers) - [Creating a 3D Card Fan with CSS Transforms](https://www.wearedevelopers.com/magazine/656-creating-a-3d-card-fan-with-css-transforms) - [Tether Elements Without JavaScript with CSS Anchor Positioning](https://www.wearedevelopers.com/magazine/714-tether-elements-without-javascript-with-css-anchor-positioning) ## Related Videos - [Kirsty's Excellent Adventure in CSS Grid ](https://www.wearedevelopers.com/videos/126-kirsty-s-excellent-adventure-in-css-grid) - [What's new in CSS for Designers?](https://www.wearedevelopers.com/videos/835-what-s-new-in-css-for-designers) - [Level up your Angular CSS with Tailwind CSS](https://www.wearedevelopers.com/videos/640-level-up-your-angular-css-with-tailwind-css) - [Level up your Angular CSS with Tailwind CSS](https://www.wearedevelopers.com/videos/366-level-up-your-angular-css-with-tailwind-css) ## Related Jobs - [Senior Software Engineer, Angular (B2C Web Platform)](https://www.wearedevelopers.com/jobs/ext/1927757-senior-software-engineer-angular-b2c-web-platform) at **Bitpanda** - [Senior Software Engineer, React (Websites & Martech)](https://www.wearedevelopers.com/jobs/ext/1605272-senior-software-engineer-react-websites-martech) at **Bitpanda** - [Software Engineer, React & Angular (Broker Web Platform](https://www.wearedevelopers.com/jobs/ext/1558399-software-engineer-react-angular-broker-web-platform) at **Bitpanda** - [Software Engineer](https://www.wearedevelopers.com/jobs/ext/1304673-software-engineer) at **Bitpanda** - [Senior Software Engineer, React (Investing & Trading)](https://www.wearedevelopers.com/jobs/ext/1937625-senior-software-engineer-react-investing-trading) at **Bitpanda** - [Junior Frontend Engineer](https://www.wearedevelopers.com/jobs/ext/1532351-junior-frontend-engineer) at **Almedia**