Scrollable element inside a container filling remaining space

Viewed 51

I have a container flexbox element filling the remaining space inside a container. Inside that, I want an element that can fill the parent and scroll on overflow. Problem is, is always just overflows the container, and I can't set height: 100%, since that won't take into account a header with a dynamic height.

Please see this code snippet for a clearer example. I want to scroll on the purple div, but the red div keeps overflowing the blue div, which it shouldn't. I would highly prefer to not change the HTML, only the CSS.

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.wrapper {
  height: 100%;
  padding: 10px;
  box-sizing: border-box;
  background: blue;
  width: 300px;
  display: flex;
  flex-direction: column;
}

.header {
  padding: 10px;
  background: green;
}

.content {
  padding: 10px;
  background: red;
  flex: 1;
  box-sizing: border-box;
}

.boxes {
  padding: 10px;
  background: purple;
  height: 100%;
  overflow-y: auto;
  box-sizing: border-box;
}

.box {
  height: 200px;
  border: 1px solid black;
  box-sizing: border-box;
  background: orange;
}
<div class="wrapper">
  <div class="header">
    This is the header.
    It has multiple lines.
  </div>
  <div class="content">
    <div class="boxes">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
  </div>
</div>

3 Answers

Not sure if this is what you are looking for. I have just added overflow: scroll to content class and it seems to work.

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.wrapper {
  height: 100%;
  padding: 10px;
  box-sizing: border-box;
  background: blue;
  width: 300px;
  display: flex;
  flex-direction: column;
}

.header {
  padding: 10px;
  background: green;
}

.content {
  padding: 10px;
  background: red;
  flex: 1;
  box-sizing: border-box;
  overflow-y: scroll;
}

.boxes {
  padding: 10px;
  background: purple;
  height: 100%;
  overflow-y: auto;
  box-sizing: border-box;
}

.box {
  height: 200px;
  border: 1px solid black;
  box-sizing: border-box;
  background: orange;
}
<div class="wrapper">
  <div class="header">
    This is the header. It has multiple lines.
  </div>
  <div class="content">
    <div class="boxes">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
  </div>
</div>

Using overflow-y: hidden; on the .content hides everything that would overflow it's parent container

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.wrapper {
  height: 100%;
  padding: 10px;
  box-sizing: border-box;
  background: blue;
  width: 300px;
  display: flex;
  flex-direction: column;
}

.header {
  padding: 10px;
  background: green;
}

.content {
  padding: 10px;
  background: red;
  flex: 1;
  box-sizing: border-box;
  overflow: hidden;
}

.boxes {
  padding: 10px;
  background: purple;
  height: 100%;
  overflow-y: auto;
  box-sizing: border-box;
}

.box {
  height: 200px;
  border: 1px solid black;
  box-sizing: border-box;
  background: orange;
}
<div class="wrapper">
  <div class="header">
    This is the header.
    It has multiple lines.
  </div>
  <div class="content">
    <div class="boxes">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
  </div>
</div>

Here, if you check, I have given max-height: calc(100% - 38px); to the .content to have a max-height. Giving flex: 1 will provide it a min-height only, it will grow more if the there is content and there is space in its wrapper. So by providing a max-height, we can avoid this issue

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.wrapper {
  height: 100%;
  padding: 10px;
  background: blue;
  width: 300px;
  display: flex;
  flex-direction: column;
}

.header {
  padding: 10px;
  background: green;
}

.content {
  padding: 10px;
  background: red;
  flex: 1;
  max-height: calc(100% - 38px);
}

.boxes {
  padding: 10px;
  background: purple;
  overflow-y: auto;
  max-height: 100%;
}

.box {
  height: 200px;
  border: 1px solid black;
  background: orange;
}
<div class="wrapper">
  <div class="header">
    This is the header.
    It has multiple lines.
  </div>
  <div class="content">
    <div class="boxes">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
  </div>
</div>

Related