'Three columns with equal height corresponding rows in each column

I need to create a layout in which you have three columns, in each column the corresponding row needs to have the same height. The requirements for this are.

  1. Three columns
  2. Inside each column there are multiple rows.
  3. Each corresponding row must be the same height.
  4. On mobile the columns will turn into a slider.

enter image description here

I've considered 2 layout options for this.

  1. target each row in each column and set the height with Javascript

<div class="container">
  <div class="col">
    <div class="row">row 1</div>
    <div class="row">row 2</div>
    <div class="row">row 3</div>
  </div>
  <div class="col">
    <div class="row">row 1</div>
    <div class="row">row 2</div>
    <div class="row">row 3</div>
  </div>
  <div class="col">
    <div class="row">row 1</div>
    <div class="row">row 2</div>
    <div class="row">row 3</div>
  </div>
</div>

This layout is ideal as I can target the column and add the drop shadow styles without having to target each row and apply to each one. Implementing the slider on mobile would be easier as there is three container columns. But, looping through each column and getting the corresponding row and updating the height on each one seems like a lot of work especially since the height will need to be recalculated every time there is an api call (there's filter above with allow you to update the data).

  1. Use flex

<div class="container">
  <div class="row">
    <div class="col">
      row 1 col 1
    </div>
    <div class="col">
      row 1 col 2
    </div>
    <div class="col">
      row 1 col 3
    </div>
  </div>
  <div class="row">
    <div class="col">
      row 2 col 1
    </div>
    <div class="col">
      row 2 col 2
    </div>
    <div class="col">
      row 2 col 3
    </div>
  </div>
  <div class="row">
    <div class="col">
      row 3 col 1
    </div>
    <div class="col">
      row 3 col 2
    </div>
    <div class="col">
      row 3 col 3
    </div>
  </div>
</div>

This approach is appealing because I don't need to use JS to set the height of each corresponding row in each column. But, i'll need to set the individual styles like drop shadows to each row which means i'll need to use all sorts of trickery so as not to apply the drop shadow to the top and bottom of each row, there's also the risk that this will not display correctly in different browsers (needs to go back as far as IE 10). Also the only slider effect i'll be able to active is overflow scroll which doesn't fit the requirments.

So, my questions are, are there other options i'm not considering? What would you do?



Solution 1:[1]

I would consider option 1 for the following reasons:

  • Your markup is semantically correct (3 columns, each with some rows) and clean
  • Your column styles can easily be applied
  • Looping through all rows just to calculate the maximum height isn't that cumbersome especially if you only have a few rows.

A solution with vanilla JavaScript could look like the following. You can wrap the code into a function and call it, whenever your filter is applied:

var rows = document.querySelectorAll(".col:nth-child(1) > .row").length, n
for (n = 1; n <= rows; ++n) {
  var cells = document.querySelectorAll('.row:nth-child(' + n + ')')
  var maxHeight = 0, i
  for (i = 0; i < cells.length; ++i) {
    maxHeight = (cells[i].clientHeight > maxHeight) ? cells[i].clientHeight : maxHeight
  }
  cells.forEach(function(cell){
    cell.style.height = Number(maxHeight-10) + 'px'
  })
}
.col {
  display: inline-block;
  width: calc(33% - 41px);
  margin: 10px 10px;
  padding: 10px;
  border-radius: 15px;
  box-shadow: 0 0 20px #aaa;
  vertical-align: top;
}
.row {
  border-top: 3px solid black;
  margin: 5px 0;
  padding: 5px;
}
<div class="container">
  <div class="col">
    <div class="row">row 1 Compare text 1</div>
    <div class="row">row 2</div>
    <div class="row">row 3</div>
  </div>
  <div class="col">
    <div class="row">row 1 Compare text 1 this text is longer</div>
    <div class="row">row 2</div>
    <div class="row">row 3 with a little more text</div>
  </div>
  <div class="col">
    <div class="row">row 1 Compare text 1 this text is even much much longer</div>
    <div class="row">row 2</div>
    <div class="row">row 3</div>
  </div>
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1