Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a flexbox row the height of shortest child element?

Tags:

html

css

flexbox

I am having some difficulty using Flexbox. The goal is to have a row that is the same height as the shortest child element. Take two images as examples, one has 200px height the other has 120px height. This example below works as intended when <img> elements are the direct children of the flex element.

.row {
  display: flex;
  width: 100%;
  background: orange;
}
<div class="row">
   <img src="https://s3.amazonaws.com/imagetest.com/purple_200.jpg" />
   <img src="https://s3.amazonaws.com/imagetest.com/teal_120.jpg" />
</div>

However, in the following example, the height of the flexbox element expands to the tallest child element:

.row {
  display: flex;
  width: 100%;
  background: orange;
}
<div class="row">
  <div class="col">
    <img src="https://s3.amazonaws.com/imagetest.com/purple_200.jpg" />
  </div>
  <div class="col">
    <img src="https://s3.amazonaws.com/imagetest.com/teal_120.jpg" />
  </div>
</div>

What is a solution to make <div class="row"> the height of the shortest child element?

like image 785
Joel Hoelting Avatar asked Jan 22 '19 23:01

Joel Hoelting


2 Answers

You can adjust the height of other columns to match the column of your choice (e.g. the shortest column) by positioning other columns absolutely in relation to the column wrapper.

Below you can find the solution with :not() to make it easier to indicate by a class name which column you want to pick as the column height reference
https://developer.mozilla.org/en-US/docs/Web/CSS/:not

No JavaScript needed!

.row {
  display: flex;
  background: orange;
}

img {
  vertical-align: top; /* to get rid of default bottom padding in images */
}

.row > div:not(.dynamic-max-height-column) {
  position: relative;
}

.row > div:not(.dynamic-max-height-column) > img {
  position: absolute;
  max-height: 100%;
}
<div class="row">
  <div class="dynamic-max-height-column">
    <img src="https://dummyimage.com/300x200/575757/ffffff" alt="">
  </div>
  <div>
    <img src="https://dummyimage.com/300x300/b3b3b3/ffffff" alt="" />
  </div>
</div>
like image 51
Adrian Bienias Avatar answered Nov 14 '22 04:11

Adrian Bienias


As pointed out by @Michael_B, the first example only appears correct because of align-items: stretch.

You cannot do this with flex, or pure CSS. If we had a CSS selector which could select the shortest sibling, then we could have done this - but we don't!

You can either use a fixed height for the parent:

.row {
  display: flex;
  width: 100%;
  height: 120px; /* fixed height */
  background-color: orange;
}
<div class="row">
   <img src="https://s3.amazonaws.com/imagetest.com/purple_200.jpg" />
   <img src="https://s3.amazonaws.com/imagetest.com/teal_120.jpg" />
</div>

Or use JavaScript to do the logic for you:

$( document ).ready(function() {
    var min_height = -1;  
    
    $("img").each(function(  ) {
        if ($(this).height() < min_height || min_height == -1) {
            min_height = $(this).height();
        }
        $('.row').height(min_height);
    })
    
    $("img").each(function(  ) {
        $(this).height(min_height);
    });
});
.row {
  display: flex;
  width: 100%;
  background-color: orange;
  align-items: flex-start
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
   <img src="https://s3.amazonaws.com/imagetest.com/purple_200.jpg" />
   <img src="https://s3.amazonaws.com/imagetest.com/teal_120.jpg" />
</div>
like image 38
Hooman Bahreini Avatar answered Nov 14 '22 05:11

Hooman Bahreini