I'm Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with HTML, CSS and SVG. To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

my books

Pro CSS3 Animation book coverPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head CanonMassive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

The New DefaultsThe New Defaults — A Sass color keyword system for designers.

CSSslidyCSSslidy — an auto-generated #RWD image slider. 3.8K of JS, no JQuery.

Pinterest-Style Column Layout In Pure CSS

Based on the work of Kushagra Agarwal, using the illustrations of Claire Hummel.

Pinterest launched three years ago with a signature and immediately emulated visual style: vertical columns of collected snippets. Pinterest uses JavaScript to achieve this layout, but for a long time I’ve wanted to replicate it using CSS alone. Based on the pioneering work of Kushagra Agarwal and using the outstanding illustrations of Claire Hummel, I’m pleased to offer this solution.

Achieving The Layout

The pictures and their captions are entered as semantic HTML5 (I’ll show just the first two images, as the code quickly becomes repetitive):

<div id="columns">
<figure>
<img src="cinderella.jpg" alt>
<figcaption>Cinderella wearing European fashion of the mid-1860’s</figcaption>
</figure>
<figure>
<img src="rapunzel.jpg" alt>
<figcaption>Rapunzel, clothed in 1820’s period fashion</figcaption>
</div>

CSS multi-column layout is perfect suited to achieving this effect. The code is shown sans vendor prefixes for clarity:

#columns {
column-width: 320px;
column-gap: 15px;
width: 90%;
max-width: 1100px;
margin: 50px auto;
}

Setting the columns to a fixed width paradoxically makes them more responsive: the spec says that the browser must base its layout of the columns on the answer to the question “how many 320px wide columns (plus any gap) can fit evenly into the space provided?” After that calculation the layout is achieved: 6 columns or 1, whatever works.

The CSS for the individual <figure> elements and the images they contain is almost as straightforward:

div#columns figure {
background: #fefefe;
border: 2px solid #fcfcfc;
box-shadow: 0 1px 2px rgba(34, 25, 25, 0.4);
margin: 0 2px 15px;
padding: 15px; padding-bottom: 10px;
transition: opacity .4s ease-in-out;
column-break-inside: avoid;
display: inline-block;
}
div#columns figure img {
width: 100%; height: auto;
border-bottom: 1px solid #ccc;
padding-bottom: 15px;
margin-bottom: 5px;
}

column-break-inside: avoid; should be enough to force each <figure> element to fall completely inside the column it starts within, without “slopping over” to the next, but no browser completely adheres to that rule yet. To get around that, I’ve added display: inline-block to the rule.

Finally, we use the deeply underappreciated :not pseudo-selector to create the hover effect, using the transition we added earlier to the <figure> elements:

div#columns:hover figure:not(:hover) { opacity: 0.4; }

Translated into English, the selector reads “if the user is hovering anywhere in the container element, set the figure elements inside to opacity: 0.4, except for any figure element that the user is hovering over directly”.

Mobile Considerations

Finally, you could add an @media query at the end to tidy up the presentation at small screen sizes:

@media screen and (max-width: 750px) {
  #columns { column-gap: 0px; }
  #columns figure { width: 100%; }
}

Alternatives

It’s possible to use flexbox to achieve this layout; the only condition is that the outer container must have an explicit height, otherwise the inner items will continue in a single unbroken column.

There’s also a lot of code repetition in the HTML: adding an image to the layout requires wrapping it in a <figure> element and inserting <figcaption> text. This process can be automated with JavaScript, while preserving the principles of progressive enhancement. Play with the code for this gallery on Codepen

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.