
Un Bento box (🍱) è il famoso porta pranzo giapponese che mantiene separati in modo ordinate le diverse pientanze preparate. Portare a scuola un bento pronto è un gesto d’affetto nei confronti di chi lo riceve e la cura con cui i diversi piatti vengono organizzati e mostrati, oltre alla qualità del cibo naturalmente, rappresentano quanto quella persona ti sta a cuore.
Da questa usanza e dal design minimalista, equilibrato e funzionale di questo peculiare oggetto è nato un trend nel UX/UI chiamato proprio Bento Layout (o Bento Box Layout) che sarà l’oggetto di questo tutorial: non riso, carotine o wurstel a forma di polipo ma moderno HTML e CSS saranno i nostri ingredienti, ma la cura e quindi l’affetto con cui sono combinati è la stessa!
La base
Per il nostro esperimento vogliamo partire da una base piuttosto semplice ma estremamente comune: abbiamo un main
che contiene diversi elementi section
con al loro interno article
ognuno con un suo header
ed una immagine all’interno di un elemento semantico figure
:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
<title>🍱 Bento Box Design Layout with Modern CSS</title>
</head>
<body>
<main>
<section class="bento">
<article>
<header>
<h2>Box 1</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
</header>
<figure>
<img src="./images/0.png" alt="ai generated anime picture">
</figure>
</article>
<!-- 7 more articles here -->
</section>
</main>
</body>
</html>
Code language: HTML, XML (xml)
Useremo CSS moderno (Baseline) per rendere responsive la nostra base avendo un approccio mobile-first:
:root {
font-family: system-ui, sans-serif;
font-size: clamp(14px, 5vw, 20px);
--dark-color: #5c6378ff;
--light-color: #edf2f4ff;
--background-color: #2b2d42ff;
--secondary-color: #757e93ff;
--antiflash-white: #edf2f4ff;
--important-color: #ef233cff;
--fire-engine-red: #d90429ff;
}
body {
background-color: var(--background-color);
color: var(--light-color);
margin: 0;
}
article {
background-color: var(--light-color);
color: var(--dark-color);
padding: 1rem;
margin-bottom: 1rem;
}
article figure {
margin: 0;
}
img {
display: block;
width: 100%;
}
main {
width: 90%;
max-width: 1200px;
margin-inline: auto;
padding-block-start: 2rem;
}
Code language: CSS (css)

Per sperimentare con un layout bento aggiungiamo qualche articolo ed osserviamo che di default, se ci limitiamo a pochi cambiamenti nel foglio di stile, i nostri elementi html appariranno accessibili e perfettamente fruibili: less is more in CSS 🍣
Bento con grid layout
La tecnica ideale per un layout modulare fatto di contenitori è impostare la proprietà css display
delle nostre section
a grid
ma per poter giocare con la posizione e la forma degli articoli avremo qualche accorgimento aggiuntivo che ci verrà comodo in seguito.
.bento {
--bento-cols: 5;
--bento-rows: 3;
--bento-border-radius: 1rem;
--bento-gap: 1rem;
display: grid;
grid-template-columns: repeat(var(--bento-cols), 1fr);
grid-template-rows: repeat(var(--bento-rows), 1fr);
width: 100%;
aspect-ratio: var(--bento-cols) / var(--bento-rows);
}
.bento>* {
overflow: hidden;
position: relative;
margin: calc(var(--bento-gap) / 2);
border-radius: var(--bento-border-radius);
}
@media screen and (aspect-ratio < 1) {
.bento {
--bento-cols: 3;
--bento-rows: 5;
}
}
Code language: CSS (css)
Abbiamo introdotto alcune variabili per controllare il numero di colonne e di righe. Utilizzeremo questi due valori per impostare in quante frazioni dividere la mia “griglia bento” e poter calcolare la proprietà aspect-ratio
cioè in che rapporto sono larghezza e altezza. Questo piccolo trucco ninja ci permette di avere delle celle esattamente quadrate e sarà questa la chiave della nostra strategia!

Affinchè i miei article
siano contenuti nelle celle abbiamo aggiunto la regola overflow: hidden
.
Per mantenere l’elasticità del nostro design è importante non usare la proprietà gap
della grid
perché questo rompe il rapporto tra altezza e larghezza totali e i moduli (gli elementi nel nostro bento non sono più esattamente quadrati). Sfrutteremo il margin
dei contenuti per distanziare gli alimenti/elementi del nostro bento.
Personalizza il tuo bento design
Finalmente arriva la parte più divertente e specifica di questo tutorial! Personalizziamo il nostro bento box decidendo di quante celle si “allarga” un elemento: usando un valore span 2
sulle proprietà grid-colum
o grid-row
possiamo ottenere moduli orizzontali (2×1 celle) e verticali (1×2 celle) e combinandoli otteniamo una cella grande quadrata (2×2 celle).
Siamo pronti a specificare così che forma (e importanzà) avranno i nostri article
in base all’ordine in cui sono nella section
: aggiungiamo una classe layout-1
che sarà il nostro template riusabile ed il gioco è fatto!
.bento.layout-1> :nth-child(1) {
grid-column: span 2;
grid-row: span 2;
background-color: var(--important-color);
color: var(--light-color);
}
.bento.layout-1> :nth-child(2) {
grid-row: span 2;
background-color: var(--secondary-color);
color: var(--light-color);
}
.bento.layout-1> :nth-child(3),
.bento.layout-1> :nth-child(4),
.bento.layout-1> :nth-child(8) {
grid-column: span 2;
background-color: var(--dark-color);
color: var(--light-color);
}
.bento.layout-1> :nth-child(n + 9) {
display: none;
}
Code language: CSS (css)

