50

So I have CSS like this:

#blogPosts{
    -moz-column-count: 3;
    -moz-column-gap: 10px;
    -webkit-column-count: 3;
    -webkit-column-gap: 10px;
    column-count: 3;
    column-gap: 10px;
    width: 100%; 
}

and this creates 3 columns perfectly but when I gain another row the order seems to come out vertically like:

1,3,5
2,4,6

Instead of what I am wanting as:

1,2,3
4,5,6

Important!

Another important attribute I need, is that there must be a set margin between every post vertically. So for example if you look at the table above if 2 is longer than 1, the top of 4 will start y bellow 1 rather than: the height of 2 + y.


The HTML is like this:

<div id="blogPosts">
    <div class="blog">Content</div>
    <div class="blog">Content</div>
    ...
</div>

What can I do to fix this?


I am happy for any solutions, even one that includes javascript/jquery


This is the kind of thing I am after

enter image description here

Community
  • 1
  • 1
maxisme
  • 3,974
  • 9
  • 47
  • 97

5 Answers5

11

The closest thing would be to use flexbox

#blogPosts {
   display: flex;
   align-items: left;
   justify-content: left;
   flex-direction: row;
   flex-wrap: wrap;
   flex-flow: row wrap;
   align-content: flex-end;
}

http://jsfiddle.net/o59gc4hw/2/

Miguel Mota
  • 20,135
  • 5
  • 45
  • 64
4

Well on the first sight I thought you should look at the Masonry library. When you then search for masonry, you possibly also will find masonry flexible box and masonry columns.

Problem with both the columns and flexible box solutions is that the first items are in the first column.

I found one possible solution, which only works when your number of item is fixed.

For nine items in three columns:

#blogPosts {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
      -ms-flex-direction: column;
          flex-direction: column;
  -webkit-flex-wrap: wrap;
      -ms-flex-wrap: wrap;
          flex-wrap: wrap;
}
.blog {
  color: white;
  width: 33%;
}
.blog:nth-child(3n+1) {
  -webkit-box-ordinal-group: 1;
  -webkit-order: 0;
      -ms-flex-order: 0;
          order: 0;
}
.blog:nth-child(3n+2) {
  -webkit-box-ordinal-group: 2;
  -webkit-order: 1;
      -ms-flex-order: 1;
          order: 1;
}
.blog:nth-child(3n+3) {
  -webkit-box-ordinal-group: 3;
  -webkit-order: 2;
      -ms-flex-order: 2;
          order: 2;
}
.blog:nth-child(n+7):nth-child(-n+9) {
  page-break-after: always;
  -webkit-break-after: always;
     -moz-break-after: always;
          break-after: always;
}
<div id="blogPosts">
    <div class="blog" style="background-color:blue; height:50px;">1</div>
    <div class="blog" style="background-color:red; height:75px;">2</div>
    <div class="blog" style="background-color:green; height:100px;">3</div>
    <div class="blog" style="background-color:black; height:30px;">4</div>
    <div class="blog" style="background-color:yellow; height:50px;">5</div>
    <div class="blog" style="background-color:purple; height:80px;">6</div>
    <div class="blog" style="background-color:pink; height:150px;">7</div>
    <div class="blog" style="background-color:orange; height:15px;">8</div>
    <div class="blog" style="background-color:gold; height:50px;">9</div>
</div>

The above use the flexible box, with the order property and nth child selectors. And finally also see: How to specify an element after which to wrap in css flexbox?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Bass Jobsen
  • 48,736
  • 16
  • 143
  • 224
0

I believe your misunderstanding how the column separation works with css colunms. Your blogPosts class is separating the content as evenly as possible across 3 colunms so it appears like:

1 3 5
2 4 6


but if you do

<div class="blogPosts">
    Content 1
</div>
<br>
<div class="blogPosts">
    Content 2
</div>
<br>
<div class="blogPosts">
     Content 3
</div>

Then the conents would appear as:

1
2
3

but the content within these sections would fit to the 3 colunms.

bytecode77
  • 14,163
  • 30
  • 110
  • 141
Chacliff
  • 63
  • 1
  • 11
0

try this

#flex-container {
  border: 1px solid black;
  background-color: rgb(255, 230, 251);
  display: grid;
  grid-template-columns: repeat(3,1fr);
  column-gap: 30px;
  }
#flex-container > div {
  border: 1px solid black;
  padding: 10px;
  background-color: lightgreen;
  }

https://www.w3schools.com/cssref/tryit.php?filename=trycss_column-gap_grid

sadeq shahmoradi
  • 1,395
  • 1
  • 6
  • 22
4seasons
  • 21
  • 4
-2

This can be implemented with simple css. HTML:

<div id="blogPosts">
<div class="blog">1Content</div>
<div class="blog">1Content</div>
<div class="blog">2Content</div>
</div>

CSS: make the "blog" class as inline-block and float to left as show below.

.blog {
     display: inline-block;
     width: 33.3%;
     float: left;
     margin-bottom: -999em;
     padding-bottom: 999em; 
}

#blogPosts{
    overflow: hidden;
}

This is will fix the height issue that you had as well. :)

  • 2
    i don't think this solves the height problem, see: http://codepen.io/anon/pen/YXWRrq – Bass Jobsen May 19 '15 at 11:23
  • 2
    @BassJobsen, Sorry, My bad I misunderstood the question. What I thought was the second row elements should start from same position. Please find the updated answer above. [JSFIDDLE LINK](http://jsfiddle.net/prashanth_j05/xbxuryhL/1/) – Prashanth Jagadeesh May 19 '15 at 19:22
  • 1
    well nice done. But i still think it does not solves: "at the table above if 2 is longer than 1, the top of 4 will start next to 2 rather than below" – Bass Jobsen May 19 '15 at 19:56