10

enter image description here

I have a "dashboard" type layout in which I have two columns of differing heights. I have a third item that I would like to add to whichever is the shortest column (see attached screenshot).

In the first example, column 1 is shorter, so we add item 3 below that, but if column 2 is shorter it should be there.

I thought I should use floats, however it doesn't run right.

Can someone please enlighten me?

Salman A
  • 262,204
  • 82
  • 430
  • 521
James Holland
  • 161
  • 3
  • 8
  • 1
    where is your code? what have you tried? "I have a third item that I would like to add to whichever is the shortest column" add how? dynamically? on the server? the client? – atmd Sep 03 '15 at 15:17
  • 1
    Probable duplicate - http://stackoverflow.com/questions/8470070/how-to-create-grid-tile-view-with-css – Paulie_D Sep 03 '15 at 15:18
  • 1
    Aside from using something like jQuery Masonry plugin, this could be achieved using a combination of JS and the CSS flex-box properties. https://css-tricks.com/snippets/css/a-guide-to-flexbox/ – Tim Bunch Sep 03 '15 at 16:35

4 Answers4

7

I don't think it is possible via a pure CSS solution. First the DOM must be render (the 2 boxes and their contents are rendered) and thus you have the exact height of each box. Then you need to calculate (Javascript ? ) which is the shortest and then append the 3rd box to that column.

So from all the above, i think that you need a combination of JS and CSS

Andreas Traganidas
  • 497
  • 1
  • 6
  • 13
5

You can float the three items left, right and left:

#wrapper {
  box-shadow: 0 0 0 1px #CCC;
}
/* clearfix */
#wrapper::after {
  content: "";
  display: block;
  clear: both;
}
.item {
  width: calc(50% - 1em);
  margin: .5em;
}
/* floats */
#item-1 {
  float: left;
  background-color: #080;
}
#item-2 {
  float: right;
  background-color: #F00;
}
#item-3 {
  float: left;
  background-color: #FF0;
}
/* demo */
textarea {
  box-sizing: border-box;
  margin: 1em;
  width: calc(100% - 2em);
  resize: vertical;
}
<p>Resize the boxes by dragging the resize handle of the textarea<br> The yellow box will position itself below the shorter of green and red box</p>
<div id="wrapper">
  <div class="item" id="item-1"><textarea rows="4">1</textarea></div>
  <div class="item" id="item-2"><textarea rows="9">2</textarea></div>
  <div class="item" id="item-3"><textarea rows="4">3</textarea></div>
</div>
Salman A
  • 262,204
  • 82
  • 430
  • 521
1

This may not be quite as you intended but by using flexbox columns you can create the effect. If you adjust the height of el1 e.g. makes it 150 you will see the shapes re-arrange. This is the best pure CSS solution I could come up with but if you need more flexibility I would recommend the Masonry plugin as others have said.

    #content {
        width: 400px;
        height: 200px;
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
    }
    
    .box {
        width: 200px;
        flex: none;
        box-sizing: border-box;
        color: white;
        text-align: center;
    }
    
    #el1 {
        height: 50px;
        background-color: green;
    }

    #el2 {
        height: 100px;
        background-color: red;
    }
    
    #el3 {
        height: 100px;
        background-color: yellow;
    }
<div id="content">
    <div class="box" id="el1">1</div>
    <div class="box" id="el2">2</div>
    <div class="box" id="el3">3</div>
</div>
Mohit Kumar Gupta
  • 362
  • 1
  • 6
  • 21
Frazzle
  • 23
  • 1
  • 9
1

Currently this is not possible with CSS only, since web layout work by line-by-line rendering.

You can use a js plugin like Masonry or write your own implementation.

AVAVT
  • 7,058
  • 2
  • 21
  • 44
  • What does CSS column layout (or flex with direction = column) do? – Salman A Feb 11 '19 at 15:21
  • @SalmanA Both doesn't work that way, they fill just column-by-column instead of line-by-line (like how Chinese write). Unless you limit the container's height, the first column could be infinitely long and never wrap to 2nd col. – AVAVT Feb 12 '19 at 00:24