21

I was surprised I could not find a simple answer to this problem by Googling, but most responses to scrolling content panels either did not work properly, or did not work with bootstrap.

Answers like this one have full page scroll-bars, which seems wrong.

I am simply trying to have 100% height html and body with no browser scrollbar, but scrolling visible on the body content area only. It needs to behave with bootstrap menu heights etc.

So far the only way seems to work, at all, is using absolutely position content and footers elements.

html {
  height: 100%;
}
html body {
  height: 100%;
  overflow: hidden;
}
html body .container-fluid.body-content {
  position: absolute;
  top: 50px;
  bottom: 30px;
  right: 0;
  left: 0;
  overflow-y: auto;
}

footer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 30px;
}

But this just seems the wrong way to go about it and seems to impact Bootstrap layouts negatively. For instance, if the menu line wraps to two lines, the content area goes under the nav-bar div.

Can any please tell me the correct way to go about this styling, that is compatible with an out-of-the-box MVC Razor/Bootstrap application?

Notes:

  • It needs to work with IE8 onwards.
  • It needs to work with Bootstrap, so if Boostrap is adjusted (header/footer sizes) then it will correct itself too.

Update:

Here is a JSFiddle to work with (including my latest solution from answer below):

JSFiddle: http://jsfiddle.net/TrueBlueAussie/6cbrjrt5/

Community
  • 1
  • 1
iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
  • is this not a super common use case? Why doesn't it work with bootstrap? I tried without bootstrap and I can do it, but then all kinds of weirdness ensues with bootstrap. What is in bootstrap that is making fixed positioning behave in non-standard ways? – user798719 Apr 22 '17 at 17:33

3 Answers3

24

Add the following css to disable the default scroll:

body {
    overflow: hidden;
}

And change the #content css to this to make the scroll only on content body:

#content {
    max-height: calc(100% - 120px);
    overflow-y: scroll;
    padding: 0px 10%;
    margin-top: 60px;
}

See fiddle here.


Edit:

Actually, I'm not sure what was the issue you were facing, since it seems that your css is working. I have only added the HTML and the header css statement:

html {
  height: 100%;
}
html body {
  height: 100%;
  overflow: hidden;
}
html body .container-fluid.body-content {
  position: absolute;
  top: 50px;
  bottom: 30px;
  right: 0;
  left: 0;
  overflow-y: auto;
}
header {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    background-color: #4C4;
    height: 50px;
}
footer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #4C4;
    height: 30px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<header></header>
<div class="container-fluid body-content">
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
</div>
<footer></footer>
falsarella
  • 12,217
  • 9
  • 69
  • 115
  • 4
    I think he doesn't want a set height for his header and footer. – Chad Mar 13 '15 at 18:31
  • @Chad Hmm, you're right. I'll review my answer asap. Thank you for pointing this out. – falsarella Mar 13 '15 at 22:21
  • Question updated, with a JSFiddle, if you want to improve upon it. Thanks. – iCollect.it Ltd Mar 16 '15 at 10:13
  • @TrueBlueAussie I think you'll need to (a.) use javascript to constantly calculate the remaining body-content height in pixels, or (b.) use multiple media queries handling each header and footer line wrapping. Is any of these an option? If yes, I can work on it later. If no, I think it won't be possible with pure CSS. It would be tough to prove the impossibility, but in fact, I would also like to wait for a good answer, since it seems that there is currently no solution on web. – falsarella Mar 18 '15 at 14:33
  • @falsarella: As it happens I wrote a simple plugin that adds size-based classes to the `body` element on resize, based on the current rendered Bootstrap size, so I *will* be able to vary based on styles alone. – iCollect.it Ltd Mar 18 '15 at 14:43
  • @TrueBlueAussie Nice! A javascript solution is indeed suitable. Alternatively, you could use media queries instead of watching for window resize. I'll update my answer with it as soon as I can. – falsarella Mar 18 '15 at 15:57
10

Another option would be using flexbox.

While it's not supported by IE8 and IE9, you could consider:

  • Not minding about those old IE versions
  • Providing a fallback
  • Using a polyfill

Despite some additional browser-specific style prefixing would be necessary for full cross-browser support, you can see the basic usage either on this fiddle and on the following snippet:

html {
  height: 100%;
}
html body {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
html body .container-fluid.body-content {
  width: 100%;
  overflow-y: auto;
}
header {
    background-color: #4C4;
    min-height: 50px;
    width: 100%;
}
footer {
    background-color: #4C4;
    min-height: 30px;
    width: 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<header></header>
<div class="container-fluid body-content">
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
  Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>Lorem Ipsum<br/>
</div>
<footer></footer>
Community
  • 1
  • 1
falsarella
  • 12,217
  • 9
  • 69
  • 115
  • 1
    Nice one! I'd like to have the header and foot fixed but inside the content I'd also like to have another header that similar sticks to the top of the inner content and on the inner content should be scrollable. When its scrolled the outer header and footer as well as the inner header stay always in place. I tried http://jsfiddle.net/7S4Xx/569/ but the inner footer is not visble. Also the same construct should still work like your with content like in your first fiddle – philk Feb 28 '16 at 01:00
  • @philk That's because your `outerContent` should be the flex wrapper, instead of an inner inner flex wrapper. [Please, take a look how it works](http://jsfiddle.net/7S4Xx/593/). – falsarella Apr 01 '16 at 12:27
2

Until I get a better option, this is the most "bootstrappy" answer I can work out:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/6cbrjrt5/

I have switched to using LESS and including the Bootstrap Source NuGet package to ensure compatibility (by giving me access to the bootstrap variables.less file:

in _layout.cshtml master page

  • Move footer outside the body-content container
  • Use boostrap's navbar-fixed-bottom on the footer
  • Drop the <hr/> before the footer (as now redundant)

Relevant page HTML:

<div class="container-fluid body-content">
    @RenderBody()
</div>
<footer class="navbar-fixed-bottom">
    <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
</footer>

In Site.less

  • Set HTML and BODY heights to 100%
  • Set BODY overflow to hidden
  • Set body-content div position to absolute
  • Set body-content div top to @navbar-height instead of hard-wiring value
  • Set body-content div bottom to 30px.
  • Set body-content div left and right to 0
  • Set body-content div overflow-y to auto

Site.less

html {
    height: 100%;

    body {
        height: 100%;
        overflow: hidden;

        .container-fluid.body-content {
            position: absolute;
            top: @navbar-height;
            bottom: 30px;
            right: 0;
            left: 0;
            overflow-y: auto;
        }
    }
}

The remaining problem is there seems to be no defining variable for the footer height in bootstrap. If someone call tell me if there is a magic 30px variable defined in Bootstrap I would appreciate it.

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202