Search code examples
csscss-multicolumn-layout

Is there a way to sort children into columns depending on the class of the children?


Let's say that I have the following HTML code.

<div class='container'>
    <div style='width: 50px; height: random' class='col1'>1</div>
    <div style='width: 50px; height: random' class='col3'>2</div>
    <div style='width: 50px; height: random' class='col2'>3</div>
    <div style='width: 50px; height: random' class='col3'>4</div>
    <div style='width: 50px; height: random' class='col1'>5</div>
    <div style='width: 50px; height: random' class='col2'>6</div>
    <div style='width: 50px; height: random' class='col1'>7</div>
    <div style='width: 50px; height: random' class='col3'>8</div>
    <div style='width: 50px; height: random' class='col2'>9</div>
</div>

<!-

|1| |3| |2| // height of 2 is greater
|5| |6| | | // height of 5 is greater
| | |9| |4| // height of 9 is greater
|7| | | |8|

->

I want container to have 3 columns. I also want each child to be sorted into one of those columns based on its class. Obviously, it would be easy to do this with JavaScript but I'm wondering if it's possible to do it with CSS.

.grid {
  -webkit-column-count: 3;
  -webkit-column-gap: 10px;
  -webkit-column-fill: auto;
  -moz-column-count: 3;
  -moz-column-gap: 10px;
  -moz-column-fill: auto;
  column-count: 4;
  column-gap: 15px;
  column-fill: auto;
}
.block {
  background-color: #ee01ca;
  display: block;
  padding: 20px;
  word-wrap: break-word;
  margin-bottom: 20px;
  -webkit-column-break-inside: avoid;
  -moz-column-break-inside: avoid;
  column-break-inside: avoid;
}

.one {
  height: 100px;
}

.two {
  height: 200px;
}

.three {
  height: 300px;
}
<div class="grid">
  <div class="block one">ervewrv</div>
  <div class="block two">afrvewrwerb</div>
  <div class="block three">dfvdsf</div>
  <div class="block one">vdfvdf</div>
  <div class="block two">dfw45g4</div>
  <div class="block one">ervewrv</div>
  <div class="block two">afrvewrwerb</div>
  <div class="block three">dfvdsf</div>
  <div class="block one">vdfvdf</div>
  <div class="block two">dfw45g4</div>
  <div class="block three">4rv4r</div>
  <div class="block one">4rv454</div>
  <div class="block three">4rv4r</div>
  <div class="block one">4rv454</div>
  <div class="block one">ervewrv</div>
  <div class="block one">ervewrv</div>
  <div class="block two">afrvewrwerb</div>
  <div class="block three">dfvdsf</div>
  <div class="block one">vdfvdf</div>
  <div class="block two">dfw45g4</div>
  <div class="block three">4rv4r</div>
  <div class="block one">4rv454</div>
  <div class="block one">ervewrv</div>
  <div class="block two">afrvewrwerb</div>
  <div class="block three">dfvdsf</div>
  <div class="block one">vdfvdf</div>
  <div class="block two">dfw45g4</div>
  <div class="block three">4rv4r</div>
  <div class="block one">4rv454</div>
  <div class="block two">afrvewrwerb</div>
  <div class="block three">dfvdsf</div>
  <div class="block one">vdfvdf</div>
  <div class="block two">dfw45g4</div>
  <div class="block one">ervewrv</div>
  <div class="block two">afrvewrwerb</div>
  <div class="block three">dfvdsf</div>
  <div class="block one">vdfvdf</div>
  <div class="block two">dfw45g4</div>
  <div class="block three">4rv4r</div>
  <div class="block one">4rv454</div>
  <div class="block three">4rv4r</div>
  <div class="block one">4rv454</div>
</div>

This is similar to the effect I'm after except I need the sorting to be done left to right. So in the example, ervewrv should be left of afrvewrwerb.


Solution

  • CSS grid may work for your layout.

    Use grid-column value to order your content.

    .container {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-gap: 15px;
      grid-auto-flow: dense;
    }
    
    .container >div {
      width: 50px;
      height: 50px;
      background: pink;
    }
    
    .col1 {
      grid-column: 1;
    }
    
    .col2 {
      grid-column: 2;
    }
    
    .col3 {
      grid-column: 3;
    }
    <div class='container'>
      <div class='col1' style="height: 80px;">1</div>
      <div class='col3'>2</div>
      <div class='col2'>3</div>
      <div class='col3' style="height: 100px;">4</div>
      <div class='col1'>5</div>
      <div class='col2'>6</div>
      <div class='col1'>7</div>
      <div class='col3'>8</div>
      <div class='col2'>9</div>
    </div>