Sickdesigner

My name is Radu Chelariu, I'm a web designer and here you can get to know me better.

Masonry CSS or Getting awesome with CSS3

Gotta tell you folks: this one’s been bugging me for a week now. I’m sure everyone is familiar with David DeSandro‘s awesome jQuery plugin, Masonry. Well, what this is is two things. First, it’s an homage to David himself and the awesome work that he does. Second, it’s a kick ass, super simple CSS technique that mimics what Masonry does. With just CSS.

For those unfamiliar with jQuery Masonry, what it, essentially, does is mimic a vertical float, not just the regular horizontal kind. In fact, I used it for the homepage of my blog (where the different posts are displayed).

So, what’s the trouble with CSS? It’s quite simple: there is no CSS model that takes into account vertical alignment. Period. I swear I tried everything. From floats, to positions, displaying inline, run-in, you name it, I tried it. But there was this midget in my head telling me that there must be a solution. And, wouldn’t you know it, BAM, two days ago, while eating an omelet, of all things, it struck me.

The all mighty columns

The solution is so simple that it gave me a brain freeze: CSS columns. Granted, their purpose is to display text in columns like a newspaper, but their display mode is exactly what’s needed to recreate the Masonry effect. But let’s get down to the code. What do you need, you say?

A container and some children

<div>
<a href="#">Whatever stuff you want to put in here. Images, text, movies, what have you. No, really, anything!</a>
...and so on and so forth ad nauseum.
</div>

The CSS magic

div{
-moz-column-count: 3;
-moz-column-gap: 10px;
-webkit-column-count: 3;
-webkit-column-gap: 10px;
column-count: 3;
column-gap: 10px;
width: 480px; }


div a{
display: inline-block; /* Display inline-block, and absolutely NO FLOATS! */
margin-bottom: 20px;
width: 100%; }

An interesting fact: the width of the elements within the columned container is not relative to the width of the parent, but the width of the column. In the case of the example above width: 100% actually translates to 150px, not 480px (the width of the parent).

Fallbacks and browser compatibility

Of course, our friends at Microsoft have taken good care to not provide support for CSS columns. Not even in IE9! In this case, I recommend slapping in David’s awesome plugin like so:

<!--[if lte IE 9]>
<script type="text/javascript" src="js/jquery.masonry.min.js"></script>
<![endif]-->

In Microsoft’s defense, for what it’s worth, this does work (well, even!) in the IE10 Platform Preview. Hopefully they’ll leave support for columns in the final version, which could be released as early as next year.

I’m guessing there’s no point in mentioning that this works (brilliantly) in Gecko and Webkit browsers (Mozilla, Chrome, Safari). Opera does weird things that I don’t quite understand yet, but does an acceptable job of rendering columns (it just has trouble with the gaps and all).

This is usually where you’d find a link to a demo page. This time, however, I direct you to the homepage of this site. Yes, I used it live. I have that much confidence in this. Enjoy, kids!

by Radu Chelariu

