What I\'m looking for is to have a container div
with any number of headers and footers which would then have another scrolling div
in between the
I took Matt Cooper's solution and updated it a bit. This resolves the inability to add more than one widget to a page, and also the footer sizing issue.
http://jsfiddle.net/XSADu/10/
Steps:
CSS
.wrapper{
height:400px;
border-left:1px solid red;
position: relative;
}
.header, .footer, .scroller {
background-color: #EEE;
position:absolute;
width: 100%;
}
.footer {
bottom: 0;
}
.scroller{
background-color: #CCC;
overflow:auto;
}
JS
$(document).ready(function(){
$('.scroller').css("top", $('.header').height());
$('.scroller').css("bottom", $('.footer').height());
});
NOTE: If the header/footer sizing are dynamic, you may want to give them some max heights as a percentage of the wrapper, so that the content isn't hidden.
Building on DMoses answer, this solution involves just a bit more jquery, but it removes the issue of the scrollbar being slightly hidden by the footer/header
the jQuery:
$(document).ready(function(){
$('.scroller').css("margin-top", $('.header').height());
var height = $('.wrapper').height() - ($('.footer').height() + $('.header').height());
$('.scroller').css("height", height);
});
jsfiddle.net/XSADu/5/
This can now be done using CSS grids pretty easily. without the need of an filler elements even.
If you want multiple headers, simply put a few divs in there, or make the "header" div a flexbox if that's what you want.
HTML stays the same:
<div class="wrapper">
<div class="header">
Some<br/>
Header
</div>
<div class="scroller">
Content<br />
Content<br />
Content<br />
Content<br />
...
</div>
<div class="footer">
Some<br/>
Footer
</div>
</div>
CSS:
.wrapper{
height:400px;
border-left:1px solid red;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: [header] auto [content]1fr [footer]auto;
}
.header{
background-color: #EEE;
grid-row: header;
}
.footer{
background-color: #EEE;
grid-row: footer;
}
.scroller{
background-color: #CCC;
overflow:auto;
grid-row: content
}
http://jsfiddle.net/yKTdz/15/
Achieved with pure CSS
(not even CSS3), by mixing table display
with relative
and absolute
positioning.
Running Demo: http://jsfiddle.net/x4vhW/
HTML
<div class="wrapper">
<div class="tr stretch">
<div class="td">a header</div>
</div>
<div class="tr">
<div class="td">
<div class="contentWrapper">
<div class="content">
content 0
...............
...............
...............
content 29
</div>
</div>
</div>
</div>
<div class="tr stretch">
<div class="td stretch">a footer</div>
</div>
</div>
CSS Dark Magic(tm)
.wrapper {
height : 200px;
width : 200px;
display : table;
}
.tr { display : table-row; }
.td { display : table-cell; }
.stretch { height : 1%; }
.contentWrapper {
position : relative;
overflow-y : scroll;
height : 100%;
}
.content {
position : absolute;
right : 0;
left : 0;
}
Note: the stretch
class is used in order to prevent headers and footers to grow if content has a small content; with stretch, they will auto-fit.
And finally, according to CanIUse, it is supported by almost all browsers, including IE8.
As stated by Matt Cooper, I don't think there's a css pure solution. Here's my attempt: jsfiddle
var CalcHeight = function() {
this.init = function() {
var totHeight = $('body').height();
var componentsHeight = $('.headers').height() + $('.footers').height();
var diff = totHeight - componentsHeight;
$('.hider').css({
height: diff
});
}
this.init();
}
var calcHeight = new CalcHeight;
There's no way to do this with just Css, You'd need to use Javascript to check the height of the header and footer when the page loads and adjust things accordingly. Otherwise when you use position:fixed you'll get some overlap. See the Attached fiddle! http://jsfiddle.net/XSADu/
I use jQuery to adapt the padding-top on the scroller on document ready. like so
$(document).ready(function(){
$('.scroller').css("padding-top", $('.header').height());
});