49

I have 2 main divs, the header and a scrolling list contained in a div. I want the header to always remain at the top of the page, and the scrolling list below. The scrollbar should be attached to the scrolling div and not to the whole page, i.e. the scrollbar does not appear on the right of the header, just the scrolling div.

This is what i'm trying to achieve:

______________________
|_______header_______|
|                  |*|
|   Container Div  |*|
|                  |*|
|                  |*|
|                  |*|
|                  |*|
|                  |*|
----------------------

* = scrollbar

The layout should be fluid and if the window is stretched vertically, only the container div and it's scrollbar should get longer.

I don't want to position the header position: fixed; as then the scrollbar will be on the right of it instead of underneath it.

Garywoo
  • 607
  • 1
  • 6
  • 9

4 Answers4

62

HTML:

​<div class="header">This is the header</div>
<div class="content">This is the content</div>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

CSS:

​.header
{
    height:50px;
}
.content
{
    position:absolute;
    top: 50px;
    left:0px;
    right:0px;
    bottom:0px;
    overflow-y:scroll;        
}​
bhamlin
  • 5,177
  • 1
  • 22
  • 17
  • Thanks, that's exactly it, such simple solution, don't know why it escaped me, haha. – Garywoo Mar 13 '12 at 03:37
  • 7
    Use `overflow-y:auto;` if there's a chance that `.content` doesn't reach the bottom of the page. It'll remove the scrollbar in that case. – ki9 Aug 15 '16 at 00:47
16

Found the flex magic.

Here's an example of how to do a fixed header and a scrollable content. Code:

<!DOCTYPE html>
<html style="height: 100%">
  <head>
    <meta charset=utf-8 />
    <title>Holy Grail</title>
    <!-- Reset browser defaults -->
    <link rel="stylesheet" href="reset.css">
  </head>
  <body style="display: flex; height: 100%; flex-direction: column">
    <div>HEADER<br/>------------
    </div>
    <div style="flex: 1; overflow: auto">
        CONTENT - START<br/>
        <script>
        for (var i=0 ; i<1000 ; ++i) {
          document.write(" Very long content!");
        }
        </script>
        <br/>CONTENT - END
    </div>
  </body>
</html>

* The advantage of the flex solution is that the content is independent of other parts of the layout. For example, the content doesn't need to know height of the header.

For a full Holy Grail implementation (header, footer, nav, side, and content), using flex display, go to here.

AlikElzin-kilaka
  • 34,335
  • 35
  • 194
  • 277
  • 3
    this is a genius solution! this is way better than 100vh – Student22 Nov 14 '17 at 05:37
  • When I use the Holy Grail implementation inside a div, the div cannot be resizable, either with CSS resize or JQuery resizable(). I think it has to do with the flex styling of the inner div. Do you know how to solve that? –  Nov 12 '18 at 00:40
  • @amt528, what do you mean "cannot be resizable"? Can you send an example plunker of what you tried? – AlikElzin-kilaka Nov 12 '18 at 12:17
  • When I go to that example (or try something similar), the header (and footer and nav and side) all scroll (and are generally off-screen) right along with the content. Is this something quirky about my setup, or a misunderstanding or change since the original answer? – user2784358 Oct 23 '21 at 20:09
  • @user2784358 the question was to nor scroll the header. Just the content. Opening the example it does just that - http://plnkr.co/edit/O7E6gl?p=preview – AlikElzin-kilaka Oct 25 '21 at 05:26
-1

Here is a demo. Use position:fixed; top:0; left:0; so the header always stay on top.

​#header {
    background:red;
    height:50px;
    width:100%;
    position:fixed;
    top:0;
    left:0;    
}.scroller {
    height:300px; 
    overflow:scroll;    
}
Dips
  • 3,220
  • 3
  • 20
  • 21
-1

You need to use js get better height for body div

<html><body>
<div id="head" style="height:50px; width=100%; font-size:50px;">This is head</div>
<div id="body" style="height:700px; font-size:100px; white-space:pre-wrap;    overflow:scroll;">
This is body
T
h
i
s

i
s

b 
o
d
y
</div>
</body></html>
PasteBT
  • 2,128
  • 16
  • 17