5

What I have is a two-column layout with several items inside:

.grid {
  column-count: 2;
}

.grid-item {
  break-inside: avoid;
  height: 50px;
  margin-bottom: 10px;
  background-color: green;
  text-align: center;
  line-height: 50px;
  color: white;
}
<div class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
</div>

https://codepen.io/Deka87/pen/RgdLeZ

Now I need an ability to reorder those items inside the columns with CSS only (so they were in a different order on different screen resolutions), so I thought I can do this with:

.grid {
  display: flex;
  flex-direction: column;
  column-count: 2;
}
.grid-item:nth-child(1) {
  order: 5;
}

Obviously, this didn't work and broke the 2-column layout. Anybody tried to solve this before? Any chance I can get this working?

PS: Items on the same line should not be of the same height (I could have used simple floats in this case). Sorry for not specifying in the beginning.

TylerH
  • 20,799
  • 66
  • 75
  • 101
sdvnksv
  • 9,350
  • 18
  • 56
  • 108

2 Answers2

3

Without a fixed height on the container, a column of flex items won't know where to wrap. There's nothing to cause a break, so items will continue expanding the single column.

Also, column-count and display: flex represent two different CSS technologies. column-count is not a valid property in a flex container.

CSS Grid Layout may be useful to you:

re-size the screen width to trigger the media query

revised codepen

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(3, auto);
  grid-auto-rows: 50px;
  grid-auto-flow: column;
  grid-gap: 10px;
}

.grid-item {
  background-color: green;
  text-align: center;
  line-height: 50px;
  color: white;
}

@media ( max-width: 500px) {
  .grid-item:nth-child(2) {
    order: 1;
    background-color: orange;
  }
}
<div class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Thanks, however items on the same line will be of the same height, right? – sdvnksv Jul 14 '17 at 16:30
  • In my example, yes. But grid items can be sized independently. See my answer here: [**Create a Masonry grid with flexbox (or other CSS)**](https://stackoverflow.com/a/43903119/3597276) – Michael Benjamin Jul 14 '17 at 16:31
  • Your solution is explained very well. Thank you! However, it seems that if I have item content height dynamic (e.g. they are text blocks), it won't work as expected. – sdvnksv Jul 14 '17 at 17:04
  • Post a codepen with a complete example and I'll check it out. – Michael Benjamin Jul 14 '17 at 17:05
  • So basically you are right and I was trying to reinvent the masonry layout. Here is a complete example: https://codepen.io/Deka87/pen/WOmdQw?editors=1100. Thanks in advance! – sdvnksv Jul 14 '17 at 17:19
  • Yes, back to square 1: `column-count` with `order`. LOL. Check out some options that may work for you in my answer here: https://stackoverflow.com/q/34480760/3597276 – Michael Benjamin Jul 14 '17 at 17:21
  • Thanks, I already understood that it's either to fix the height or the container of try out the JS plugins :-) – sdvnksv Jul 14 '17 at 17:28
1

I tend to use flexbox for this

.grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
}
.grid-item {
  box-sizing: border-box;
  width: calc( 50% - 5px );
  min-height: 50px;
  margin-bottom: 10px;
  background-color: green;
  text-align: center;
  line-height: 50px;
  color: white;
}

.grid-item:nth-child(1) {
  order: 5;
}
<div class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
</div>  

The flex syntax is widely supported and super flexible.

lumio
  • 7,428
  • 4
  • 40
  • 56
  • The problem with this approach is that the items in the same line will be of the same height. – sdvnksv Jul 14 '17 at 16:31
  • It won't if you use `align-items`. Because the default value here is `stretch`. But you could also set it to `center` or as I did `flex-start` – lumio Jul 14 '17 at 16:35
  • I am not sure you are right at this point. No matter the `align-items` value, items on the same line will occupy the same height. – sdvnksv Jul 14 '17 at 16:38
  • Ah sorry, I misunderstood what you meant. Yes you're right. That is indeed a problem. – lumio Jul 14 '17 at 16:42
  • Unless you have two adjacent flexbox columns, of course, which are wrapped in their parent on smartphones... – Rene van der Lende Jul 16 '17 at 09:05