Bento Layout verticale
Su uno schermo verticale potremmo dover riarrangiare il nostro bento layout. Cogliamo questa opportunità per creare un layout specifico invertendo il numero di colonne e righe e reimpostando i nostri moduli perché abbiano un equilibrio su display verticali.

@media screen and (aspect-ratio < 1) {
.bento.layout-1 {
--bento-cols: 3;
--bento-rows: 5;
}
.bento.layout-1> :nth-child(n) {
/* Reset spans */
grid-column: auto;
grid-row: auto;
}
.bento.layout-1> :nth-child(1),
.bento.layout-1> :nth-child(8) {
grid-column: span 2;
grid-row: span 2;
}
.bento.layout-1> :nth-child(5) {
grid-column: span 2;
}
.bento.layout-1> :nth-child(7) {
grid-column: 1;
grid-row: 5;
}
}
Code language: CSS (css)
Bento box layout e container queries
Ed ora il piatto forte del nostro bento layout: usiamo le container query per dare un design specifico ad ogni article
!
Prima di personalizzare i singoli format dei nostri elementi prepariamo una base comune che ci faciliti il lavoro:
.bento>* {
display: flex;
flex-direction: column-reverse;
}
.bento.layout-1 h1, .bento.layout-1 h2, .bento.layout-1 h3, .bento.layout-1 p {
margin: 0;
}
.bento.layout-1>* figure {
position: absolute;
inset: 0;
}
.bento.layout-1>* header {
position: relative;
z-index: 1;
background-color: inherit;
}
.bento.layout-1>* figure img {
object-fit: cover;
height: 100%;
}
.bento.layout-1>* header {
position: absolute;
bottom: 0;
inset-inline: 0;
border-radius: 0;
font-size: 70%;
padding: 0.5rem;
}
Code language: CSS (css)
Aggiungiamo finalmente le proprietà CSS container-type
e container-name
per dare al contenuto dei nostri bento layout il super potere di fare query sulle proprietà come width
, height
e, super importante, aspect-ratio
!
.bento > * {
container-type: size;
container-name: bento-item;
}
Code language: CSS (css)
Completiamo il nostro bento design caratterizzando i diversi formati in cui dovrà apparire ogni articolo. Per farlo possiamo valutare le dimensioni (e quindi nascondere alcuni elementi) ma anche le proporzioni: il mio contenitore sarà quadrato, verticale o orizzontale? Avrà abbastanza spazio per tutto?
Scopriamolo con le container queries:
@container bento-item (width < 200px) and (height < 200px) {
.bento.layout-1>* header {
font-size: 0.7rem;
}
.bento.layout-1>* header p {
display: none;
}
}
@container bento-item (aspect-ratio > 1) {
.bento.layout-1>* header {
top: 0;
right: 60%;
}
.bento.layout-1> * figure {
inset: 0 0 0 40%;
}
}
@container bento-item (aspect-ratio = 1) and (width > 200px) {
.bento.layout-1>* header {
font-size: 120%;
background-color: #0006;
color: var(--light-color);
backdrop-filter: blur(4px);
}
}
Code language: CSS (css)

Micro-animazioni
Per dare vita al nostro bento layout, aggiungiamo delle micro-animazioni sottili ma efficaci. Le animazioni rendono l’interfaccia più dinamica e piacevole, mantenendo sempre un approccio minimalista che rispecchia la filosofia del design bento.
Prima di tutto, aggiungiamo una transizione fluida a tutti gli elementi del bento:
.bento > * {
transition: transform 0.3s ease-out, filter 0.3s ease-out;
}
Code language: CSS (css)
Creiamo un effetto di hover che solleva leggermente l’elemento e aggiunge una sottile ombra:
.bento > *:hover {
transform: translateY(-0.5rem);
filter: drop-shadow(0 0.5rem 0.1rem #0009);
}
Code language: CSS (css)
Per le immagini, possiamo aggiungere un leggero effetto di zoom unito ad un movimento verso il basso ottenendo una sorta di movimento di camera (come un dolly):
.bento.layout-1 > * figure img {
transition: transform 1s;
}
.bento.layout-1 > *:hover figure img {
transform: scale(1.50) translateY(15%);
}
Code language: CSS (css)

Ricordiamoci di rispettare le preferenze di accessibilità dell’utente disabilitando le animazioni se prefers-reduced-motion
è attivato nel browser:
@media (prefers-reduced-motion: reduce) {
.bento > *,
.bento.layout-1 > * header,
.bento.layout-1 > * figure img {
transition: none;
}
.bento > *:hover {
transform: none;
}
.bento.layout-1 > *:hover figure img {
transform: none;
}
}
Code language: CSS (css)
Conclusioni
In questo tutorial abbiamo esplorato come creare un moderno Bento Box Layout utilizzando CSS contemporaneo. Partendo dalla filosofia del bento giapponese, abbiamo costruito un’interfaccia modulare usando:
- CSS Grid per la struttura base con
span
nelle proprietàgrid-column
egrid-row
per creare i moduli di diverse taglie aspect-ratio
obblicare la griglia a mantenere le proporzioni quadrate dei moduli- Container Queries per adattare il contenuto ai diversi contenitori
- Media Queries per avere il controllo di layout verticali
- Micro-animazioni per dare vita all’interfaccia
La bellezza di questo approccio sta nella sua flessibilità: come un vero bento box, possiamo organizzare i nostri contenuti in infinite combinazioni mantenendo sempre ordine ed equilibrio. Abbiamo visto come le moderne funzionalità CSS ci permettono di creare layouts complessi ma mantenibili, responsive ma precisi, dinamici ma accessibili.
Il codice di questo tutorial è pensato per essere un punto di partenza: vi invito a sperimentare per trovare le ricette giuste per il vostro speciale bento.
Buon appetito!