1

I have a pretty simple page setup in the following manner using flexboxes:

enter image description here

The blue div is supposed to make up 25% in height and the violet div 75%. In case there are too many lines in the blue div, it should stay the same size an show a scrollbar. This works for a few lines, but breaks at some point and the blue div overflows and grows into the violet one. I'm new to flexboxes, so I don't really understand why this is happening. Would I be better off not using flexboxes? Thankful for any hints or pointer at this point.

This is the code I use (run in full page):

function lines(noLines) {
  var text = "line</br>".repeat(noLines);
  document.getElementById("lower").innerHTML = text;
}
* {
  box-sizing: border-box;
}

.body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

#static1 {
  height: 30px;
  width: 100%;
  background-color: red;
}

#static2 {
  height: 40px;
  width: 100%;
  background-color: orange;
}

#content {
  display: flex;
  flex: 1;
}

#left {
  width: 40%;
  background-color: yellow;
}

#right {
  width: 60%;
  display: flex;
  flex-direction: column;
}

#upper {
  flex: 3 0;
  background-color: violet;
}

#lower {
  flex: 1;
  background-color: blue;
  overflow: auto;
}
<div class="body">
  <div id="static1">Some static div</div>
  <div id="static2">Another static div. Flexbox below fills rest of remaining screen.</div>
  <div id="content">
    <div id="left">
      Left part, fixed width in percentage.</br>
      Click to enter lines into the bottom right:</br>
      <button onclick=lines(20)>Few Lines</button>
      <button onclick=lines(200)>Many Lines</button>
    </div>
    <div id="right">
      <div id="upper">Flexbox with flex=3.</div>
      <div id="lower">Flexbox with flex=1.</div>
    </div>
  </div>
</div>

3 Answers 3

2

For the overflow property to work properly, the container needs an actual height or max-height. Flex heights (you have flex: 1 on .content) won't cut it.

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap. ~ MDN

Since you already know the height of the primary container (100vh) and the first two rows (30px and 40px), the rest is simple using the calc() function.

function lines(noLines) {
  var text = "line</br>".repeat(noLines);
  document.getElementById("lower").innerHTML = text;
}
.body {
  display: flex;
  flex-direction: column;
  height: 100vh;  /* adjustment */
}

#static1 {
  flex-shrink: 0;  /* disable shrinking */
  height: 30px;
  /* width: 100%; */
  background-color: red;
}

#static2 {
  flex-shrink: 0;  /* disable shrinking */
  height: 40px;
  /* width: 100%; */
  background-color: orange;
}

#content {
  height: calc(100vh - 70px); /* new */
  display: flex;
  /* flex: 1; */ /* may work in some browsers, but not reliable */
}

#left {
  width: 40%;
  background-color: yellow;
}

#right {
  width: 60%;
  display: flex;
  flex-direction: column;
}

#upper {
  flex: 3 0;
  background-color: violet;
}

#lower {
  flex: 1;
  background-color: aqua; /* adjusted for illustration */
  overflow: auto;
}

body {
  margin: 0; /* new; override browser default  */
}

* {
  box-sizing: border-box;
}
<div class="body">
  <div id="static1">Some static div</div>
  <div id="static2">Another static div. Flexbox below fills rest of remaining screen.</div>
  <div id="content">
    <div id="left">
      Left part, fixed width in percentage.<br> Click to enter lines into the bottom right:<br>
      <button onclick=lines(20)>Few Lines</button>
      <button onclick=lines(200)>Many Lines</button>
    </div>
    <div id="right">
      <div id="upper">Flexbox with flex=3.</div>
      <div id="lower">Flexbox with flex=1.</div>
    </div>
  </div>
</div>

jsFiddle demo

Sign up to request clarification or add additional context in comments.

1 Comment

I tried avoiding explicitly calculating the container height with hard-coded values or via JavaScript and tried relying on HTML and CSS only. But for the time being this is probably what I'm going with, thank you.
0

I hope this is what you mean, but If I'm wrong, apologies. The problem I can see lies in the way you are using flex: 1 & flex: 3 to define the proportions of the right column, without specifying to what height their parent container has, i.e. #right has no height, so the box can always expand as it gets more filled with content.

Please try this, I hope this works and if I can answer anything else, just ask please.

The only thing I changed was your CSS and added max-height: calc(100vh - 70px); to the #right div. And changed overflow: auto; to overflow-y: scroll;

* {
  box-sizing: border-box;
}

.body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  
}

#static1 {
  height: 30px;
  width: 100%;
  background-color: red;
}

#static2 {
  height: 40px;
  width: 100%;
  background-color: orange;
}

#content {
  display: flex;
  flex: 1;
}

#left {
  width: 40%;
  background-color: yellow;
}

#right {
  width: 60%;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 70px);
}

#upper {
  flex: 3;
  height: 75%;
  background-color: violet;
}

#lower {
  flex: 1;
  height: 25%;
  background-color: blue;
  overflow-y: scroll;
} 

Comments

0

Change the top part of CSS to this:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.