让 div 占据100% 的身高,减去固定高度的页眉和页脚

根据我的研究,这似乎是一个绝对经典的 CSS 问题,但我不能找到一个明确的答案-所以 StackOverflow 它。

如何设置一个内容 div 来占用100% 的主体高度,减去固定高度的页眉和页脚所占用的高度?

<body>
<header>title etc</header>
<div id="content">body content</div>
<footer>copyright etc</footer>
</body>


//CSS
html, body {
height: 100%;
}
header {
height: 50px;
}
footer {
height: 50px;
}
#content {
height: 100% of the body height, minus header & footer
}

我想使用纯 CSS,并且为了使答案在浏览器之间是防弹的。

183438 次浏览

您可以利用 css 属性 箱子尺寸

#content {
height: 100%;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box;    /* Firefox, other Gecko */
box-sizing: border-box;         /* Opera/IE 8+ */
padding-top: 50px;
margin-top: -50px;
padding-bottom: 50px;
margin-bottom: -50px;
}

看看 JsFiddle

只要它不是跨浏览器的解决方案,您就可以利用使用 calc(expression)来实现这一点。

html, body {
height: 100%;
}
header {
height: 50px;
background-color: tomato
}


#content {
height: -moz-calc(100% - 100px); /* Firefox */
height: -webkit-calc(100% - 100px); /* Chrome, Safari */
height: calc(100% - 100px); /* IE9+ and future browsers */
background-color: yellow
}
footer {
height: 50px;
background-color: grey;
}

例如 JsFiddle

如果你想知道更多关于 calc(expression)你最好访问 这个网站。

这个版本将在所有最新的浏览器和 ie8中工作,如果你有现代化脚本(如果不只是将 headerfooter改成 div) :

小提琴

html,
body {
min-height: 100%;
padding: 0;
margin: 0;
}


#wrapper {
padding: 50px 0;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}


#content {
min-height: 100%;
background-color: green;
}


header {
margin-top: -50px;
height: 50px;
background-color: red;
}


footer {
margin-bottom: -50px;
height: 50px;
background-color: red;
}


p {
margin: 0;
padding: 0 0 1em 0;
}
<div id="wrapper">
<header>dfs</header>
<div id="content">
</div>
<footer>sdf</footer>
</div>

滚动内容: 小提琴

这个问题已经得到了很好的回答,但是我冒昧地添加了一个 javascript 解决方案。只要给出想要“展开”id footerspacerdiv的元素,这个 javascript 代码片段就会展开这个 div,直到页面占据整个浏览器窗口的高度。

它的工作原理是,当一个页面小于浏览器窗口的整个高度时,document.body. scrollHeight 等于 document.body. clientHeight。While 循环增加 footerspacerdiv的高度,直到 document.body. scrollHeight 大于 document.body. clientHeight。此时,footerspacerdiv实际上会高出1个像素,浏览器将显示一个垂直滚动条。因此,脚本的最后一行将 footerspacerdiv的高度降低一个像素,使页面高度恰好与浏览器窗口的高度相同。

通过将 footerspacerdiv放在页面的“页脚”之上,这个脚本可以用来“将页脚向下推”到页面的底部,这样在较短的页面上,页脚与浏览器窗口的底部齐平。

<script>
//expand footerspacer div so that footer goes to bottom of page on short pages
var objSpacerDiv=document.getElementById('footerspacer');
var bresize=0;


while(document.body.scrollHeight<=document.body.clientHeight) {
objSpacerDiv.style.height=(objSpacerDiv.clientHeight+1)+"px";
bresize=1;
}
if(bresize) { objSpacerDiv.style.height=(objSpacerDiv.clientHeight-1)+"px"; }
</script>

这里有一个不使用负边距或 calc的解决方案。运行下面的代码片段来查看最终结果。

解释

我们给页眉和页脚一个固定的 30px高度,并将它们分别绝对定位在顶部和底部。为了防止内容落在下面,我们使用两个类: below-headerabove-footer30px填充上下的 div。

所有内容都包装在一个 position: relative div 中,这样页眉和页脚就位于 内容的顶部/底部,而不是窗口。

我们使用类 fit-to-parentmin-fit-to-parent使内容填充页面。这给了我们一个粘性的页脚,它至少和窗口一样低,但是如果内容比窗口长就隐藏起来。

在页眉和页脚内部,我们使用 display: tabledisplay: table-cell样式给页眉和页脚一些垂直填充,而不会破坏页面的收缩包装质量。(给他们真正的填充会导致页面的总高度超过 100%,这会导致在不需要滚动条的时候出现滚动条。)

.fit-parent {
height: 100%;
margin: 0;
padding: 0;
}
.min-fit-parent {
min-height: 100%;
margin: 0;
padding: 0;
}
.below-header {
padding-top: 30px;
}
.above-footer {
padding-bottom: 30px;
}
.header {
position: absolute;
top: 0;
height: 30px;
width: 100%;
}
.footer {
position: absolute;
bottom: 0;
height: 30px;
width: 100%;
}


/* helper classes */


