2

Given a collection of boxes of varying height

<div class="collection">
    <div style="height:50px">1</div>
    <div style="height:80px">2</div>
    <div style="height:60px">3</div>
    <div style="height:40px">4</div>
    <div style="height:80px">5</div>
    <div style="height:50px">6</div>
    <div style="height:60px">7</div>
    <div style="height:40px">8</div>
</div>

and some jquery to give them unique colors (for debugging)

$('.collection>div').each(function (n) {
    $(this).css('backgroundColor', 'hsla(60, ' + n*10 + '%, 45%, 1)');
});

How can I display them in "sensible" columns? The best way I can explain it is if there existed a float:up that would work for boxes with the same width and varying height isomorphically to the way float:left does for boxes of equal height but varying width.

With float: left the ordering seems random to the uninitiated, and gives lots of ugly space internally and also to the bottom and right (the padding on .collection should only be a third of the spacing between boxes):

.collection { 
    outline: 1px dotted blue; 
    padding: 5px;
    overflow: hidden;  /* clearfix */
}
.collection > div { 
    margin: 0 15px 15px 0;
    width: calc((100% - 2 * 15px) / 3);  /* doesn't work */
    width: calc(33% - 14px);             /* magic 14..? */
    float: left;
}

float gaps https://jsfiddle.net/mojx8rre/1/

I've tried column-count:

.collection { 
    -webkit-column-count: 3; 
    -moz-column-count: 3;
    column-count: 3;
    height: 200px; 
    outline: 1px dotted blue; 
    padding; 5px;
}
.collection > div { 
    margin-bottom: 15px;
}

https://jsfiddle.net/25c4g8a8/2/

But that works differently between eg. Chrome and Firefox and the boxes end up sliced - sometimes with just slivers in one column. Chrome: column slices

vs. Firefox:

column slices

thebjorn
  • 26,297
  • 11
  • 96
  • 138
  • 1
    I guess you are looking for something similar to what Isotope plugin does. Check their plugin out to find a solution: http://isotope.metafizzy.co/#isotope-in-use. – sdvnksv Sep 26 '15 at 15:21
  • I don't really understand what yo are trying to do. As far as i understand it you are looking for something like http://packery.metafizzy.co/, don't you? Or can you scribble the idea? – radscheit Sep 26 '15 at 15:22
  • Yes, the Masonry example from http://packery.metafizzy.co/ seems like exactly what I'm looking for. Is it possible to do that with plain css? – thebjorn Sep 26 '15 at 15:44
  • @thebjorn See my answer for a plain CSS solution. – zer00ne Sep 26 '15 at 16:12

1 Answers1

1

You could try flexbox. It's a CSS layout, no plugin or framework, just plain old CSS. See the demo below:

DEMO

CSS

/* Defaults */
 html {
    box-sizing: border-box;
    font: 400 16px/1.45 'Source Code Pro';
}
*, *:before, *:after {
    box-sizing: inherit;
    margin: 0;
    padding: 0;
    border: 0 solid transparent;
}
body {
    width: 100vw;
    height: 100vh;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 .collection {
    /* Flexbox Properties */
    /* https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties */      
    display: -webkit-flex;
    display: flex;
    -webkit-flex-flow: column wrap;
    flex-flow: column wrap;
    -webkit-justify-content: flex-start;
    justify-content: flex-start;
    -webkit-align-items: flex-start;
    align-items: flex-start;
    -webkit-align-content: flex-start;
    align-content: flex-start;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    outline: 1px dotted blue;
    padding: 5px;
    overflow: hidden;
    /* Limited height to coincide with examples */
    height: 100%;
    max-height: 250px;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}
.collection > div {
    margin: 0 15px 15px 0;
    width: calc((100% - 2 * 15px) / 3);
    width: calc(33% - 14px);
}
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • I think only the `flex` and `flex-flow` rules are needed (https://jsfiddle.net/hsg09krc/2/) – thebjorn Sep 26 '15 at 19:47
  • @thebjorn Correct, I always use the extra properties just in case there are certain circumstances that require them. If you aren't concerned about Safari, you can delete the `-webkit-*` properties as well. – zer00ne Sep 27 '15 at 19:48