DlafCreative DlafCreative - 2 months ago 19
HTML Question

Sticky header and footer with autoscrolling content

I'm trying to make a layout where the header and the footer would be sticky at their position, and the content would have a minimum height and shows a scrollbar if the viewport height is too small.

I successfully performed it, on this codepen :
http://codepen.io/DlafCreative/pen/wzdOEN
inpired from another one.

The problem is that the HTML markup is not convenient with the framework I use (Angular2), as the

<header>
is at the same level that
<main>
, and the
<footer>
is outside
<prop-wrapper>
.

In my app, header should remain the same in all pages, whereas footer should be dynamic. So what I'd like is having
<header>
before
<prop-wrapper>
, and
<footer>
after
<main>
, like this forked codepen : http://codepen.io/DlafCreative/pen/xEAXxy
This way, I could more easily define the content of

Now, I struggle to get the same behavior with that markup. Help would be welcome !
Thx a lot :)

Answer

This might help you. So how it works is given below:

  1. First of all, remove the browser's default margin using:

    body {
      margin: 0;
    }
    
  2. Make your prop-body a flexbox by using display: flex. You will give flex-direction: column to make it flex vertically. To fill the whole screen height give height: 100vh:

    prop-body {
      display: flex;
      flex-direction: column;
      height: 100vh;
    }
    
  3. Add flex: 1 to prop-wrapper so that it fills the space between header and footer.

    This is a shorthand that means:

    a. flex-grow is 1 b. flex-shrink is 1

    which means that the height of this flex item will fill the remaining space by growing or shrinking.

See flex: 1 meaning here.

flex: Equivalent to flex: 1 0. Makes the flex item flexible and sets the flex basis to zero, resulting in an item that receives the specified proportion of the free space in the flex container. If all items in the flex container use this pattern, their sizes will be proportional to the specified flex factor.

  1. Now you can easily see the layout- we are using some nested flexboxes.

body {
  margin: 0;
}
prop-body {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
prop-body header {
  background: grey;
  padding: 20px;
}
prop-body prop-wrapper {
  display: flex;
  flex-direction: column;
  background: lightblue;
  flex: 1;
}
prop-body prop-wrapper main {
  overflow-y: auto;
  flex: 1;
}
prop-body prop-wrapper main p {
  padding: 50px;
}
footer {
  display: flex;
  background: pink;
  min-height: 50px;
  height: 10vh;
}
footer .footer-content {
  flex: 1;
  background: plum;
}
<prop-body>
  <header>Header</header>
  <prop-wrapper>
    <main>
      <p>CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT
        CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT</p>
    </main>
    <footer>
      <div class="footer-content">
        Footer
      </div>
    </footer>
  </prop-wrapper>
</prop-body>