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
Use Excel Vba to Click on a Button in Internet Explorer, When The Button Has No "Name" Associated
How to Show PDF File in Ionic App with Out Download
Schema.Org Newsarticle: Invalid Value for Logo Property
How to Fix "Insecure Content Was Loaded Over Https, But Requested an Insecure Resource"
Can't Show Some Websites in Iframe Tag
How to Create a Wavy Shape CSS
Add Border to Div Increase Div Width
How to Control The Width of a Label Tag
Diagonal Stripes That Are 1Px Wide
Xpath to Select Between Two HTML Comments Is Not Working
How to Set the Space Between Lines in a Div Without Setting Line Height
Inverted Scooped Corners Using CSS
Force <A Download /> to Download Image Instead of Opening Url Link to Image
Select First Occurring Element After Another Element
CSS Zigzag Border with a Textured Background
File Opens Instead of Downloading in Internet Explorer in a Href Link
How to Remove The Previously Selected Option from a Drop-Down Menu in a Table