2

I'm trying to design the following layout using flex:

initial layout

The target is DIV 1 to fill all available height in the screen and to be scrollable at the same time, so I could have something like this:

enter image description here

This is the basic HTML structure:

* {
  box-sizing: border-box;
}
html, body { height: 100%; }
body {
  margin: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
header {
  width: 100%;
  background-color: #DDD;
}
main {
  flex: 1;
}
.dScroll {
  background-color: #CCF;
}
footer {
  width: 100%;
  background-color: #DDD;
}
<header>
  Header
</header>

<main>
  <div class="wrapper">
    <h2>Title</h2>
    <div class="dScroll">
    This is Div 1
    </div>
    <div>
    This is Div 2
    </div>
  </div>
</main>

<footer>
  Footer
</footer>

Now I'm blocked and I don't know how to continue.

I've tried to use a new flex wrapper insinde the main block, but it does not seem to work. I can easily add a scroll through the overflow property in the MAIN section, but I can't do it in DIV1 while avoiding the whole page scroll. This is what I've done so far: http://jsfiddle.net/d35k06f4/22/

I've also tried different approaches suggested in Stack Overflow, but despite they work in simpler layouts, they don't work in mine.

Is anyone able to point me to the right direction?

MaxiGui
  • 6,190
  • 4
  • 16
  • 33
Carles
  • 418
  • 2
  • 18

4 Answers4

2

I think I have a way to do this without calculating any heights. Here is a Codepen.

Here is the code:

HTML & CSS

* {
  box-sizing: border-box;
}

.container {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 800px;
  border: 1px solid red;
  display: flex;
  flex-direction: column;
}

header {
  background-color: #DDD;
}

main {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  /* for Firefox */
  min-height: 0;
}

.dScroll {
  background-color: #CCF;
  flex-grow: 1;
  overflow: auto;
  /* for Firefox */
  min-height: 0;
}

footer {
  background-color: #DDD;
}
<div class="container">
  <header>
    Header
  </header>

  <main>
    <h2>Title</h2>
    <div class="dScroll">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ullamcorper tortor ac massa interdum, quis mollis orci feugiat. Vivamus fermentum felis ac suscipit pulvinar. Etiam in pretium mi. Mauris malesuada rutrum nisi ut blandit. Nunc eget nulla nec quam mollis volutpat eget nec arcu. Donec tincidunt, tortor a volutpat fringilla, tellus sapien finibus urna, nec faucibus neque dui vitae metus. Sed in egestas nunc. Sed nunc massa, euismod quis lacinia quis, accumsan quis augue. Nam est nunc, sodales at gravida vel, porttitor sed turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus vehicula, lectus non suscipit iaculis, lacus lacus blandit nibh, sit amet iaculis ipsum ante sagittis enim. Ut egestas, nisi sit amet molestie tempus, justo lacus mollis lorem, vitae facilisis lorem erat in risus. Donec est urna, iaculis in elit vel, maximus pharetra est. Ut convallis elit enim, ac aliquet nisl sollicitudin id. Ut rutrum, urna non tempor dapibus, ante lectus rutrum massa, dictum ultrices leo lacus ac arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ullamcorper tortor ac massa interdum, quis mollis orci feugiat. Vivamus fermentum felis ac suscipit pulvinar. Etiam in pretium mi. Mauris malesuada rutrum nisi ut blandit. Nunc eget nulla nec quam mollis volutpat eget nec arcu. Donec tincidunt, tortor a volutpat fringilla, tellus sapien finibus urna, nec faucibus neque dui vitae metus. Sed in egestas nunc. Sed nunc massa, euismod quis lacinia quis, accumsan quis augue. Nam est nunc, sodales at gravida vel, porttitor sed turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus vehicula, lectus non suscipit iaculis, lacus lacus blandit nibh, sit amet iaculis ipsum ante sagittis enim. Ut egestas, nisi sit amet molestie tempus, justo lacus mollis lorem, vitae facilisis lorem erat in risus. Donec est urna, iaculis in elit vel, maximus pharetra est. Ut convallis elit enim, ac aliquet nisl sollicitudin id. Ut rutrum, urna non tempor dapibus, ante lectus rutrum massa, dictum ultrices leo lacus ac arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ullamcorper tortor ac massa interdum, quis mollis orci feugiat. Vivamus fermentum felis ac suscipit pulvinar. Etiam in pretium mi. Mauris malesuada rutrum nisi ut blandit. Nunc eget nulla nec quam mollis volutpat eget nec arcu. Donec tincidunt, tortor a volutpat fringilla, tellus sapien finibus urna, nec faucibus neque dui vitae metus. Sed in egestas nunc. Sed nunc massa, euismod quis lacinia quis, accumsan quis augue. Nam est nunc, sodales at gravida vel, porttitor sed turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus vehicula, lectus non suscipit iaculis, lacus lacus blandit nibh, sit amet iaculis ipsum ante sagittis enim. Ut egestas, nisi sit amet molestie tempus, justo lacus mollis lorem, vitae facilisis lorem erat in risus. Donec est urna, iaculis in elit vel, maximus pharetra est. Ut convallis elit enim, ac aliquet nisl sollicitudin id. Ut rutrum, urna non tempor dapibus, ante lectus rutrum massa, dictum ultrices leo lacus ac arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ullamcorper tortor ac massa interdum, quis mollis orci feugiat. Vivamus fermentum felis ac suscipit pulvinar. Etiam in pretium mi. Mauris malesuada rutrum nisi ut blandit. Nunc eget nulla nec quam mollis volutpat eget nec arcu. Donec tincidunt, tortor a volutpat fringilla, tellus sapien finibus urna, nec faucibus neque dui vitae metus. Sed in egestas nunc. Sed nunc massa, euismod quis lacinia quis, accumsan quis augue. Nam est nunc, sodales at gravida vel, porttitor sed turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus vehicula, lectus non suscipit iaculis, lacus lacus blandit nibh, sit amet iaculis ipsum ante sagittis enim. Ut egestas, nisi sit amet molestie tempus, justo lacus mollis lorem, vitae facilisis lorem erat in risus. Donec est urna, iaculis in elit vel, maximus pharetra est. Ut convallis elit enim, ac aliquet nisl sollicitudin id. Ut rutrum, urna non tempor dapibus, ante lectus rutrum massa, dictum ultrices leo lacus ac arcu.
    </div>
    <div>
      This is Div 2
    </div>
  </main>

  <footer>
    Footer
  </footer>
</div>

I removed the .wrapper you had inside the main tag too.

I found this pen which helped a great deal

MaxiGui
  • 6,190
  • 4
  • 16
  • 33
samkitson
  • 184
  • 9
1

The first thing to do is to fix wrapper height and display as follow:

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

Then just add align items stretch and flex as below:

.dScroll {
  align-items: stretch;
  flex:1; 
}

And trick is done.

Inspired from: How can I make Flexbox children 100% height of their parent?

EDIT: Tomake overflow working you nee to get a height fixed at a point. So just add max-height on wrapper as followed: max-height: calc(100vh - 36px); where 36px is height of header (18px) + footer (18px)

DEMO:

* {
  box-sizing: border-box;
}
html, body { height: 100%; }
body {
  margin: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
header {
  width: 100%;
  background-color: #DDD;
}
main {
  flex: 1;
}
.dScroll {
  background-color: #CCF;
  align-items: stretch;
  flex:1;
  overflow-y: auto;
}
footer {
  width: 100%;
  background-color: #DDD;
}
.wrapper{
  display: flex;
  flex-direction: column;
  height:100%;
  max-height: calc(100vh - 36px);
}
<header>
  Header
</header>

<main>
  <div class="wrapper">
    <h2>Title</h2>
    <div class="dScroll">
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    </div>
    <div>
    This is Div 2
    </div>
  </div>
</main>

<footer>
  Footer
</footer>
MaxiGui
  • 6,190
  • 4
  • 16
  • 33
  • Overflow-y do not seem to work with this solution. I am going to search more – MaxiGui Oct 06 '20 at 10:20
  • This does not seem to work, as you can see in fiddle: http://jsfiddle.net/d35k06f4/24/ – Carles Oct 06 '20 at 10:20
  • Beat me to it! The main trick there is adding the `flex: 1` to the `main` element (`flex-grow: 1`). – samkitson Oct 06 '20 at 10:22
  • This seems to work when the content of the div is lower than the available height, but not when it overflows it. This is why I was turning crazy with this. – Carles Oct 06 '20 at 10:23
  • @samkitson flex:1 to main does not seem to fix the issue: http://jsfiddle.net/d35k06f4/24/ – Carles Oct 06 '20 at 10:24
  • @Carles Ok so I fixed by adding: a max-height on wrapper as followed: `max-height: calc(100vh - 36px);` where 36px is height of header (18px) + footer (18px) – MaxiGui Oct 06 '20 at 10:31
  • 1
    Ohhh you were faster :D i was so slow at typing my answer, its basically the same like yours, just with code comments for a bit in depth understanding why i did what i did. This here is the best solution i think – Warden330 Oct 06 '20 at 10:34
  • Thanks guys, I presume this is tricky, and suspected that the only way to go was to use fixed heights, but I wanted to avoid this, since the layout could fit from phones to big screens. I pressume that I would need to create CSS sections depending on the screen size. – Carles Oct 06 '20 at 10:43
  • hmm if you use responsive height units like vh it should work on mobile screens like this too, you just need to adjust the font-sizes to something thats screen-responsive too, could work – Warden330 Oct 06 '20 at 10:50
  • @Carles yeah and this is what it is doing... So the way I made it it should work on all device – MaxiGui Oct 06 '20 at 10:50
  • yeah actually.. MaxiGui's solution should work fine on phones, all units are responsive, or am i missing something? – Warden330 Oct 06 '20 at 10:52
1

Here is my attempt. I added a lot of comments to the css code so you can see if you understand how and why this works. Colors etc. are just for better understanding where which element is.

Note: Make sure you look at it in full window as the Font-size is not responsive in this example, it will look kinda weird in the small preview-field

* {
  box-sizing: border-box;
}
html, body { height: 100%; }
body {
  margin: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  font-size: 1.5vw;
}
/*I build the CSS new from here on, comments will explain*/
  /*We need fixed heights for everything so we can adjust content to their parents*/
  header {
    height: 5%;
    width: 100%;
    text-align: center;
    background-color: red;
    color: white;
  }
  footer {
    height: 5%;
    width: 100%;
    text-align: center;
    background-color: red;
    color: white;
  }
  main{
    height: 90%;
  }
  .wrapper{
    height: 100%;
    display: flex;
    /*Combination of flex-direction and flex-wrap, we need horizontal build and dont want it to wrap*/
    flex-flow: column nowrap;
    /*put everything in the center*/
    align-items: center;
  }
  .wrapper h2 {
    height: 5%;
    width: 90%;
    text-align: center;
    background-color: grey;
    color: white;
    margin: 0;
    font-size: 2vw;
  }
  .dScroll{
    /*Flex:1 is shorthand for flex-grow 1, flex-shrink 1 and flex-basis 0
    which means: 1: the div will grow with window size, 2: the diw will shrink with window size, 3: the     div wont have a specific starting size but it will take up whats available
    */
    flex: 1;
    /*This will help the div to know it is supposed to take up whatever space is remaining*/
    align-items: stretch;
    background-color: red;
    color: white;
    width: 100%;
    /*add the scroll bar and you are good to go!*/
    overflow-y: scroll;
  }
  .secondary {
    height: auto;
    width: 90%;
    background-color: grey;
    color: white;
  }
<header>
  Header
</header>

<main>
  <div class="wrapper">
    <h2>Title</h2>
    <div class="dScroll">
        This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    This is Div 1 <br>
    </div>
    <div class="secondary">
    This is Div 2
    </div>
  </div>
</main>

<footer>
  Footer
</footer>
Warden330
  • 999
  • 1
  • 5
  • 11
-3

use this....

.dScroll {
  background-color: #CCF;
  overflow: hidden;
  overflow-y: scroll;
  height: 100px;
}
Ishita Ray
  • 672
  • 3
  • 8
  • Thanks for your interest, but this fixes the height to 100px and I do really need to fill the remaining space in height, that's the tricki part. – Carles Oct 06 '20 at 10:05
  • 1
    @MaxiGui Don't worry that much, no need to be rude with her. – Carles Oct 06 '20 at 10:08
  • Thanks Carles, but I still dont get this people posting random codes and expecting for positive answer. – MaxiGui Oct 06 '20 at 10:09