Pinterest has inspired many to do masonry-based layouts on their sites. We already have some solid JavaScript alternatives out there to create masonry layouts. How about using only CSS to create a masonry?

Before moving any further, I have some updates for you about my experiments with CSS masonry:

After the launch of Pinterest in 2011, I myself tried creating its lookalike with plain CSS. I started off by using CSS floats, then tried inline-blocks, ended up in a messed up layout with tables.

A basic masonry pattern
This is what a masonry pattern looks like

Not exactly tables, but the table display properties. All I got was a equal-height columns, which is definitely not a masonry. Later on, I got success with it using some rarely-used CSS properties.

The secret CSS recipe for Masonry Layout

Not a secret actually, some people have already written about it. Before going further, I would like to show you with a demo of what we are going to create:

Basic Demo Advanced Demo

About the secret, I discovered this technique while experimenting with CSS column properties. I also contributed the outcome of this experiment to a WordPress plugin later on, which was a hit back then.

A wireframe for CSS Masonry

Not many people know about CSS multi-column layout module, which allows us to present blocks as part of virtual columns. One of its properties, column-count, is the magic wand that we’ll be utilising to lay down our masonry.

After that, we will also pair column-count with another multi-column property called column-gap to add gutter to our masonry.

Note: Gutter is the space between the masonry items.

If you are okay with HTML and CSS, this tutorial is going to be easy for you. Let’s jump into the code mess.

The column-count property

CSS column-count allows you to add a specific number of adjacent columns to any block element. The child elements inside the block get aligned as per the specified number of columns.

And this gives an effect of a masonry layout, without any involvement of JavaScript. Read more on column-count here.

What about spacing between the grid items? The column-gap property solved the gutter problem.

HTML

Let’s start with the markup. I have a container division that wraps our masonry and contains all our masonry items or bricks or tiles or columns.

<div class="masonry">
   <div class="item">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
   <div class="item">...</div>
   ...
   ...
   <div class="item">...</div>
</div>

Clearly, the .masonry division acts as the masonry container and each .item acts as the masonry item.

I’ve also used some sample data to in the demo page for a practically-better demonstration.

CSS

Now comes the most fun and important part, i.e. the CSS.

.masonry { /* Masonry container */
    column-count: 4;
    column-gap: 1em;
}

.item { /* Masonry bricks or child elements */
    background-color: #eee;
    display: inline-block;
    margin: 0 0 1em;
    width: 100%;
}

We perform the following tasks with the above CSS:

  1. Apply the column-count property to the container. Because we want to automatically arrange the items in a masonry-fashion.
  2. Set the items as inline blocks with 100% width. Because we want to fit the items properly inside the masonry columns.

That’s the basic idea. We end up getting something like this demo consequently.

Fallback?

Extensive support? CSS columns are robust enough, as they are widely supported by modern browsers. You may, however, consider adding a JavaScript fallback of your choice to make it work on older browsers.

Proceed like this to use a JavaScript masonry solution as a fallback to our CSS masonry in IE9 or below:

<!--[if lte IE 9]>
<script src="masonry.js"></script>
<![endif]-->

This basic masonry is device-friendly. It doesn’t create scroll-bars on zooming-in, as none of its elements has any fixed width. But still, we can make it look different on different resolutions.

Responsive CSS masonry

Along with the responsiveness, I tried to make it look better than our basic demo. Simply modify the column-count for different screen breakpoints with the help media queries.

Note that I make use of box-sizing reset in all my examples here. Here is the CSS snippet that I used to revamp our masonry:

Styling

/* Box-sizing reset: //w3bits.com/?p=3225 */
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

/* The Masonry Container */
.masonry {
  margin: 1.5em auto;
  max-width: 768px;
  column-gap: 1.5em;
}

/* The Masonry Brick */
.item {
  background: #fff;
  padding: 1em;
  margin: 0 0 1.5em;
}

/* Masonry on large screens */
@media only screen and (min-width: 1024px) {
  .masonry {
    column-count: 4;
  }
}

/* Masonry on medium-sized screens */
@media only screen and (max-width: 1023px) and (min-width: 768px) {
  .masonry {
    column-count: 3;
  }
}

/* Masonry on small screens */
@media only screen and (max-width: 767px) and (min-width: 540px) {
  .masonry {
    column-count: 2;
  }
}

Markup would be pretty much like previous example, obviously because this is just an extension to it. Consequently, the demos looks better and attractive as I’ve used more images in it. You can see the full markup in the page source.

Demo the final product Download it for free!


Fixes

  • Many people complained about the disappearing of image on hover in the final masonry. I fixed it by setting backface-visibility to hidden.
  • Some other layout problems disappeared on setting vertical-align as middle for the images.

Conclusion

To sum up, we created a CSS-only masonry with the help of multi-column layout module. I was not 100% satisfied with this solution, as the masonry you get with it is top-to-bottom, not left-to-right. For a horizontal masonry solution, read my latest experiment called CSS Grid Masonry.

And there you have it. Further, you may play with the styles to give it the desired look. Hope you enjoyed the tutorial, I welcome your thoughts, questions, and suggestions.