0

The layout I'm trying to achieve is a classic header + sidebar + content + footer with flex filling the whole screen.

The thing I can't understand how to do is make the sidebar content fill the screen space (not the html page but the screen) and if its content is taller than the container make it scroll.

Desidered behaviour

Here the sample code

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

.wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.side {
  display: flex;
  flex-direction: column;
  background-color: lime;
}

.row-wrapper {
  flex-grow: 1;
  display: flex;
  background-color: orange;
  flex-direction: row;
}

.footer {
  height: 40px;
  background-color: purple;
}

.col-wrapper {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  background-color: lightgreen;
}

.header {
  background-color: yellow;
}

.content {
  flex-grow: 1;
  background-color: gold;
}
<div class="wrapper">
  <div class="row-wrapper">
    <div class="side"> side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>
    </div>
    <div class="col-wrapper">
      <div class="header">
        header
      </div>
      <div class="content">
        content
      </div>
    </div>
  </div>
  <div class="footer">
    footer
  </div>
</div>

Look how the content in sidebar is pushing its height making the whole page scroll instead of the sidebar only. The same happen with the content.

enter image description here

Fabio C.
  • 347
  • 4
  • 15

1 Answers1

2

Just added 3 lines to get this working:

  1. max-height: 100vh; to .wrapper to be sure it won't overflow viewport
  2. overflow: auto; to .side to make it scrollable
  3. min-height: 0; to .row-wrapper to prevent it from stretching (read more in another answer)

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

.wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  /* added */
  max-height: 100vh;
}

.side {
  display: flex;
  flex-direction: column;
  background-color: lime;
  /* added */
  overflow: auto;
}

.row-wrapper {
  flex-grow: 1;
  display: flex;
  background-color: orange;
  flex-direction: row;
  /* added */
  min-height: 0;
}

.footer {
  height: 40px;
  background-color: purple;
}

.col-wrapper {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  background-color: lightgreen;
}

.header {
  background-color: yellow;
}

.content {
  flex-grow: 1;
  background-color: gold;
}
<div class="wrapper">
  <div class="row-wrapper">
    <div class="side"> side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>side<br/>
    </div>
    <div class="col-wrapper">
      <div class="header">
        header
      </div>
      <div class="content">
        content
      </div>
    </div>
  </div>
  <div class="footer">
    footer
  </div>
</div>
Jax-p
  • 7,225
  • 4
  • 28
  • 58