CSS flex layout

Viewed 108

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?

4 Answers

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

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>

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>

use this....

.dScroll {
  background-color: #CCF;
  overflow: hidden;
  overflow-y: scroll;
  height: 100px;
}
Related