.padding-lr-small {
padding: 0 5px;
}
.relative {
position: relative;
}
.auto-scroll {
overflow: auto;
}
/* these two classes work together to create vertical centering */
.valign-outer {
display: table;
}
.valign-inner {
display: table-cell;
vertical-align: middle;
}
<html class='fit-parent'>
<body class='fit-parent'>
<div class='min-fit-parent auto-scroll relative' style='background-color: lightblue'>
<div class='header valign-outer' style='background-color: black; color: white;'>
<div class='valign-inner padding-lr-small'>
My webpage
</div>
</div>
<div class='fit-parent above-footer below-header'>
<div class='fit-parent' id='main-inner'>
Lorem ipsum doloris finding dory Lorem ipsum doloris finding
dory Lorem ipsum doloris finding dory Lorem ipsum doloris
finding dory Lorem ipsum doloris finding dory Lorem ipsum
doloris finding dory Lorem ipsum doloris finding dory Lorem
ipsum doloris finding dory Lorem ipsum doloris finding dory
Lorem ipsum doloris finding dory Lorem ipsum doloris finding
dory Lorem ipsum doloris finding dory Lorem ipsum doloris
finding dory Lorem ipsum doloris finding dory Lorem ipsum
doloris finding dory Lorem ipsum doloris finding dory Lorem
ipsum doloris finding dory Lorem ipsum doloris finding dory
Lorem ipsum doloris finding dory Lorem ipsum doloris finding
dory Lorem ipsum doloris finding dory Lorem ipsum doloris
finding dory Lorem ipsum doloris finding dory Lorem ipsum
doloris finding dory Lorem ipsum doloris finding dory Lorem
ipsum doloris finding dory Lorem ipsum doloris finding dory
Lorem ipsum doloris finding dory Lorem ipsum doloris finding
dory Lorem ipsum doloris finding dory Lorem ipsum doloris
finding dory Lorem ipsum doloris finding dory Lorem ipsum
doloris finding dory Lorem ipsum doloris finding dory Lorem
ipsum doloris finding dory Lorem ipsum doloris finding dory
Lorem ipsum doloris finding dory Lorem ipsum doloris finding
dory Lorem ipsum doloris finding dory Lorem ipsum doloris
finding dory Lorem ipsum doloris finding dory Lorem ipsum
doloris finding dory Lorem ipsum doloris finding dory Lorem
ipsum doloris finding dory Lorem ipsum doloris finding dory
Lorem ipsum doloris finding dory Lorem ipsum doloris finding
dory Lorem ipsum doloris finding dory Lorem ipsum doloris
finding dory Lorem ipsum doloris finding dory Lorem ipsum
doloris finding dory Lorem ipsum doloris finding dory Lorem
ipsum doloris finding dory Lorem ipsum doloris finding dory
Lorem ipsum doloris finding dory Lorem ipsum doloris finding
dory Lorem ipsum doloris finding dory Lorem ipsum doloris
finding dory Lorem ipsum doloris finding dory Lorem ipsum
doloris finding dory Lorem ipsum doloris finding dory Lorem
ipsum doloris finding dory Lorem ipsum doloris finding dory
</div>
</div>
<div class='footer valign-outer' style='background-color: white'>
<div class='valign-inner padding-lr-small'>
&copy; 2005 Old Web Design
</div>
</div>
</div>
</body>
</html>

新的、现代的方法是通过从视窗的垂直高度减去页眉和页脚的高度来计算垂直高度。

//CSS
header {
height: 50px;
}
footer {
height: 50px;
}
#content {
height: calc(100vh - 50px - 50px);
}

当我试图找到这个问题的答案时,这个结果仍然排在谷歌搜索结果的首位。在我的项目中,我不需要支持较老的浏览器,我觉得我在 弹性箱中找到了一个更好、更简单的解决方案。下面的 CSS 代码片段是所有必要的。

我还演示了如何使主要内容滚动,如果屏幕高度太小。

html,
body {
height: 100%;
display: flex;
flex-direction: column;
}
header {
min-height: 60px;
}
main {
flex-grow: 1;
overflow: auto;
}
footer {
min-height: 30px;
}
<body style="margin: 0px; font-family: Helvetica; font-size: 18px;">
<header style="background-color: lightsteelblue; padding: 2px;">Hello</header>
<main style="overflow: auto; background-color: lightgrey; padding: 2px;">
<article style="height: 400px;">
Goodbye
</article>
</main>
<footer style="background-color: lightsteelblue; padding: 2px;">I don't know why you say, "Goodbye"; I say, "Hello."</footer>
</body>

试图计算页眉和页脚是不好的: (设计应该是简单的,不言而喻的。很简单。计算真是... 不容易。对人类来说不容易,对机器来说有点难。

你要找的是 圣杯设计的一个子集。

这里的 是一个使用 Flex 显示的实现,它包括了边栏以及页脚和页眉:

<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta charset=utf-8 />
<title>Holy Grail</title>
<!-- Reset browser defaults -->
<link rel="stylesheet" href="reset.css">
</head>
<body style="display: flex; height: 100%; flex-direction: column">
<div>HEADER<br/>------------
</div>
<!-- No need for 'flex-direction: row' because it's the default value -->
<div style="display: flex; flex: 1">
<div>NAV|</div>
<div style="flex: 1; overflow: auto">
CONTENT - START<br/>
<script>
for (var i=0 ; i<1000 ; ++i) {
document.write(" Very long content!");
}
</script>
<br/>CONTENT - END
</div>
<div>|SIDE</div>
</div>
<div>------------<br/>FOOTER</div>
</body>
</html>