Creating CSS masonry-style layouts
Tags: css, webdev
Published: 2023-03-22 14:30:40

**Written by [Nwani Victory](https://blog.logrocket.com/author/nwanivictory/)✏️**

When designing a page with content overflowing the viewport, an indirect way to instruct users to keep scrolling is to display new content partially. One such approach is the masonry layout, which places elements inline and allows them to move up to fill empty spaces. 

Within this tutorial, we will explore the experimental masonry layout added to the [CSS Grid Level 3 Specification](https://blog.logrocket.com/css-grid-guide/). We will also consider other similar ways to replicate the masonry layout with CSS. 

Jump ahead:

*   [Understanding the masonry layout](#understanding-masonry-layout)
*   [Creating a sample masonry CSS project](#creating-sample-masonry-css-project)
*   [Adding initial styles to our CSS masonry project](#adding-initial-styles-css-masonry-project)
*   [Achieving a masonry layout with CSS grid’s experimental feature](#achieving-masonry-layout-css-grid-experimental-feature)
*   [Imitating a masonry layout using columns](#imitating-masonry-layout-columns)

Before you begin building, let’s take some time out to understand how the concept of masonry-style layouts came about.

## Understanding the masonry layout <a name="understanding-masonry-layout">

As its name suggests, the masonry layout has to do with the masonry craft in which workers called masons laid bricks to build concrete walls. 

In the practice of their craft, masons often stacked bricks using the stretcher bond pattern, meaning the bricks were staggered by half over each other. Besides its stability and aesthetic appeal, the stretcher bond pattern also reduced material waste, as there was no need to cut the bricks in half at every joint. 

When it comes to front-end development, the masonry layout has proven to be an effective way to display multiple items in a grid by partially revealing content. This layout has become widely adopted and popularized by platforms such as Pinterest. 

With no native [CSS grid support for masonry layouts](https://drafts.csswg.org/css-grid-3/#masonry-layout), developers relied on using libraries such as [Masonry.js](https://github.com/desandro/masonry) or [Brick.js](https://github.com/callmecavs/bricks.js/) to replicate this visual design. These libraries can accomplish masonry-style layouts without CSS by using JavaScript to manipulate the DOM, then placing each element within the appropriate spaces. 

However, these libraries were reported to have a drastic impact on performance. They had to make frequent expensive computations to find the available areas within the layout, resulting in a laggy scroll experience. 

Fast forward to more recent years — now that CSS specifications have improved and become more robust, can developers achieve masonry layouts using only CSS? Let’s explore how to create a masonry layout in CSS by building the feed page of a sample blog website.

## Creating a sample masonry CSS project <a name="creating-sample-masonry-css-project">

Let’s create a page to display the blog posts. Each post element will contain a cover image, title, and description as shown in the prototype below: ![Prototype Of Page Styled Using Css Masonry Layout With Element Tiles Represented With Grey Boxes And Lines](https://blog.logrocket.com/wp-content/uploads/2023/03/img1-CSS-masonry-layout-prototype.png) 

To get started, create a directory to store the HTML and CSS files for the website about to be built. 

Within your new directory, create an `index.html` file and add the contents of the code block below into the file. To make it easier to use, the images within the code have been remotely [stored within a bucket on Cloudinary](https://blog.logrocket.com/handling-images-with-cloudinary-in-react/):

```html
<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>CSS Masonry Playground</title>

   <link rel="stylesheet" href="/index.css" />
 </head>
 <body>
   <div class="container">
     <div>
       <h1>CSS Masonry Playground</h1>

       <p>
         Lorem ipsum dolor sit amet consectetur adipisicing elit. A recusandae
         sunt perspiciatis magnam neque, quae aliquid cupiditate dignissimos
         omnis adipisci praesentium et maiores vero corporis atque ipsum harum
         quisquam iusto.
       </p>
     </div>

     <div class="gallery-container">
       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674371886/logrocket-css-masonry/10.jpg"
           alt="blog post one"
         />
         <h2>One Blog Title Here</h2>
         <figcaption>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </figcaption>
       </figure>

       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674344289/logrocket-css-masonry/8.jpg"
           alt="blog post two"
         />
         <h2>Two Blog Title Here</h2>
         <figcaption>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </figcaption>
       </figure>

       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674373487/logrocket-css-masonry/window.jpg"
           alt="blog post three"
         />
         <h2>Three Blog Title Here</h2>
         <p>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </p>
       </figure>

       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674344282/logrocket-css-masonry/4.jpg"
           alt="blog post four"
         />
         <h2>Four Blog Title Here</h2>
         <figcaption>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </figcaption>
       </figure>

       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674344280/logrocket-css-masonry/7.jpg"
           alt="blog post five"
         />
         <h2>Five Blog Title Here</h2>
         <figcaption>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </figcaption>
       </figure>

       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674344279/logrocket-css-masonry/6.jpg"
           alt="blog post six"
         />
         <h2>Six Blog Title Here</h2>
         <figcaption>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </figcaption>
       </figure>

       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674344278/logrocket-css-masonry/1.jpg"
           alt="blog post seven"
         />
         <h2>Seven Blog Title Here</h2>
         <figcaption>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </figcaption>
       </figure>

       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674344277/logrocket-css-masonry/9.jpg"
           alt="blog post eight"
         />
         <h2>Eight Blog Title Here</h2>
         <figcaption>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </figcaption>
       </figure>

       <figure>
         <img
           src="https://res.cloudinary.com/dkfptto8m/image/upload/v1674344276/logrocket-css-masonry/3.jpg"
           alt="blog post nine"
         />
         <h2>Nine Blog Title Here</h2>
         <figcaption>
           Lorem ipsum dolor sit amet consectetur, adipisicing elit. Soluta eos
           expedita quis perspiciatis dicta qui magni?
         </figcaption>
       </figure>
     </div>
   </div>
 </body>
</html>
```

At this point, the website has been built; however, it has no styles because the `/index.css` file has not been created. 

Let’s proceed to add some styling in the next section.

## Adding initial styles to our CSS masonry project <a name="adding-initial-styles-css-masonry-project">

Within the project directory, create a file and name it `index.css` to store the CSS stylesheets. 

Add the following CSS code into the `index.css` file to only style the `div` and `img` elements within the page:

```css
.container {
   max-width: 1224px;
   margin: 0 auto;
}

img {
   width: 500px;
   object-fit: contain;
   border-radius: 15px;
}

figure {
   margin: 0;
}
```

As shown in the image below, the parent `div` containing the list of images was not styled to achieve the masonry layout: ![Project Images Displayed In List Without Css Masonry Styling](https://blog.logrocket.com/wp-content/uploads/2023/03/img2-Images-list-no-masonry-styling.png) 

Over the next subsections, you will explore various ways to create a masonry look in various CSS layout modules. Let’s start with the experimental CSS grid masonry support.

## Achieving a masonry layout with CSS grid’s experimental feature <a name="achieving-masonry-layout-css-grid-experimental-feature">

Open the `index.css` file and add the `.gallery-container` selector to the existing selectors you added during the previous step:

```css
.gallery-container {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-gap: 1rem 3rem;
   grid-template-rows: masonry;
}
```

The magic word within the `.gallery-container` selector above is the `masonry` value provided to the `grid-template-rows` property. 

As a feature still in draft status at this time, the grid masonry layout will only work in a browser with support for beta features. Hence, the `grid-template-rows` property will not be applied when you open the blog website via stable browsers such as Chrome, Mozilla, or Safari. 

The image below shows the layout of the blogs being viewed via Chrome browser. Notice that the [images are arranged in a grid](https://blog.logrocket.com/responsive-image-gallery-css-flexbox/), but not a masonry-style grid. The columns have a strict axis, causing a blank space below blog posts with a smaller image: ![Project Images Arranged In Grid But With Whitespace Between Content Due To Absence Of Masonry Css Styling](https://blog.logrocket.com/wp-content/uploads/2023/03/img3-Images-arranged-grids-not-masonry-style.png) To see the masonry layout, download and open the website using [the Firefox Nightly build](https://www.mozilla.org/en-US/firefox/channel/desktop/), allowing you to experience yet-to-be-released next-generation features of the web: ![Project Images In Masonry Layout Using Experimental Css Grid Feature Displayed In Firefox Nightly](https://blog.logrocket.com/wp-content/uploads/2023/03/img4-Masonry-layout-Firefox-Nightly.png) 

Note that [the Google Chrome browser](https://support.google.com/chrome/answer/10612145?hl=en) and [the Mozilla Firefox browser](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Experimental_features) also allow you to test experimental features by setting the flags for these experimental features. 

At this point, you have learned how to create a masonry layout using the experimental CSS `grid-template-rows` property. Considering that this property is yet to be released with full browser support, you cannot use it while building for the public. 

Let’s consider another solution on how to create a masonry layout using the multi-column layout.

## Imitating a masonry layout using columns <a name="imitating-masonry-layout-columns">
 
This approach will leverage the CSS [CSS multi-column layout](https://www.w3.org/TR/css-multicol-1/) with a defined `column-count` to have the browser figure out how to [arrange elements within the columns](https://blog.logrocket.com/understanding-grid-template-columns-css/) without a strict height, thus creating a masonry layout. 

Replace the rules within the `.gallery-container` and `figure` class selectors within the `index.css` file with the code below:

```css
.gallery-container {
 column-count: 3;
 column-gap: 20px 20px;
 width: 1200px;
}

figure {
 margin: 0;
 display: inline-block;
 margin-bottom: 0px;
 width: 100%;
}
```

The new CSS rules above will style the blog posts into a three column layout without a defined vertical axis. This will cause the elements to fill up the available vertical space, making it appear visually similar to a masonry layout: ![Project Images Arranged In Three Columns To Imitate Css Masonry Styling But Displayed In Nonintuitive Order](https://blog.logrocket.com/wp-content/uploads/2023/03/img5-Images-arranged-three-columns-visually-similar-masonry-style.png) 

As pointed out in the image above, the ordering and sequence of the blog posts are vertical — from top to bottom — rather than being shown horizontally from left to right. This causes a disconnect between the visual order as seen by users and the DOM order. 

Before you adopt this approach of creating a masonry-style layout using CSS, it is important that you consider the effect the lack of intuitive ordering will have on users, especially those who depend on [web accessibility features](https://blog.logrocket.com/a-guide-to-improving-web-accessibility-with-css/). 

Without text or some visual element to explain the ordering of elements, users will expect that the elements are ordered from left to right. Those who rely on their keyboards to navigate the list will find this very confusing, as each press of the tab key will move them through the content from top to bottom, rather than right to left as visually expected.

## Conclusion

Huge congratulations to you on completing this tutorial! 

At the start of the tutorial, we set out to learn more about the masonry layout and how we could achieve it using only CSS. To achieve our goal, we dug deeper into the origin of the masonry layout and built the post feed page of a vanilla HTML website using two different approaches with CSS. 

As you anticipate the general release of the masonry CSS grid layout, you can check if a user’s browser supports it through [the `CSS.supports()` method](https://developer.mozilla.org/en-US/docs/Web/API/CSS/supports). By doing this, you can replace your masonry hacks with the simplified masonry layout implementation once it’s supported. 

If you enjoyed learning about the experimental masonry property for the grid layout, check out some [articles about other new CSS features](https://blog.logrocket.com/tag/css/), such as [LCH and LAB support](https://blog.logrocket.com/building-color-palette-css/#exploring-relative-color-syntax-css-lch-lab).

---

## Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, [try LogRocket] (https://logrocket.com/signup/).

[![LogRocket Dashboard Free Trial Banner] (https://blog.logrocket.com/wp-content/uploads/2019/12/cpu-memory-usage.png)](https://logrocket.com/signup/)

[LogRocket] (https://logrocket.com/signup/) is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — [Start monitoring for free] (https://logrocket.com/signup/).