50 Comments

  1. Marco says:

    I actually totally “forgot” about the inline-block, since IE doesn’t really like it. But this is one pretty nifty solution in combination with the columns that it HAS to be used, well done!

  2. Utwo says:

    On smashingmagazine.com I read an interesting article on how we should provide a single design for all screen sizes, from mobile to TV. I think this is the best method so far. Easy to implement, valid, quick, almost full browser support and … pure CSS.
    I think we should eat more often omelet.
    Bon appétit Radu!

  3. First you’ll be glad to know that I write you this comment from my bathroom. Thx to technologie.

    I was thinking of doing some expérimentation with css column on my next

    • Don’t we all, buddy! Smartphones have probably increased bathroom time worldwide by at least 200%. But, hey, at least you’re honest about it! :)

    • … next work. So i’ll give an eye at your post, and let you know if I end with something cool.

      Thank you for sharing this nice tip.
      F**k you IPhone for the message in two parts. I swear, no more comment in bathroom …

  4. That was just in time !

    Yesterday i was playing with my Tumblr i wanted to make this effect without Masonery . I used inline-block & it solved 60% of the problem but i haven`t thought of the columns part.

    Well done !

  5. Greg Babula says:

    I wish the I could use this on every project, it would solve so many issues

  6. Keri says:

    Ah, the amazing magical powers of omelettes. Thanks so much! Bookmarked =D

  7. lewismc says:

    I totally ditched column layout on a recent project … something to do with attempting to break the column on h1′s … but now I’ll have to revisit. SICK!!!

  8. Percept says:

    Radu,

    I’m not sure if I’m understanding this incorrect but the CSS3 column method does not provide the same result as Masonry?

    For example if you set 3 columns, how would “block 8″ in the example at http://desandro.com/resources/jquery-masonry/ span 2 columns?

    • The real trick that makes David’s Masonry plugin so useful is the elimination of variable vertical gaps between blocks, which is what I was looking for with this technique. Indeed, using columns does not provide the same flexibility as David’s plugin, but that is somewhat a given, seeing as this is just a CSS trick and not a full fledged plugin.

      • Percept says:

        Alright, I mis-read your post as a full CSS Masonry alternative. My bad :)

  9. I check the post.. but the js work around for IE. Don’t work that satisfactorily .

    If the masonry.js works ok..in case you have tried it.

    • You need to put the IE conditional comment inside the tags. Just like you would call a regular script, except for IE only. And, in the case of my example, the script goes in a folder called “js”.

      • Hello Radu Chelariu,
        Alright..
        What I meant that.. the workaround method by mason.js for IE… gives near around the same visible results ??
        as given by the CSS magic code.

        Namaste from India
        Gaurav M

  10. Euhm …
    You used it live on the front of you blog but something goes wrong for me in safari 5.0.5 on mac

    The masonry effect works, but not completely.

    To the left is one line of posts, all underneath each other. Next to it are empty white blocks.

    I presume the content is supposed to be inside those white blocks? :)

    Just thought I’d let you know.

    Great concept btw.

    • Hmm, apparently Safari 5 is being smart. I’m looking into it, see if I can’t find some sort of solution here. It’s a cryin’ shame, really. Thanks!

  11. The idea of combining columns and inlne-block is great.

    However, I’m not fully convinced for a similar reason as Gaurav’s. Masonry sorts the blocks left-to-right first, while the column solution does top-bottom first. This makes it useless in many scenaries, where you have lots of blocks, that extend beneath the fold, and you want the most current to line up at the top.

    I don’t think that we can get the desired effect w/o JS in the next 10 years, even if browsers would support something as cutting-edge as CSS template layouts, http://www.w3.org/TR/css3-layout/.

    Now that that’s out of the way, let me say, that this is the first example of CSS columns I ever read, that uses it for something else than mere text layout. So thanks for putting this property in our (mental) toolbox.

    • I’m a bit more optimistic and hope to see cross-browser CSS columned layouts in about 3 years. Still, I’m glad to see that everyone gets what this is for and, like all new stuff in this business, should be used rarely and for good reasons.

      • Just to make my point clear: I don’t think, that we can get the *exact Masonry effect* within the next 10 years with CSS alone.

        My pessimism there is fed by the fact, that it’s now 6 years that I asked on the public-css list about an CSS property to vertically align block content. The WG members said, that it’s something being worked on.

        And until today there was literally no motion forward on this (rather oftenly asked) topic…

        • I try to keep an optimistic view, though I know what you’re talking about, Manuel. It gets pretty frustrating when you realize that in an industry that thrives off progress, we’re left waiting years on end for the tiniest of extra feature. Damn you, W3C! You hear that? Damn you!

  12. Awesome work, can’t wait to put it on a project, maybe next one :)

  13. Martin says:

    Damn, first thought your a genious, but Manuel Strehl is right of course. To bad.

  14. Luis says:

    Great article and solution. Loved your site. Will come here more often. Cheers!

  15. Well that looks neat!
    This is a css3 trick that does the work quite well, and I didn’t think of it too!
    Thank you for sharing, this makes stuff much easier! :)

  16. Could you please make a demo page for this one? Because I tried it out myself and it only works partially in WebKit and not at all in Firefox.

  17. Jordan Moore says:

    You clever, clever bastard. *bookmarked*

  18. Butch V. says:

    Nice article! A new way of arranging my layouts that I want to try out now. Thanks! :)

  19. Geniala treaba chiar ma intrebam cum naibii le-ai aranjat frate, ce sa zic you the man Radule, posteaza cat mai multe.
    Mult noroc.

  20. rrobe says:

    Doesn’t look right on android 2.2 phone, I’m afraid…

  21. Clark Pan says:

    Great concept but i have a question regarding the semantics of this technique.

    It doesn’t really apply to your front page since you don’t seem to have dates anywhere on the site, but lets say you want to list your articles chronologically, wouldn’t it break reading conventions the articles will be listed until the bottom of the page before it wraps to the top again?

  22. Marcel says:

    Love it! Except for Safari. Got the same problem with 5.0.5. He somehow kicks the content out of the boxes.

    But I’m confident, that there has to be some workaround for that!

  23. Aawesome!!!

    The CSS-only solution works 100% for me in Firefox and Opera, Chrome does a decent job, Safari aligns the items like a pyramid and IE9 actually works for me!

  24. Rhokstar says:

    Why does it have to be midget?

  25. onioneye says:

    LOL, your comments are hilarious. Oh, oh, now please do a joke on me on how I delebaretely misspelled the word deliberately, you schmuck :P

  26. I love this idea. I had a project that required this to be done. Oh well, I can use it next time, however now =].

    Thanks for the plugin. This will help a lot of people who need it.

  27. Gustavo says:

    I love CSS, loathe inconsistent browsers, thanks for the tip, bookmarked.

Speak your mind

RSS Twitter Facebook Dribbble LoveDSGN Flickr