0

I want to achieve a layout like this using flexbox:

---------------------
|                   |
---------------------
|     |             |
|     |             |
|     |             |
---------------------
|                   |
---------------------

I started with a simplified version:

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

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

.red {
  background-color: red;
  height: 20px;
  min-height: 20px;
}

.content {
  flex: 1;
  overflow-y: scroll;
}
<div class="container">
  <div class="red"></div>
  <div class="content">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
  </div>
  <div class="red"></div>
</div>

The key point here is that the content div scrolls internally. Now I want to implement another flex-container like this:

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

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

.red {
  background-color: red;
  height: 20px;
  min-height: 20px;
}

.blue {
  display: flex;
  flex: 1;
  background-color: blue;
}

.green {
  width: 30px;
  background-color: green;
}

.content {
  flex: 1;
  overflow-y: scroll;
}
<div class="container">
  <div class="red"></div>
<div class="blue">           
  <div class="green"></div>
  <div class="content">
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
  </div>
  </div>
  <div class="red"></div>
</div>

Now the behavior changes and the red div on the bottom disappears because the central div takes as much space as is needed by the content.

How can I change the behavior so that the content does not pushes away

Alexander Schmidt
  • 5,631
  • 4
  • 39
  • 79

2 Answers2

2

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

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

.red {
  background-color: red;
  height: 20px;
  min-height: 20px;
}

.blue {
  display: flex;
  flex: 1;
  background-color: blue;
  overflow-y: hidden; /* added */
}

.green {
  width: 30px;
  background-color: green;
}

.content {
  flex: 1;
  overflow-y: scroll;
}
<div class="container">
  <div class="red"></div>
<div class="blue">           
  <div class="green"></div>
  <div class="content">
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
  </div>
  </div>
  <div class="red"></div>
</div>

Add overflow: hidden to .blue. If not added the scroll behavior in .content won't activate because its parent would stretch to fit the content.

Richard Yan
  • 1,276
  • 10
  • 21
  • `min-height:0;` Instead – Rainbow Jun 07 '20 at 14:10
  • @ZohirSalak hmmm. This also works, but I don't see why. Would you care to explain what's happening under the hood? This wouldn't be my preferred approach but I'm just surprised it works at all. – Richard Yan Jun 07 '20 at 14:14
  • That is actually the right approach https://stackoverflow.com/a/36247448/7148391 overflow auto or scroll works because it also ignores children's size – Rainbow Jun 07 '20 at 14:16
  • Ah, I see. That actually makes a lot of sense. My answer was written without knowledge of this default behavior, so I would say it's easier to understand. But I do admit setting min-height should be the proper way. – Richard Yan Jun 07 '20 at 14:19
0

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

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

.red {
  background-color: red;
  height: 20px;
  min-height: 20px;
}

.blue {
  display: flex;
  flex: 1;
  max-height: 80vh;
  background-color: blue;
}

.green {
  width: 30px;
  background-color: green;
}

.content {
  flex: 1;
  overflow-y: scroll;
}
<div class="container">
  <div class="red"></div>
<div class="blue">           
  <div class="green"></div>
  <div class="content">
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
  </div>
  </div>
  <div class="red"></div>
</div>

Set max-height on .content. That way it doesn't matter what the height of any other elements around it is, it will still scroll how you want.

EDIT

Better yet, add it to .blue.

Daniel_Knights
  • 7,940
  • 4
  • 21
  • 49
  • To what value should I set it. i want the site to behave exactly as in the first snippet but simply with a nested flex. setting the height to a fixed value would meen to leave the purpose of flexbox. – Alexander Schmidt Jun 07 '20 at 14:04
  • Setting `max-height` doesn't mean setting the actual height of the `div`, it just means that the height won't extend beyond whatever height you set and `overflow: scroll` will still work. – Daniel_Knights Jun 07 '20 at 14:06
  • As to what value, it's up to you. However high you want the `div`s max-height to be. – Daniel_Knights Jun 07 '20 at 14:07