115

I have a div positioned fixed on the left side of a web page, containing menu and navigation links. It has no height set from css, the content determines the height, the width is fixed. The problem is that if the content is too much, the div will be larger than the window's height, and part of the content will not be visible. (Scrolling the window doesn't help, since the position is fixed and the div won't scroll.)

I tried to set overflow-y:auto; but that doesn't help either, the div doesn't seem to notice that part of it is outside of the window.

How can I make it's contents scrollable only, if needed, if the div hangs out of the window?

isherwood
  • 52,576
  • 15
  • 105
  • 143
Mkoch
  • 1,844
  • 2
  • 13
  • 20
  • A solution with CSS calc() can be found here : http://stackoverflow.com/q/29754195/3168107. – Shikkediel Apr 20 '15 at 21:04
  • `calc()` is an [experimental technology](https://developer.mozilla.org/en-US/docs/Web/CSS/calc) and may result in [unexpected results](http://caniuse.com/#feat=calc). If you choose to use it, make sure you know your target audience and test it in those browsers. – c1moore Aug 20 '15 at 12:26
  • Ran into same problem and used something like max-height: calc(100vh - 100px); where my navbar and paddings were making upto 100px – Zia Ul Rehman Mughal Dec 15 '16 at 04:44

9 Answers9

121

You probably can't. Here's something that comes close. You won't get content to flow around it if there's space below.

http://jsfiddle.net/ThnLk/1289

.stuck {
    position: fixed;
    top: 10px;
    left: 10px;
    bottom: 10px;
    width: 180px;
    overflow-y: scroll;
}

You can do a percentage height as well:

http://jsfiddle.net/ThnLk/1287/

.stuck {
    max-height: 100%;
}
isherwood
  • 52,576
  • 15
  • 105
  • 143
50

The link below will demonstrate how I accomplished this. Not very hard - just have to use some clever front-end dev!!

<div style="position: fixed; bottom: 0%; top: 0%;">

    <div style="overflow-y: scroll; height: 100%;">

       Menu HTML goes in here

    </div>

</div>

http://jsfiddle.net/RyanBrackett/b44Zn/

Ryan Brackett
  • 982
  • 9
  • 13
  • 1
    Underrated answer. For my use-case - Outer div style is `position: fixed; bottom: 0%; top: 0%; overflow: scroll; height: 100vh;` will make the outer div scroll-able based on content. – kilogic Jul 17 '20 at 15:35
  • Great answer for those who have a `top` property different than 0. In those cases, the scrolling bar wouldn't reach the end of the content. – T.Trassoudaine Sep 10 '21 at 15:23
13

Try this on your position:fixed element.

overflow-y: scroll;
max-height: 100%;
Lucas Bustamante
  • 13,827
  • 7
  • 77
  • 75
8

You probably need an inner div. With css is:

.fixed {
   position: fixed;
   top: 0;
   left: 0;
   bottom: 0;
   overflow-y: auto;
   width: 200px; // your value
}
.inner {
   min-height: 100%;
}
Aureliano Far Suau
  • 6,291
  • 2
  • 20
  • 25
3

This is absolutely doable with some flexbox magic. Have a look at this pen.

You need css like this:

aside {
  background-color: cyan;
  position: fixed;
  max-height: 100vh;
  width: 25%;
  display: flex;
  flex-direction: column;
}

ul {
  overflow-y: scroll;
}

section {
  width: 75%;
  float: right;
  background: orange;
}

This will work in IE10+

transGLUKator
  • 587
  • 5
  • 15
3

Here is the pure HTML and CSS solution.

  1. We create a container box for navbar with position: fixed; height:100%;

  2. Then we create an inner box with height: 100%; overflow-y: scroll;

  3. Next, we put out content inside that box.

Here is the code:

.nav-box{
        position: fixed;
        border: 1px solid #0a2b1d;
        height:100%;
   }
   .inner-box{
        width: 200px;
        height: 100%;
        overflow-y: scroll;
        border: 1px solid #0A246A;
    }
    .tabs{
        border: 3px solid chartreuse;
        color:darkred;
    }
    .content-box p{
      height:50px;
      text-align:center;
    }
<div class="nav-box">
  <div class="inner-box">
    <div class="tabs"><p>Navbar content Start</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content</p></div>
    <div class="tabs"><p>Navbar content End</p></div>
    </div>
</div>
<div class="content-box">
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
  <p>Lorem Ipsum</p>
</div>

Link to jsFiddle:

Manoj Negi
  • 1,067
  • 16
  • 18
1

For your purpose, you can just use

position: absolute;
top: 0%;

and it still be resizable, scrollable and responsive.

0

I'm presenting this as a workaround rather than a solution. This may not work all the time. I did it this way as I'm doing a very basic HTML page, for internal use, in a very bizarre environment. I know there are libraries like MaterializeCSS that can do really nice nav bars. (I was going to use them, but it didn't work with my environment.)

<div id="nav" style="position:fixed;float:left;overflow-y:hidden;width:10%;"></div>
<div style="margin-left:10%;float:left;overflow-y:auto;width:60%;word-break:break-all;word-wrap:break-word;" id="content"></div>
0

Add this to your code for fixed height and add one scroll.

.fixedbox {
    max-height: auto;
    overflow-y: scroll;
}
hellow
  • 10,920
  • 6
  • 47
  • 69