Yanick Rochon
Yanick Rochon

Reputation: 53521

CSS fixed element appear over scrollbars

I have seen a few questions about somewhat the same issue, but none of the specified answers actually work for this one.

Consider the following snippet :

$(function () {
  $(window).on('scroll', function () {
    /**
      THIS SHOULD NOT BE CALLED!!!
      So, change some colors to warn about it, if it happens.
    */
    $('#content').css('background-color', 'red');
  });
});
body {
  margin:0;
  padding:0;
    
  height: 100%;
  width: 100%;
}

#container {
  position: absolute;
    
  height: 100%;
  width: 100%;
  z-index: 9999999;
    
  overflow: auto;
}

#nav {
  background-color:rgb(50,50,50);
  color: white;

  position: fixed;
  left: 0;
  top: 0;
  
  width: 100%;
  height: 30px;
  padding-top: 10px;
  z-index: 100;
}

#content-wrapper {
  background-color:rgb(200,200,200);

  min-height: 100%;
  height: auto !important;
  width: 100%;
  z-index:2;
}

#content {
  padding-top: 40px;
  padding-bottom: 40px;
}

#footer {
  background-color: rgb(220, 220, 240);
  
  position: fixed; 
  left: 0;
  bottom: 0;

  height: 30px;
  width: 100%;
  padding-top: 10px;
  z-index: 9999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
  <div id="nav">
    Navbar
  </div>
    
  <div id="content-wrapper">
    <div id="content">
      <div>
        Begin
      </div>
      <div style="height: 600px;">
        ...
      </div>
      <div>
        End
      </div>
    </div>
  </div>
    
  <div id="footer">
    Footer
  </div>
</div>

The scrollbar goes underneath nav and footer. Since this is very important that only the container element scrolls (the BODY element must not scroll), how can I fix this? Is it possible?

The HTML structure should essentially be as suggested in this question (fixed nav, full height content, etc.). I have tried several tricks; modifying z-indexes, wrapping things around, etc., I'm at a lost here.

The targeted browser is Google Chrome, as this is the adopted browser in use for this application. The ideal solution would make the fixed element adjust their width to compensate for the overflow: auto; on the container element.

Upvotes: 5

Views: 9820

Answers (4)

mikakun
mikakun

Reputation: 2255

I don't think calc was implemented at time of the question so here is a modern take

Facing the same issue, but with the x scrollbar & horizontal fixed element hiding it on chromium browsers, I have dealt with it setting my body height to height : calc(100vh - var(--fixedBottomElementHeight);.

Interestingly, on firefox, the body height doesn't change & scrollbar remains visible at the bottom of the window while on chromium, the scroll appears now above the fixed element & is no more hidden.

so, if the slight rendering difference between chromium & firefox is not an issue, here is an alternative solution to reveal Y scroll bar hidden by horizontal fixed element, css only & normally respecting the no body scroll requirement :

:root {
  --navHeight    : 96px;
  --footerHeight : 48px;
  }

body {
  margin : 0;
  padding: 0;

  height: 100vh;
  
  width : 100vw; /* or % */


  overflow: hidden;

  }

#nav {
   position: fixed;
   height: var(--navHeight);
   width: 100vw;
   top: 0;
}

#footer {
   position: fixed;
   height: var(--footerHeight);
   width: 100vw;
   bottom: 0;
}

#container {

   height:  calc(100vh - var(--footerHeight)  - var(--navHeight));
   margin-top: var(--navHeight);

   width: 100%;
   overflow: auto;

 }

Upvotes: 0

TheLeggett
TheLeggett

Reputation: 980

Demo in this fiddle

An alternative approach here would be to only scroll the #content-wrapper from your example. Here's a basic example of how this might be done:

HTML

<div id="container">
    <div id="nav">
        Navbar
    </div>

    <div id="content-wrapper">
        <div id="content">
            <div>
                Begin
            </div>
            <div style="height: 600px;">
                ...
            </div>
            <div>
                End
            </div>
        </div>
    </div>

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

CSS

body {
    margin:0;
    padding:0;
    height: 100%;
    width: 100%;
}

#container {
    position: absolute;
    height: 100%;
    width: 100%;
    overflow: hidden;
}

#nav {
    background-color:rgb(50,50,50);
    color: white;
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 30px;
    padding-top: 10px;
}

#content-wrapper {
    position:absolute;
    top:40px;
    bottom:40px;
    left:0;
    right:0;
    background-color:rgb(200,200,200);
    width: 100%;
    overflow:scroll;

}

#footer {
    background-color: rgb(220, 220, 240);
    position: fixed; 
    left: 0;
    bottom: 0;
    height: 30px;
    width: 100%;
    padding-top: 10px;
}

Upvotes: 4

Lal
Lal

Reputation: 14810

See this fiddle

Remove overflow:auto from #container.

So the CSS for #container would be like

#container {
  position: absolute;    
  height: 100%;
  width: 100%;
  z-index: 9999999;
}

UPDATE

Add overflow:auto to #content.

Upvotes: 4

DivideByZero
DivideByZero

Reputation: 545

http://jsfiddle.net/a8xqhh3L/

Remove overflow: auto from #container.

Upvotes: 0

Related Questions