Masonry photo grid in pure CSS

This short article aims to show how it is possible to display a masonry photo grid only in HTML and CSS, without the help of Javascript, which remains elegantly aligned without being a too repetitive grid.


It may be achieved with a simple HTML markup:

<div class="gallery">
<div><img src="1.jpg" alt=""></div>
<div><img src="2.jpg" alt=""></div>
<div><img src="3.jpg" alt=""></div>
<div><img src="4.jpg" alt=""></div>
<div><img src="5.jpg" alt=""></div>
<div><img src="6.jpg" alt=""></div>
<div><img src="7.jpg" alt=""></div>
<div><img src="8.jpg" alt=""></div>
<div><img src="9.jpg" alt=""></div>


The trick is to use a flex display for the div, with a row wrap flow. Then, an object-fit: cover with overflow: hidden does the job. The tall and narrow class help to give more variation for vertical images:

@media only screen and (min-width: 550px) {
    .gallery {
        display: flex;
        width: 100%;
        flex-flow: row wrap;
        margin-left: -4px;

    .gallery div {
        overflow: hidden;
        margin: 0 0 8px 8px;
        flex: auto;
        height: 250px;
        min-width: 150px;

    .gallery div:nth-child(8n+1) {
        width: 310px;

    .gallery div:nth-child(8n+2) {
        width: 270px;

    .gallery div:nth-child(8n+3) {
        width: 260px;

    .gallery div:nth-child(8n+4) {
        width: 310px;

    .gallery div:nth-child(8n+5) {
        width: 240px;

    .gallery div:nth-child(8n+6) {
        width: 190px;

    .gallery div:nth-child(8n+7) {
        width: 210px;

    .gallery div:nth-child(8n+8) {
        width: 170px;

    .gallery div.wide {
        width: 650px;

    .gallery div.tall {
        width: 650px;
        height: 450px;

    .gallery div.narrow {
        width: 120px;

    .gallery img {
        object-fit: cover;
        width: 100%;
        height: 100%;

To have the images displayed in full screen at the click, you may consult the following article:

Image overlay in pure CSS