fikkatra
fikkatra

Reputation: 5792

Flexbox: how to make element scrollable without taking up remaining space

I have 2 divs, yellow and red. The yellow div has a variable content. enter image description here

I want to achieve the following:

How can I achieve this with flexbox?

I succeeded in making the yellow box scrollable, and keeping the red box always visible. However, my solution displays the yellow box always at the bottom of the page, which is not what I want.

.page {
  height: 120px;
  width: 300px;
  display: flex;
  flex-direction: column;
  border: 4px solid gray;
  padding: 10px;
}

.yellow {
  flex: 1 1 0;
  overflow: auto;
  min-height: 0;
  border: 4px solid #F7B64C;
  padding: 10px;
  margin-bottom: 10px;
}

.red {
  border: 4px solid #F05467;
  padding: 10px;
}
Example 1: yellow div has a lot of content and correctly becomes scrollable:
<div class="page">
  <div class="yellow">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </div>
  <div class="red"></div>
</div>
<br/>
<br/> Example 2: yellow div has little content, incorrectly pushes red div to the bottom:
<div class="page">
  <div class="yellow">
    Lorem ipsum dolor sit amet.
  </div>
  <div class="red"></div>
</div>

How can I make the yellow box take up only the space it actually needs, and not take up the remaining space?

Upvotes: 0

Views: 46

Answers (1)

John Li
John Li

Reputation: 7447

It seems that the default behavior of flex box might achieve the desired result without additional settings.

In the following example, try click the buttons to adjust the amount of content in yellow and red.

An additional spacer div after red can be added to further enforce the layout, but it seems to be unnecessary in this use case.

.spacer {flex: 1}
<div class="spacer"></div>

Example:

const btns = document.querySelectorAll("button");
const yellow = document.querySelector(".yellow");
const red = document.querySelector(".red");

btns.forEach((btn, i) =>
  btn.addEventListener("click", () => {
    yellow.innerText = i === 0 ? "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." : i === 1 ? "Lorem ipsum dolor sit amet." : yellow.innerText;
    red.innerText = i === 2 ? "Duis aute irure dolor in reprehenderit in velit eu fugiat nulla pariatur." : i === 3 ? "" : red.innerText;
  })
)
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: flex;
}

.control {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 300px;
  margin: 10px 10px;
  gap: 10px;
}

button {
  padding: 6px;
}

section {
  height: 180px;
  width: 300px;
  display: flex;
  flex-direction: column;
  border: 4px solid gray;
  padding: 10px;
  margin: 3px 10px;
}

.yellow {
  overflow: auto;
  min-height: 0;
  border: 4px solid #f7b64c;
  padding: 10px;
  margin-bottom: 10px;
}

.red {
  border: 4px solid #f05467;
  padding: 10px;
}

/* .spacer {
  flex: 1;
} */
<div class="control">
  <button>Example 1: Lots of content in yellow</button>
  <button>Example 2: Little content in yellow</button>
  <button>Example 3: Some content in red</button>
  <button>Example 4: No content in red</button>
</div>
<br />
<section>
  <div class="yellow">Try click buttons to see examples</div>
  <div class="red"></div>
  <!--   <div class="spacer"></div> -->
</section>

Upvotes: 2

Related Questions