Sickdesigner.com

The work & fun of web designer Radu Chelariu.

Menu

Experiments, ideas & things done just for the fun of it

Contact me

Feel free to get in touch with me if you want to hire me (design work, speaking engagements, guest posting), interviews, if you have a problem with either Photoshop, HTML, CSS or Wordpress, or if you just want to talk about design. I'm also available on Twitter, Facebook or Google+, if that's more your game.

But, for the love of all that is Bauhaus, please do not contact me if you're selling something or about link exchanges and that kind of stuff. I will not reply to these requests.

Masonry in CSS

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.

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?

The basic HTML

1
2
3
4
5
6
<div>
<a href="#">Whatever stuff you want to put in here.</a>
<a href="#">Whatever stuff you want to put in here.</a>
<a href="#">Whatever stuff you want to put in here.</a>
...and so on and so forth ad nauseum.
</div>

And the CSS magic

1
2
3
4
5
6
7
8
9
10
11
12
13
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:

1
2
3
<!--[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, my technique 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 which will see a final release when I’ll be able to lick the back of my own head.

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! Since the new design doesn’t use this technique, I put together a demo page here:
Demo

Cheers, all!

68 Comments so far

  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.

  28. Shaun says:

    Well done sir.

  29. Hi. Great article!
    I seem to be stuck on IE9 compatibility. I have an indexhibit plugin with masonry.
    I’ve already reinstalled with latest jquery from http://masonry.desandro.com/ and made your tip on browser compatibility, but still tha images don’t appear in height.

    They only appear in width.

    In firefox and google chrome all works perfectly.

    coud you help?

    thank you
    hugo

  30. Sam Wilson says:

    This saved me a lot of time, thanks.

  31. Brad says:

    Well played, good sir. I like this.

  32. Catherine says:

    Nice solution Thanks.
    But, as I tried to use it on my design it worked well in FF but I had surprises in Chrome and Opera (didn’t try Safari and IE,well I usually don’t even bother… I’m bad I know).
    The “bricks” of my layout have img background and CSS rounded corners -> those are gone on one side in Chrome and Opera. And the gaps are way bigger than expected, nothing like the 20px I had set.
    Also, I have 12 bricks of diverse sizes: FF and Chrome arranged them in 4 columns of 3, Opera in 2 col of 4, one of 3 and a lonely element in the last… (Don’t ask the opera guys to effectively fill the trucks when moving out… Or are they hooked on some sort of alternative sokoban? ;-) )
    And btw, checking your homepage, the links and effects only worked in the 1st row in Opera, worked fine in FF and Chrome. (Or is it just me?)
    Anyway, if you have some good advices to straighten things up in Opera and Chrome, I’m listening.
    And keep on with the good work mate :-)

    • Catherine says:

      Resolved gap and round corners problems by applying a different size to the parent width and a margin-left on it and not the children…
      Yep, size is all that counts ;-)
      but as the columns population arrangement goes it’s weird since Opera dev sheet says the default on Opera is balanced columns…

  33. Davide says:

    thanks radu, i’m asking my self if i want to create the internal boxes with different width from each other with percentage, that always make a sum of 100% i can i do?

  34. Great stuff! I was looking for a css-only way to do a Pinterest-layout. Tada ! :)

  35. Alex Oviedo says:

    Just got introduced to your blog via Smashing. Awesome! I’m new to web development an you have been out on my favorites!

    • Pretty much half of the people who know about this blog have found out courtesy of Vitaly and the Smashing team. I’ve got to shower that man in beer next time I see him!

  36. Mohamed Mansour says:

    It works great in IE10, what issues are you having?

  37. Cole says:

    Is there any way to reorder these (even with just a short bit of js) so that they run left to right rather than top to bottom?

    • Unfortunately, no, as of this time there is no property to allow for horizontal spanning of column content. Though, just like yourself, I wish there were.

  38. Your HTML is incorrect in line 1. Should be , not <div<.

  39. Webbower says:

    This is an awesome trick. However, as noted by others, it’s not quite the Masonry effect. Masonry works left-to-right whereas this works top-to-bottom. In and of itself, this is not a huge issue. However, it becomes a big issue when you try to recreate the Pinterest experience of injecting more tiles into the layout. What was at the top of column 2 will now be somewhere down column 1.

    Example here: http://jsfiddle.net/webbower/5h6xT/

    I am by no means shooting this down, just pointing out pitfalls.

  40. Clint says:

    Setting the OL to a percent width and IMG to 100% width give a nice responsive feel if you’re not using iframes in your layout.

    Thanks!

  41. avetisk says:

    It worths to notice that in Chrome combining transition with columns is not a good idea: https://code.google.com/p/chromium/issues/detail?id=177556

    So if you were about to use the pure CSS solution, forget it for now.

Speak your mind