Can I use `overflow: scroll` on a div with variable height?

Is it possible to use overflow: scroll on a div that has height set to auto?

I have a div with an unordered list inside of it. The amount of items in the list is variable so there is no way I can use a fixed height. The div that contains the unordered list is where the scrollbars need to be, here is my code:

#page {
    height: auto; /* default */
    overflow-y: scroll;
    overflow-x: hidden;
}

As stated, the unordered list is contained within the #page div. The height of the page is assigned by the unordered list's value. Is there a way to make overflow: scroll work on a div with variable height like this or must I use JavaScript to do this?

Thanks


Solution 1:

One way of approaching this design...

Suppose that you have the following HTML:

<div class="main">
    <div class="inner">
        <ul>
            <li>Some list items...</li>
            ...
        </ul>
    </div>
</div>

The .main block is fitted to the page, for example, by absolute positioning:

.main {
    border: 2px dashed blue;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

The .inner block holds the navigation list that can cause scrolling:

.inner {
    border: 2px dotted red;
    position: absolute;
    top: 10px;
    bottom: 10px;
    left: 10px;
    right: 10px;
    overflow-y: scroll;
}

In this example, I constrain the height of the .inner block to fit within .main, and set overflow-y: scroll, which creates a scroll bar contained within the edges of the container block.

You may have to adapt this to your mobile platform, but the concept should still apply.

Demo fiddle: http://jsfiddle.net/audetwebdesign/ac4xT/

Solution 2:

Simply put, if it has variable height (auto), it will never have overflow in the y axis (vertically), because the div will always grow to fit its contents.

overflow: scroll will force it to present a scrollbar, but it will always be disabled, because the contents will never extend beyond the displayed pane.

If you want vertical scrolling, you have to define a height, either in px, %, or em.

If you do height: 100%, the div will fill the height of the page, and scroll content that extends beyond the window's viewport height.

If you have a header area, try something like this:

body {
  margin: 0;
}
#header {
  position: absolute;
  width: 100%;
  height: 40%;
  background-color: #ccc;
}
#body {
  position: absolute;
  top: 40%;
  width: 100%;
  height: 60%;
  overflow-y: auto;
  background-color: #eee;
}
<body>
  <div id="header">
    <p>Header</p>
  </div>
  <div id="body">
    <p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p>
    <p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p>
  </div>
</body>

For a fixed-height header (per the comments), use absolute positioning with a top and botom value to position the scrollable div below it:

body {
  margin: 0;
}
#header {
  position: absolute;
  width: 100%;
  height: 60px;
  background-color: #ccc;
}
#body {
  position: absolute;
  top: 60px;
  bottom: 0px;
  width: 100%;
  overflow-y: auto;
  background-color: #eee;
}
<body>
  <div id="header">
    <p>Header</p>
  </div>
  <div id="body">
    <p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p>
    <p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p><p>Body</p>
  </div>
</body>

Solution 3:

Why not use max-height on the div?

max-height sets the maximum height to which an element can expand. I suppose what you want is the div to never go out of the screen. So you can set a max-height and then overflow: auto;