Fixed Header, Footer, and Sidebars with Scrolling Content Area in Center

Fixed Header, Footer, and Sidebars with scrolling content area in center

Using display:grid

This uses several new features of CSS that may or may not be supported in your browser of choice. These include Grid Layout, CSS Variables, and position:sticky. CSS Variables can be worked around with static values and Grid/position:sticky can degrade gracefully with @supports.

/* Remove unnecessary margins/padding */html, body { margin: 0; padding: 0 }
.wrapper { display: grid; /* Header and footer span the entire width, sidebars and content are fixed, with empty space on sides */ grid-template-areas: "header header header header header" "empty_left sidebar_1 content sidebar_2 empty_right" "footer footer footer footer footer"; /* Only expand middle section vertically (content and sidebars) */ grid-template-rows: 0fr 1fr 0fr; /* 100% width, but static widths for content and sidebars */ grid-template-columns: 1fr 100px 400px 100px 1fr; /* Force grid to be at least the height of the screen */ min-height: 100vh;}.header { grid-area: header;
/* Stick header to top of grid */ position: sticky; top: 0; /* Ensure header appears on top of content/sidebars */ z-index: 1;
/* General appearance */ background-color: #FCFF34; text-align: center; font-size: 1rem; line-height: 1.5; padding: 1rem;}/* Save header height to properly set `padding-top` and `margin-top` for sticky content */:root { --header-height: calc(1rem * 1.5 + 1rem * 2);}
.sidebar-1 { grid-area: sidebar_1;}.sidebar-2 { grid-area: sidebar_2;}.sidebar-1,.sidebar-2 { display: flex; flex-direction: column; position: sticky; top: 0;
/* Styling to match reference */ background-color: #BC514F;}
.content { grid-area: content;
/* General appearance */ background-color: #99BB5E;}.footer { grid-area: footer;
/* Stick footer to bottom of grid */ position: sticky; bottom: 0;
/* General appearance */ background-color: #FCFF34; text-align: center; font-size: .8rem; line-height: 1.5; padding: .5rem;}/* Save footer height to properly set `bottom` and `min-height` for sticky content */:root { --footer-height: calc(.8rem * 1.5 + .5rem * 2);}
.sticky-spacer { flex-grow: 1;}.sticky-content { position: sticky; bottom: var(--footer-height); min-height: calc(100vh - var(--footer-height)); box-sizing: border-box;
--padding: 10px; padding: calc(var(--header-height) + var(--padding)) var(--padding) var(--padding); margin-top: calc(0px - var(--header-height));}
<div class="wrapper"><div class="header">Header (Absolute)</div><div class="sidebar-1">  <div class="sticky-spacer"></div>  <div class="sticky-content">Sidebar 1 Absolute position, Fixed width</div></div><div class="content">  <div class="sticky-spacer"></div>  <div class="sticky-content">    Scrollable content<br><br>    line 1<br><br>    line 2<br><br>    line 3<br><br>    line 4<br><br>    line 5<br><br>    line 6<br><br>    line 7<br><br>    line 8<br><br>    line 9<br><br>    line 10<br><br>    line 11<br><br>    line 12<br><br>    line 13<br><br>    line 14<br><br>    line 15<br><br>    line 16<br><br>    line 17<br><br>    line 18<br><br>    line 19<br><br>    line 20  </div></div><div class="sidebar-2">  <div class="sticky-spacer"></div>  <div class="sticky-content">    Sidebar 2 Absolute position, Fixed width<br><br>  line 1<br><br>  line 2<br><br>  line 3<br><br>  line 4<br><br>  line 5<br><br>  line 6<br><br>  line 7<br><br>  line 8<br><br>  line 9<br><br>  line 10  </div></div><div class="footer">Footer (Absolute)</div></div>

Fixed header, footer with scrollable content

Something like this

<html>
<body style="height:100%; width:100%">
<div id="header" style="position:absolute; top:0px; left:0px; height:200px; right:0px;overflow:hidden;">
</div>
<div id="content" style="position:absolute; top:200px; bottom:200px; left:0px; right:0px; overflow:auto;">
</div>
<div id="footer" style="position:absolute; bottom:0px; height:200px; left:0px; right:0px; overflow:hidden;">
</div>
</body>
</html>

Fixed header, scrollable content and fixed footer layout using flexbox only

Adding flex: 1 1 auto; and height: 0px; will make the .content scrollable.

However, since there's a height: 100%; on the .container, .content will shrink, use a min-height to prevent this;

.container {
display: flex;
flex-direction: column;
height: 100%;
width: 400px;
background-color: white;
border: 1px solid black;
text-align: center;
border-collapse: collapse;
overflow-y: hidden;
}

.header {
justify-self: flex-start;
background-color: #cdcdcd;
padding: 8px;
}

.content {
flex: 1 1 auto;
height: 0px;
min-height: 300px;

border: 1px solid black;
padding: 8px;
overflow-y: scroll;
}

.footer {
justify-self: flex-end;
background-color: #cdcdcd;
padding: 8px;
}
<div class="container">
<div class="header">Header</div>
<div class="content">
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
<p>Very tall content</p>
</div>

<div class="footer">
Footer
</div>
</div>

Layout with fixed header and footer, fixed width sidebar and flexible content

The magic is in box-sizing:border-box;. For compatibility with Firefox, chrome<10, and safari<5.1, add the -webkit- and -moz- prefixes. IE supports it as of 8.0.

<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<title>very structured layout</title>
<style type='text/css'>
* {margin:0; padding:0;}
body {background:#fff; position:absolute; width:100%; height:100%;}
#main {background:#888; height:100%; padding:60px 0 40px; box-sizing:border-box;}
#head {background:#f8f; position:absolute; width:100%; height:60px;}
#left {background:#ff8; float:left; width:250px; height:100%; overflow:scroll;}
#right {background:#8f8; height:100%; overflow:scroll;}
#foot {background:#f88; position:absolute; bottom:0; width:100%; height:40px;}​
</style>
</head>
<body>
<div id='head'>header: width = 100%, height = 40px</div>
<div id='main'>
<div id='left'>left: width = 250px, height = 100%</div>
<div id='right'>right: width = 100% - 250px, height = 100%</div>
</div>
<div id='foot'>foot: width = 100%, height = 60px</div>​
</body>
</html>

fiddle

edit: after Andres' solution made me realize I could achieve greater compatibility, I messed around a bit and came up with an alternate solution, which I think is more intuitive as well. It doesn't work in IE7, but it does work in IE8.

The page is the same as the above, with the only change being that the CSS is replaced with this:

*      {margin:0; padding:0;}
body {background:#fff;}
#main {background:#888; position:absolute; top:40px; bottom:60px; width:100%;}
#head {background:#f8f; position:absolute; width:100%; height:40px;}
#left {background:#ff8; position:absolute; width:250px; height:100%; overflow:scroll;}
#right {background:#8f8; margin-left:250px; height:100%; overflow:scroll;}
#foot {background:#f88; position:absolute; bottom:0; width:100%; height:60px;}

fiddle

Note that, for both versions, #head and #foot need to have an overflow property other than visible if their content would otherwise extend off the page.



Related Topics



Leave a reply



Submit