Il layout Masonry è il classico effetto “a mattoncini” usato in tante gallery fotografiche, portfolio creativi, card di blog, sezioni recensioni o layout in stile Pinterest: gli elementi non hanno tutti la stessa altezza, ma si dispongono uno sotto l’altro cercando di occupare lo spazio nel modo più compatto possibile.
Il risultato è dinamico, meno rigido della classica griglia a colonne tutte uguali, e visivamente molto interessante. Soprattutto quando abbiamo contenuti con altezze diverse: immagini verticali e orizzontali, testi più lunghi e più brevi, card di portfolio, anteprime di articoli o box informativi.
La domanda però è sempre la stessa:
si può creare un layout masonry solo con il CSS, senza JavaScript?
La risposta breve è: sì, si può ottenere un effetto masonry solo con CSS.
La risposta più precisa, però, è leggermente più interessante: oggi possiamo creare un effetto masonry molto convincente usando CSS puro, soprattutto con il layout multi-column. Il vero masonry nativo CSS, invece, è ancora una tecnologia da trattare con attenzione, perché il supporto tra browser non è ancora uniforme. MDN, infatti, definisce il masonry layout come una tecnologia sperimentale e non ancora “Baseline”, quindi da verificare bene prima di usarla in produzione.
In questo articolo vediamo quindi una soluzione concreta, leggera e utilizzabile già oggi.
Cos’è un layout Masonry?
Un layout masonry è una griglia in cui gli elementi vengono disposti in colonne, ma senza l’obbligo di rispettare righe perfettamente allineate.
In una griglia tradizionale, se una card è più alta delle altre, lascia spesso degli spazi vuoti sotto gli elementi più corti. Nel masonry, invece, gli elementi successivi “risalgono” per riempire quegli spazi.
È un layout molto utile quando i contenuti non hanno tutti la stessa altezza.
Per esempio:
- portfolio di lavori;
- gallery fotografiche;
- griglie di articoli del blog;
- sezioni recensioni;
- card prodotto;
- raccolte di risorse;
- pagine ispirazionali;
- layout editoriali meno rigidi.
Dal punto di vista del design, il masonry comunica movimento, varietà e naturalezza. Non è perfetto per ogni caso, ma quando viene usato bene rende una pagina più viva.
Perché molti usano JavaScript per il Masonry?
Storicamente, per creare un vero layout masonry si è usato spesso JavaScript.
Il motivo è semplice: JavaScript può misurare l’altezza degli elementi, calcolare lo spazio disponibile e posizionare ogni card nel punto più adatto.
Librerie come Masonry.js sono nate proprio per questo: prendere elementi di altezza diversa e distribuirli automaticamente all’interno di una griglia compatta.
Il problema è che JavaScript aggiunge complessità.
Non sempre è un problema, sia chiaro. In certi casi è la scelta migliore. Ma per un sito vetrina, un portfolio semplice o una gallery non troppo complessa, usare una libreria solo per ottenere un effetto visivo può essere eccessivo.
Vuol dire aggiungere:
- un file JavaScript in più;
- logica da mantenere;
- possibili problemi al caricamento delle immagini;
- possibili ricalcoli del layout;
- maggiore dipendenza da librerie esterne;
- più attenzione alle performance.
Per questo, quando possibile, conviene chiedersi:
posso ottenere un risultato simile solo con CSS?
In molti casi sì.
La soluzione pratica: CSS Multi-column
Il modo più semplice per ottenere un effetto masonry solo con CSS è usare il layout multi-column.
Il modulo CSS multi-column permette di dividere un contenuto in più colonne, controllando larghezza, numero delle colonne, spazio tra colonne e comportamento delle interruzioni.
La logica è questa: invece di creare una griglia con display: grid, diciamo al contenitore di distribuire i suoi elementi in colonne.
Poi, su ogni card, usiamo break-inside: avoid; per evitare che il singolo elemento venga spezzato tra una colonna e l’altra. La proprietà break-inside, infatti, controlla il comportamento delle interruzioni all’interno di un box ed è ampiamente supportata nei browser moderni.
Ecco il concetto base:
.masonry {
columns: 3 280px;
column-gap: 24px;
}
.masonry-card {
break-inside: avoid;
margin-bottom: 24px;
}
Con pochissime righe abbiamo già una struttura molto simile a un masonry.
Esempio HTML completo
Partiamo da un markup molto semplice.
Immaginiamo di voler creare una sezione con alcune card. Può essere una sezione portfolio, una gallery, una lista di articoli o una raccolta di progetti.
<section class="masonry-section">
<div class="masonry-intro">
<p class="masonry-eyebrow">Portfolio</p>
<h2>Una griglia masonry realizzata solo con CSS</h2>
<p>
Un esempio semplice di layout fluido, responsive e leggero,
senza utilizzare JavaScript.
</p>
</div>
<div class="masonry-grid">
<article class="masonry-card">
<img src="immagine-1.jpg" alt="Anteprima del progetto uno">
<div class="masonry-card-content">
<h3>Progetto creativo</h3>
<p>
Una card breve, ideale per mostrare un lavoro grafico,
una landing page o una piccola anteprima di portfolio.
</p>
</div>
</article>
<article class="masonry-card">
<img src="immagine-2.jpg" alt="Anteprima del progetto due">
<div class="masonry-card-content">
<h3>Sito WordPress</h3>
<p>
Questa card contiene un testo leggermente più lungo. In un layout
masonry non è necessario che tutti gli elementi abbiano la stessa
altezza: anzi, la varietà è proprio ciò che rende il layout più
interessante dal punto di vista visivo.
</p>
</div>
</article>
<article class="masonry-card">
<img src="immagine-3.jpg" alt="Anteprima del progetto tre">
<div class="masonry-card-content">
<h3>Restyling homepage</h3>
<p>
Una card compatta per presentare un intervento di restyling.
</p>
</div>
</article>
<article class="masonry-card">
<img src="immagine-4.jpg" alt="Anteprima del progetto quattro">
<div class="masonry-card-content">
<h3>Landing page</h3>
<p>
Le landing page spesso hanno bisogno di sezioni leggere, modulari
e facilmente adattabili ai diversi dispositivi. Un layout di questo
tipo può essere utile per mostrare blocchi di contenuto con
lunghezze differenti.
</p>
</div>
</article>
<article class="masonry-card">
<img src="immagine-5.jpg" alt="Anteprima del progetto cinque">
<div class="masonry-card-content">
<h3>Gallery fotografica</h3>
<p>
Perfetto anche per immagini verticali e orizzontali.
</p>
</div>
</article>
<article class="masonry-card">
<img src="immagine-6.jpg" alt="Anteprima del progetto sei">
<div class="masonry-card-content">
<h3>Blog layout</h3>
<p>
Un effetto masonry può essere usato anche per rendere più dinamica
una pagina archivio o una selezione di articoli in evidenza.
</p>
</div>
</article>
</div>
</section>
La struttura è volutamente pulita:
- una sezione principale;
- un blocco introduttivo;
- un contenitore per la griglia;
- una serie di card;
- immagine, titolo e testo per ogni elemento.
Questo è un markup facilmente adattabile anche a WordPress, GenerateBlocks, Elementor o a un tema custom.
Il CSS per creare il layout Masonry
Adesso passiamo al CSS.
.masonry-section {
padding: 80px 20px;
background: #f7f7f5;
}
.masonry-intro {
max-width: 760px;
margin: 0 auto 48px;
text-align: center;
}
.masonry-eyebrow {
margin-bottom: 12px;
font-size: 0.85rem;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
color: #666;
}
.masonry-intro h2 {
margin: 0 0 18px;
font-size: clamp(2rem, 4vw, 3.4rem);
line-height: 1.05;
color: #121212;
}
.masonry-intro p {
margin: 0;
font-size: 1.05rem;
line-height: 1.7;
color: #555;
}
.masonry-grid {
max-width: 1180px;
margin: 0 auto;
columns: 3 280px;
column-gap: 24px;
}
.masonry-card {
display: inline-block;
width: 100%;
margin: 0 0 24px;
break-inside: avoid;
overflow: hidden;
border-radius: 22px;
background: #ffffff;
box-shadow: 0 18px 45px rgba(0, 0, 0, 0.08);
}
.masonry-card img {
display: block;
width: 100%;
height: auto;
}
.masonry-card-content {
padding: 24px;
}
.masonry-card h3 {
margin: 0 0 12px;
font-size: 1.25rem;
line-height: 1.2;
color: #121212;
}
.masonry-card p {
margin: 0;
font-size: 0.98rem;
line-height: 1.65;
color: #555;
}
Con questo CSS otteniamo un layout responsive senza dover scrivere media query complesse.
La riga più importante è questa:
columns: 3 280px;
Significa: crea fino a 3 colonne, cercando di mantenere una larghezza ideale di circa 280px.
Il browser adatterà automaticamente il numero di colonne in base allo spazio disponibile. Su desktop potremo avere tre colonne, su tablet due, su smartphone una.
Poi abbiamo:
column-gap: 24px;
che gestisce lo spazio orizzontale tra le colonne.
E infine:
break-inside: avoid;
che evita che una card venga spezzata tra due colonne.
Senza questa proprietà, in alcuni casi il browser potrebbe interrompere il contenuto di una card e continuarlo nella colonna successiva. Per una card di portfolio o di blog sarebbe un effetto pessimo.
Perché display: inline-block?
Nel CSS della card ho inserito:
display: inline-block;
width: 100%;
Questo aiuta ogni card a comportarsi come un blocco completo all’interno del flusso multi-column.
In pratica diciamo alla card:
occupi tutta la larghezza della colonna, ma resti dentro il comportamento del layout a colonne.
È una piccola accortezza che rende il risultato più stabile.
Versione ancora più semplice
Se vuoi ridurre tutto all’essenziale, il layout masonry può essere ottenuto anche così:
.masonry-grid {
columns: 3 280px;
column-gap: 24px;
}
.masonry-card {
display: inline-block;
width: 100%;
margin-bottom: 24px;
break-inside: avoid;
}
Questo è il cuore tecnico della soluzione.
Tutto il resto — colori, ombre, border radius, padding, tipografia — serve solo a rendere le card più belle.
Una variante per immagini senza testo
Se vuoi creare una gallery fotografica pura, senza titoli e descrizioni, puoi semplificare ancora di più.
HTML:
<div class="photo-masonry">
<figure>
<img src="foto-1.jpg" alt="Descrizione della foto 1">
</figure>
<figure>
<img src="foto-2.jpg" alt="Descrizione della foto 2">
</figure>
<figure>
<img src="foto-3.jpg" alt="Descrizione della foto 3">
</figure>
<figure>
<img src="foto-4.jpg" alt="Descrizione della foto 4">
</figure>
</div>
CSS:
.photo-masonry {
columns: 4 220px;
column-gap: 18px;
}
.photo-masonry figure {
display: inline-block;
width: 100%;
margin: 0 0 18px;
break-inside: avoid;
overflow: hidden;
border-radius: 18px;
}
.photo-masonry img {
display: block;
width: 100%;
height: auto;
}
Questa versione è perfetta per una gallery semplice.
Molto leggera, molto pulita, zero JavaScript.
Posso usarlo in WordPress?
Sì, tranquillamente.
In WordPress puoi usare questa tecnica in diversi modi.
Per esempio, se usi GenerateBlocks, puoi creare un container esterno e assegnargli una classe personalizzata, per esempio:
sergio-masonry
Poi alle singole card puoi dare una classe tipo:
sergio-masonry-card
A quel punto il CSS diventa:
.sergio-masonry {
columns: 3 280px;
column-gap: 24px;
}
.sergio-masonry-card {
display: inline-block;
width: 100%;
margin-bottom: 24px;
break-inside: avoid;
}
Questa è una soluzione molto comoda perché non ti obbliga a modificare il tema o a creare template particolari.
Puoi inserirla:
- nel CSS aggiuntivo di WordPress;
- nel CSS del tema child;
- in uno snippet CSS;
- nel pannello di personalizzazione del tema;
- in un blocco HTML personalizzato, se stai facendo una demo;
- in una sezione costruita con GenerateBlocks o Elementor.
Naturalmente, se il layout viene generato da un loop dinamico — per esempio articoli del blog, custom post type o portfolio — bisogna controllare le classi prodotte dal tema o dal page builder.
Ma il principio resta lo stesso: il contenitore gestisce le colonne, le card evitano di spezzarsi.
I vantaggi di un Masonry solo CSS
Il vantaggio principale è la leggerezza.
Non dobbiamo caricare librerie esterne, non dobbiamo aspettare che JavaScript calcoli le altezze, non dobbiamo gestire eventi di resize o ricaricamenti dopo il caricamento delle immagini.
Per molte situazioni reali, questo è già tantissimo.
Un layout masonry solo CSS è interessante perché:
- è leggero;
- è semplice da mantenere;
- non richiede dipendenze JavaScript;
- funziona bene per contenuti statici o semi-statici;
- è facile da integrare in WordPress;
- è naturalmente responsive;
- riduce il rischio di layout shift causati da script;
- migliora la pulizia del codice.
Per un sito vetrina, un portfolio personale o una gallery editoriale, spesso è più che sufficiente.
E per un Web Designer questo è un ragionamento importante: non sempre la soluzione più potente è la soluzione migliore. A volte la soluzione migliore è quella più semplice, più stabile e più proporzionata al problema.
I limiti della soluzione con CSS columns
Detto questo, bisogna essere onesti: la tecnica con columns non è un vero masonry perfetto.
Funziona molto bene dal punto di vista visivo, ma ha alcuni limiti.
Il primo limite riguarda l’ordine degli elementi.
Con il layout multi-column, gli elementi scorrono dall’alto verso il basso nella prima colonna, poi passano alla colonna successiva. Questo può creare un ordine visivo diverso da quello che ci aspetteremmo in una griglia classica da sinistra verso destra.
Per una gallery fotografica di ispirazione può non essere un problema. Per una lista di articoli ordinati cronologicamente, invece, può diventare più delicato.
Il secondo limite riguarda il controllo preciso della posizione.
Con JavaScript possiamo decidere meglio dove finiscono gli elementi. Con CSS columns lasciamo che sia il browser a distribuire il contenuto secondo il comportamento delle colonne.
Il terzo limite riguarda alcune interazioni avanzate.
Se vuoi filtri animati, ordinamenti dinamici, caricamento progressivo, drag and drop o transizioni complesse, probabilmente una soluzione JavaScript resta più adatta.
Quindi il punto non è dire che CSS sia sempre meglio di JavaScript.
Il punto è capire quando JavaScript è davvero necessario.
Quando usare questa soluzione CSS?
Io userei questa tecnica in questi casi:
- gallery fotografiche semplici;
- portfolio con card di altezza variabile;
- sezione recensioni;
- raccolte di risorse;
- blocchi editoriali;
- homepage con card decorative;
- layout di ispirazione;
- pagine statiche o semi-statiche;
- siti WordPress dove vuoi evitare plugin aggiuntivi.
La userei soprattutto quando l’obiettivo è ottenere un effetto visivo piacevole senza costruire una logica complessa.
Per esempio, in un portfolio personale ha molto senso.
Hai diversi progetti, magari alcuni con descrizioni più lunghe e altri con descrizioni più brevi. Invece di forzare tutte le card alla stessa altezza, puoi lasciare che il layout respiri.
Il risultato sembra meno rigido e più naturale.
Quando invece è meglio usare JavaScript?
JavaScript diventa più indicato quando il layout deve essere davvero controllato.
Per esempio:
- griglie con filtri per categoria;
- ordinamenti dinamici;
- animazioni al cambio filtro;
- caricamento infinito;
- contenuti caricati via AJAX;
- ecommerce con molte card prodotto;
- layout dove l’ordine visivo deve essere precisissimo;
- progetti dove il comportamento masonry deve essere identico su tutti i browser.
In questi casi, una libreria JavaScript può avere ancora senso.
Non bisogna demonizzare JavaScript. Bisogna solo evitare di usarlo quando non serve.
E il Masonry nativo CSS?
Qui la questione diventa interessante.
Il CSS sta andando verso un supporto nativo del masonry. MDN parla del masonry layout, noto anche come grid-lanes layout, accessibile tramite valori come display: grid-lanes e inline-grid-lanes. La stessa documentazione segnala però che si tratta di una funzionalità sperimentale e da controllare bene prima di usarla in produzione.
WebKit ha presentato CSS Grid Lanes come il futuro dei layout masonry sul web, mostrando una sintassi di questo tipo:
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
È una sintassi molto promettente, perché permetterebbe di creare un layout masonry in modo più naturale e potente rispetto al trucco con le colonne.
Il problema è il supporto.
Secondo Can I Use, ad aprile 2026 CSS Grid Lanes ha ancora una copertura globale molto bassa: risulta supportato in Safari 26.4 e versioni successive, mentre Chrome e Firefox lo hanno ancora disabilitato di default nelle versioni indicate.
Quindi, per un sito reale, oggi non baserei un layout importante solo su display: grid-lanes.
Molto meglio usare una strategia progressiva:
- soluzione stabile con
columns; - eventuale miglioramento futuro con
@supports; - niente rotture sui browser che non supportano ancora il masonry nativo.
Progressive enhancement: prepararsi al futuro
Una possibile strategia potrebbe essere questa:
.masonry-grid {
columns: 3 280px;
column-gap: 24px;
}
.masonry-card {
display: inline-block;
width: 100%;
margin-bottom: 24px;
break-inside: avoid;
}
@supports (display: grid-lanes) {
.masonry-grid {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
columns: initial;
}
.masonry-card {
display: block;
margin-bottom: 0;
}
}
L’idea è semplice: uso oggi una soluzione compatibile, ma preparo il codice per sfruttare il masonry nativo quando sarà più diffuso.
Questo approccio si chiama progressive enhancement.
In pratica: prima creo una base che funziona per tutti, poi aggiungo un miglioramento per i browser più moderni.
È un modo molto sano di lavorare sul web, perché evita di costruire siti fragili basati su funzionalità ancora poco supportate.
Attenzione alle immagini
Quando si crea un layout masonry con molte immagini, bisogna curare bene anche le performance.
Le immagini dovrebbero essere:
- compresse;
- ridimensionate correttamente;
- caricate nel formato giusto;
- dotate di attributo
alt; - possibilmente servite in formato moderno come WebP o AVIF;
- caricate in lazy loading quando non sono subito visibili.
Un esempio di immagine più curata potrebbe essere:
<img
src="progetto-web-design.webp"
alt="Anteprima di un progetto di web design responsive"
loading="lazy"
width="800"
height="1000"
>
Inserire width e height aiuta il browser a riservare lo spazio corretto prima che l’immagine venga caricata. Questo riduce il rischio di spostamenti improvvisi del layout durante il caricamento della pagina.
Su un layout masonry questa cosa è ancora più importante, perché immagini di dimensioni diverse possono rendere la pagina visivamente instabile se non vengono gestite bene.
Accessibilità: non dimentichiamola
Un layout bello non deve diventare un layout confuso.
Quando usiamo un effetto masonry, dobbiamo comunque mantenere una struttura HTML sensata.
Le card dovrebbero avere:
- titoli chiari;
- testi leggibili;
- link riconoscibili;
- immagini con
altdescrittivi; - ordine del DOM coerente;
- focus visibile da tastiera;
- buon contrasto tra testo e sfondo.
Un errore comune è pensare solo alla parte estetica.
Ma se il layout è bello e difficile da navigare, non è un buon layout.
Per esempio, se ogni card è cliccabile, possiamo strutturarla così:
<article class="masonry-card">
<a href="/portfolio/nome-progetto/" class="masonry-card-link">
<img src="progetto.jpg" alt="Anteprima del progetto Nome Progetto">
<div class="masonry-card-content">
<h3>Nome progetto</h3>
<p>Breve descrizione del lavoro realizzato.</p>
</div>
</a>
</article>
E poi nel CSS:
.masonry-card-link {
display: block;
color: inherit;
text-decoration: none;
}
.masonry-card-link:focus-visible {
outline: 3px solid #121212;
outline-offset: 4px;
}
Questo rende la card navigabile anche da tastiera.
Conclusione
Creare un layout masonry solo con CSS è possibile.
La soluzione più sicura e utilizzabile oggi è quella basata su CSS multi-column:
.masonry-grid {
columns: 3 280px;
column-gap: 24px;
}
.masonry-card {
display: inline-block;
width: 100%;
margin-bottom: 24px;
break-inside: avoid;
}
Con poche righe possiamo ottenere una griglia fluida, responsive e leggera, senza caricare librerie JavaScript.
Non è una soluzione perfetta per ogni caso. Se servono filtri dinamici, ordinamenti complessi o controllo totale della disposizione, JavaScript può essere ancora la scelta più corretta.
Ma per gallery, portfolio, sezioni editoriali e card visive, il masonry solo CSS è una soluzione concreta, elegante e molto più semplice di quanto sembri.
La cosa importante è non innamorarsi della tecnica in sé.
Il masonry non va usato perché “fa figo”.
Va usato quando aiuta il contenuto a respirare meglio, quando valorizza immagini e testi di dimensioni diverse, quando rende la pagina più dinamica senza appesantirla.
E questa, spesso, è la vera differenza tra aggiungere un effetto grafico e progettare davvero un’interfaccia.



