I\'m trying to make a web page with a fixed header and a scrollable content area. This is trivial when the header has a known height but I\'m struggling to find a solution f
Assuming by "fixed" you mean position:fixed
, I don't think it's possible in pure CSS, as position:fixed
takes the element out of the document flow.
However, it should just take a line or two of JavaScript to get what you want. Something like this (untested, only for example purposes, will need syntax tweaked to actually work):
var height = document.getElementById("head").offsetHeight;
document.getElementById("content").style.marginTop = height + 'px';
Something like that should get you the rendered height of the fixed <div>
and set the content <div>
's margin accordingly. You'll also need to explicitly set a background color on the fixed <div>
, otherwise the content will appear to bleed into the fixed one when scrolling.
Here's a solution, but it's a cheat. Basically, you have a duplicate header element, to push down the content, under the fixed position one:
<div class="outer">
<div class="header">Header content goes here</div>
<div class="header-push">Header content goes here</div>
<div class="content">
...
</div>
</div>
I did a combination of both the accepted and Eric's answer. An empty div is used to push the content bellow "head". The width of this div is set by jQuery when window.onresize is fired:
function resizeHeader() {
$(".header-push").height($(".header").height());
}
$(document).ready(resizeHeader);
$(window).resize(resizeHeader);
See this jsFiddle for more info.
Here is a full code example of Shauna's solution above for the lazy/confused/people who can't get this working.
<html>
<head>
<style>
#FreezePaneHeader {
position: fixed; top:0; left: 0; width: 100%;background-color: gray;
}
#FreezePaneBody {
margin-top: 30px;
}
</style>
<script type="text/javascript">
function resizeFreezePane()
{
var height = document.getElementById("FreezePaneHeader").offsetHeight;
document.getElementById("FreezePaneBody").style.marginTop = height + 'px';
}
//Resizes content to allow static header with dynamic height on postbacks
function pageLoad() {
resizeFreezePane();
}
var addEvent = function (elem, type, eventHandle) {
if (elem == null || typeof (elem) == 'undefined') return;
if (elem.addEventListener) {
elem.addEventListener(type, eventHandle, false);
} else if (elem.attachEvent) {
elem.attachEvent("on" + type, eventHandle);
} else {
elem["on" + type] = eventHandle;
}
};
//also when page is resized.
addEvent(window, "resize", resizeFreezePane);
function GenerateLorem(ele){
var x = document.getElementById(ele);
x.innerHTML = x.innerHTML + "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur pretium euismod leoquis convallis. In ornare suscipit massa eu commodo. Pellentesque vel nibh volutpat, commodo libero et,
porta tellus. Duis eu fringilla arcu. Etiam imperdiet lectus diam, dignissim viverra dui hendrerit id. Fusce condimentum bibendum tincidunt. Aenean fringilla felis elit, et dapibus ante tempus at. Phasellus quis dolor odio.</p>";
resizeFreezePane();
}
</script>
</head>
<body>
<div id="FreezePaneHeader">Frozen Page Header</div>
<div id="FreezePaneBody">
<button id="ButtonAddText" onclick="GenerateLorem('FreezePaneHeader'); return false;">Add more header text</button>
<button id="ButtonAddText" onclick="GenerateLorem('FreezePaneBody'); return false;">Add more body text</button>
<p id="PageContents"></p>
</div>
</body>
</html>
This javascript will take the variable height of a fixed header and set the top margin of the content to flow underneath. Just call page load.
<script type="text/javascript">
function AdjustHeight() {
var height = document.getElementById("fixedheader").offsetHeight;
document.getElementById("content").style.marginTop = height + 'px';
}
</script>