Search code examples
htmlcsslayoutflexbox

How do I dynamically stretch elements along the flexbox main axis to fill container


I have a "container" element containing two columns. Each column can contain a variable number of items (though generally, the first column will contain more than the second).

HTML:

<div class="container">
   <div class="columns-2">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
   </div>
   <div class="columns-2 stretched">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
   </div>
</div>

Initial Layout

I would like the items in the second column to be vertically stretched to fill the space taken by the first column.

Desired Layout

I have tried every combination of height and flex properties that thought might work but nothing is having the desired effect. The closest that I have come is by explicitly specifying the height of the columns, but this does not work because each column can contain a variable number of items.

CSS:

.container {
  min-width: 22em;
  width: 90%;
  max-width: 25rem;
  min-height: 50px;
  background-color: #ffff99;
  border-style: solid;
  box-sizing: border-box;
  margin: 0.75rem auto;
  overflow: auto;
  padding: 0.5rem 0.5rem;
}

.columns-2 {
  background-color: lightblue;
  border-style: solid;
  box-sizing: border-box;
  min-height: 1em;
  padding: inherit;
  width: 50%;
  float: left;
  display: flex;
  flex-direction: column;
  gap: 0.5em;

  /* Added explicit height */
  height: 160px;
  }

.item {
  background-color: #d8d8d8;
  border-style: solid;
  padding: 0.5rem;
  text-align: center;
  align-items: center;
  justify-content: center;

  /* added */
  height:100%;
}

How can I accomplish this dynamically though CSS?


Solution

  • I think I just figured it out!

    Add "display:flex;" to the container element so that you can use "flex-grow:1;" with both the column and item elements.

    .container {
      background-color: #ffff99;
      border-style: solid;
      box-sizing: border-box;
      min-height: 50px;
      width: 90%;
      min-width: 22em;
      max-width: 25rem;
      margin: 0.75rem auto;
      padding: 0.5rem 0.5rem;
      overflow: auto;
      /* added */
      display: flex;
    }
    
    .columns-2 {
      background-color: lightblue;
      border-style: solid;
      box-sizing: border-box;
      min-height: 1em;
      padding: inherit;
      width: 50%;
      float: left;
      display: flex;
      flex-direction: column;
      gap: 0.5em;
      /* added */
      flex-grow: 1;
    }
    
    .item {
      background-color: #d8d8d8;
      border-style: solid;
      padding: 0.5rem;
      text-align: center;
      align-items: center;
      justify-content: center;
      /* added */
      flex-grow: 1;
    }
    <div class="container">
      <div class="columns-2">
        <div class="item">Item 1</div>
        <div class="item">Item 2</div>
        <div class="item">Item 3</div>
      </div>
      <div class="columns-2 stretched">
        <div class="item">Item 1</div>
        <div class="item">Item 2</div>
      </div>
    </div>