Fylgja Bento Grid
A bento grid arranges cards of different sizes into one tidy
block, like the compartments of a bento box. It suits feature overviews and
landing pages, where one tile leads and smaller ones support it. The grid is a
plain <ul>, so the tiles stay a real list for assistive tech.
Preview
-
Classless base
Native elements look right out of the box, so most markup needs no classes at all.
-
Design tokens
Colors, shadows, and easings as CSS variables you can pick from.
-
Utilities
Layout helpers driven by variables.
-
No build step
Import the CSS and go.
-
Pick what you need
Every package works on its own, so you only ship the parts your project uses.
<ul role="list" class="grid-cols gap" style="--sm_grid-cols: 2; --md_grid-cols: 4">
<li class="card flex-col" style="--sm_col: span 2; --md_row: span 2">
<img
src="/images/placeholders/deer-wide.webp"
alt="A deer standing in a misty forest"
width="960"
height="640"
loading="lazy"
class="object-cover w-full flex-auto"
style="--size-y: 12rem"
/>
<div class="card-content">
<h3 class="lead">Classless base</h3>
<p>Native elements look right out of the box, so most markup needs no classes at all.</p>
</div>
</li>
<li class="card" style="--sm_col: span 2">
<h3 class="lead">Design tokens</h3>
<p>Colors, shadows, and easings as CSS variables you can pick from.</p>
</li>
<li class="card">
<h3 class="lead">Utilities</h3>
<p>Layout helpers driven by variables.</p>
</li>
<li class="card">
<h3 class="lead">No build step</h3>
<p>Import the CSS and go.</p>
</li>
<li class="card" style="--sm_col: span 2; --md_col: span 4">
<h3 class="lead">Pick what you need</h3>
<p>Every package works on its own, so you only ship the parts your project uses.</p>
</li>
</ul>Usage
- Wrap the tiles in a
<ul role="list" class="grid-cols gap">. The grid starts at one column, and--sm_grid-colsand--md_grid-colsadd columns from those breakpoints up. - Make each tile a
<li class="card">. Set--color--rowto a span (for examplespan 2) to size it, with a breakpoint prefix such as--md_rowso the span only applies once there are enough columns. - Plan each row so its spans add up to the column count. Here the four column grid has a lead tile two columns wide and two rows tall, and a full width tile closes it off.
- For a tile with an image, make the card
flex-coland give the imageflex-autoandobject-cover, so it fills whatever height the row span gives it. Put the text in a.card-contentwrapper.
Anatomy
| Part | Responsibility |
|---|---|
<ul class="grid-cols gap"> |
The grid, with the column count per breakpoint. |
<li class="card"> |
A tile, sized with --col and --row spans. |
.card-content |
Padding wrapper for the text when the tile has media. |
Accessibility
- Keep the visual order and the source order the same. Reordering tiles with grid placement makes keyboard and screen reader order jump around the page.
- Give each tile a real heading so it shows up in the document outline.
- Give images a descriptive
alt, oralt=""when they are purely decorative.
Related: Card, Gallery, Product Grid.
FAQ
How do I make a tile wider or taller?
Set --col or --row on the tile to a grid span, such as span 2. Prefix the variable with a breakpoint (--sm_col, --md_row) to apply the span only from that screen size up, which keeps every tile full width on phones.
Why does the grid start with one column?
grid-cols defaults to a single column. The --sm_grid-cols and --md_grid-cols variables add columns as the screen grows, so small screens get a simple stack without any media queries in your markup.
Why is there a gap in my grid?
Grid places tiles in source order, so a wide tile that does not fit at the end of a row moves down and leaves a hole. Make the spans in each row add up to the column count, or reorder the tiles.
Should I use auto-grid instead?
Use auto-grid when every item is the same size and the column count should follow the width. A bento grid needs a fixed column count, because spans only line up when you know how many columns there are.