3

Each of my columns has different heights. How can I order my column to horizontally instead of vertical using CSS? Also on hovering of each item, the height will increase a little bit without overlapping below items.

.parent{
    /*display: flex;
    flex-flow: column wrap;
    height:600px; */

    column-count: 3;
    column-gap: 20px;
    -moz-column-count: 3;
    -moz-column-gap: 20px;
    -webkit-column-count: 3;
    -webkit-column-gap: 20px;
}
.child{
    background-color:#eee;
    margin-bottom:2px;
}
.child:hover{
    min-height:300px;
}
<div class="parent">
    <div class="child" style="height:100px">1</div>
    <div class="child" style="height:120px">2</div>
    <div class="child"  style="height:200px">3</div>
    <div class="child"  style="height:100px">4</div>
    <div class="child"  style="height:50px">5</div>
    <div class="child"  style="height:100px">6</div>
    <div class="child"  style="height:100px">7</div>
    <div class="child"  style="height:100px">8</div>
    <div class="child"  style="height:100px">9</div>
</div>

Current order is

147
258
369

But I need

123
456
789
Rajilesh Panoli
  • 770
  • 10
  • 17

3 Answers3

2

One possibility is to use flex columns, and sort the items depending on their position modulo 3. Also, insert pseudo elements to force the wrap

.parent {
  display: flex;
  flex-flow: column;
  flex-wrap: wrap;
  height: 500px;
  width: 300px;
}

.child {
  margin: 5px;
  width: 100px;
  background-color: lightgreen;
  transition: padding 1s;
}

.child:hover {
   padding: 30px 0px;
}

.child:nth-child(3n + 1) {
  order: 1;
}

.child:nth-child(3n + 2) {
  order: 10;
}

.child:nth-child(3n) {
  order: 20;
}

.parent:before,
.parent:after {
  content: "";
  width: 0px;
  height: 999px;
}

.parent:before {
  order: 5;
}

.parent:after {
  order: 15;
}
<div class="parent">
  <div class="child" style="height:100px">1</div>
  <div class="child" style="height:120px">2</div>
  <div class="child" style="height:200px">3</div>
  <div class="child" style="height:100px">4</div>
  <div class="child" style="height:50px">5</div>
  <div class="child" style="height:100px">6</div>
  <div class="child" style="height:100px">7</div>
  <div class="child" style="height:100px">8</div>
  <div class="child" style="height:100px">9</div>
</div>
TylerH
  • 20,799
  • 66
  • 75
  • 101
vals
  • 61,425
  • 11
  • 89
  • 138
  • In this case you *need* to define a fixed height right? – IvanS95 Feb 06 '19 at 18:48
  • 1
    @IvanS95 Yes, I don't think it can work with a fixed height. But it can be almost any value, you only need to the set the pseudos height to something higher – vals Feb 06 '19 at 20:25
  • @vals, thanks for the answer. Is it possible without parent height? My contents are dynamically adding also responsive so not able to add fixed height. CSS3 column property doesn't need parent height. I'm facing issue only on horizontal order. flex won't work in my case. I had tried flex and grid as well. – Rajilesh Panoli Feb 07 '19 at 05:44
  • As far as I know, there is no solution for your request using only CSS without the fixed height. You would need to use a javascript for this. A workaround could be to set a container with height = viewport, and then a nested container with a very high height. (E.g 10000px). – vals Feb 07 '19 at 10:56
1

Please check this link and let me know if it worked.

https://jsfiddle.net/sreenath124/cp2vj9sh/

html

<div class="parent">
    <div class="child">1</div>
    <div class="child">2</div>
    <div class="child">3</div>
    <div class="child">4</div>
    <div class="child">5</div>
    <div class="child">6</div>
</div>

css

.parent {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, 200px);
  grid-auto-rows: 1fr;
}

.child {
  border: 1px solid;
  padding: 10px;
  transition: all 0.5s ease;
}
.child:hover {
  transform: scale(1.1);
}

Also please check this link if you are looking for something like this. https://codepen.io/andybarefoot/pen/QMeZda

https://medium.com/@andybarefoot/a-masonry-style-layout-using-css-grid-8c663d355ebb

Sree Nath
  • 543
  • 6
  • 19
  • Thanks for the answer. I checked this but here I'm not able to add a hover effect. Item height should increase when I hover an item. Also, other elements should adjust according to that item's hover height. Only height. scale won't work in my case. – Rajilesh Panoli Feb 06 '19 at 10:58
0

It is easy if you structure the HTML differently:

.parent {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
.child {
  /* Just to demonstrate */
  background-color: powderblue;
  margin: 1px;
}
.child:hover {
  min-height: 40px;
}
<div class="parent">
  <div class="column">
    <div class="child" style="height: 25px">1</div>
    <div class="child" style="height: 30px">4</div>
    <div class="child" style="height: 40px">7</div>
  </div>
  <div class="column">
    <div class="child" style="height: 30px">2</div>
    <div class="child" style="height: 20px">5</div>
    <div class="child" style="height: 30px">8</div>
  </div>
  <div class="column">
    <div class="child" style="height: 30px">3</div>
    <div class="child" style="height: 30px">6</div>
    <div class="child" style="height: 30px">9</div>
  </div>
</div>

P Varga
  • 19,174
  • 12
  • 70
  • 108
  • Thanks @pete for the answer. But here gaps are visible between 1 and 4, 2 and 5, etc. It should work like a masonry layout. I tried grid as well – Rajilesh Panoli Feb 06 '19 at 09:03
  • Edited my answer, is the result similar to what you're after? I think it does require structuring the `
    `s into columns like above, though.
    – P Varga Feb 06 '19 at 09:29
  • This is a nice solution but in my case I'm not able to change structure as It will affect my responsiveness. In mobile version it will become single column so the order again will change. order changing after resizing browser also – Rajilesh Panoli Feb 06 '19 at 10:52