Html 如何定位 DIV 以填充页眉 DIV 和页脚 DIV 之间的所有可用空间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/57091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to position a DIV to fill all available space between a header DIV and a footer DIV?
提问by qbeuek
Let's say I have a parent DIV. Inside, there are three child DIVs: header, content and footer. Header is attached to the top of the parent and fills it horizontally. Footer is attached to the bottom of the parent and fills it horizontally too. Content is supposed to fill all the space between header and footer.
假设我有一个父 DIV。在里面,有三个子 DIV:页眉、内容和页脚。标题附加到父级的顶部并水平填充。页脚附加到父级的底部并水平填充它。内容应该填充页眉和页脚之间的所有空间。
The parent has to have a fixed width and height. The content DIV has to fill all available space between header and footer. When the content size of the content DIV exceeds the space between header and footer, the content DIV should display scrollbars and allow appropriate scrollingso that the footer contents should never be obscured nor the footer obscure content.
父级必须具有固定的宽度和高度。内容 DIV 必须填充页眉和页脚之间的所有可用空间。当内容 DIV 的内容大小超过页眉和页脚之间的空间时,内容 DIV 应显示滚动条并允许适当滚动,以便页脚内容永远不会被遮挡,页脚也不应遮挡内容。
Now comes the hard part: you don't know the height of the header nor footer beforehand(eg. header and footer are filled dynamically). How can content be positioned without using JavaScript?
现在是困难的部分:您事先不知道页眉和页脚的高度(例如,页眉和页脚是动态填充的)。如何在不使用 JavaScript 的情况下定位内容?
Example:
例子:
<div style="position : relative; width : 200px; height : 200px; background-color : #e0e0ff; overflow : hidden;">
<div style="background-color: #80ff80; position : absolute; left : 0; right : 0; top : 0;">
header
</div>
<div style="background-color: #8080ff; overflow : auto; position : absolute;">
content (how to position it?)
</div>
<div style="background-color: #ff8080; position : absolute; bottom : 0px; left :0; right : 0;">
footer
</div>
</div>
To clarify this event further- the target layout that I'm trying to achieve will be used in a business web application. The parent DIV will have a fixed, but unknown size(for instance, it will be exactly the size of the browser viewport, sizing itself along with sizing the browser window by the user). Let's call the parent DIV a "screen".
为了进一步澄清此事件- 我试图实现的目标布局将用于业务 Web 应用程序。父 DIV 将具有固定但未知的大小(例如,它将与浏览器视口的大小完全相同,其自身大小与用户对浏览器窗口的大小相同)。让我们称父 DIV 为“屏幕”。
The header will contain a set of filtering controls (like textboxes, drop down lists and a "filter" button) that should wrap to the next line if there is insufficient horizontal space (so its height can change any time to accomodate line breaking). The header should always be visible and attached to the topof the "screen".
标题将包含一组过滤控件(如文本框、下拉列表和“过滤器”按钮),如果水平空间不足,它们应该换行到下一行(因此其高度可以随时更改以适应换行)。标题应始终可见并附加到“屏幕”的顶部。
The footer will contain a set of buttons, like on a dialog window. These too can wrap to next line if there is not enough space horizontally. The footer must be attached to the bottomof the "screen" to be accessible and visible at all times.
页脚将包含一组按钮,就像在对话窗口上一样。如果水平方向没有足够的空间,这些也可以换行到下一行。页脚必须附加到“屏幕”的底部,以便在任何时候都可以访问和可见。
The content will contain "screen" contents, like dialog fields etc. If there are too few fields, the rest of the content will be "blank" (in this case the footer should not begin right after the content, but still be attached to the bottom of the "screen" which is fixed size). If there are too many fields, the content DIV will provide scrollbar(s)to access the hidden controls (in this case the content DIV must not extend itself below the footer, as the scrollbar would be partially hidden).
内容将包含“屏幕”内容,如对话框字段等。如果字段太少,其余内容将是“空白”(在这种情况下,页脚不应紧跟在内容之后开始,但仍应附加到固定大小的“屏幕”底部)。如果字段太多,内容 DIV 将提供滚动条以访问隐藏控件(在这种情况下,内容 DIV 不得将自身扩展到页脚下方,因为滚动条将部分隐藏)。
I hope this clarifies the question a little bit further, as I have too low rep to enter comments to your repsonses.
我希望这能进一步澄清这个问题,因为我的代表太低而无法对您的回复发表评论。
回答by harpo
I'm going to get downmodded for this, but this sounds like a job for a table.
我将为此而降级,但这听起来像是一张桌子的工作。
What you're trying to do is to set the total height of three contiguous divs as a unit, and a 1x3 table with height 100% is actually a cleaner solution.
你想要做的是将三个连续的div的总高度设置为一个单位,高度为100%的1x3表格实际上是一个更简洁的解决方案。
回答by Ian Oxley
If you can get away with not having the main content scrollable, you might be better using the footerStickAltmethod to make sure your footer stays at the bottom of the screen or the bottom of the content (if the content extends beyond the bottom of the screen).
如果您可以避免使主要内容无法滚动,则最好使用footerStickAlt方法来确保您的页脚位于屏幕底部或内容底部(如果内容超出屏幕底部) )。
回答by pschueller
Pure CSS Solution 1 - Flexbox:
纯 CSS 解决方案 1 - Flexbox:
You can create a column of divs that behave in this way by using the CSS3 display: flex;
property (see W3 Specs)
您可以使用 CSS3display: flex;
属性创建一列具有这种行为的 div (请参阅 W3 规范)
Using a wrapper, you can align everything in a column with the flex-direction: column;
declaration and then fill the vertical space with justify content: space-between;
and height: 100vh;
. Then all you need to do is make your content element expand with flex: 1 0 0;
and give it a scrollbar with overflow-y: auto;
.
使用包装器,您可以将列中的所有内容与flex-direction: column;
声明对齐,然后用justify content: space-between;
和填充垂直空间height: 100vh;
。然后你需要做的就是让你的内容元素扩展,flex: 1 0 0;
并给它一个滚动条overflow-y: auto;
。
Note on browser support- While flexbox is supported by most modern browsers, there are still a few limitations (see: http://caniuse.com/#feat=flexbox). I would recommend using the -webkit-
and -ms-
prefixes.
关于浏览器支持的注意事项- 虽然大多数现代浏览器都支持 flexbox,但仍有一些限制(请参阅:http://caniuse.com/#feat=flexbox)。我建议使用-webkit-
和-ms-
前缀。
Working example: See the following snippet and this jsfiddle.
工作示例:请参阅以下代码段和此jsfiddle。
body {
display: -webkit-flex; /* Safari 6.1+ */
display: -ms-flex; /* IE 10 */
display: flex;
-webkit-flex-direction: column; /* Safari 6.1+ */
-ms-flex-direction: column; /* IE 10 */
flex-direction: column;
-webkit-justify-content: space-between; /* Safari 6.1+ */
-ms-justify-content: space-between; /* IE 10 */
justify-content: space-between; /* Header top, footer bottom */
height: 100vh; /* Fill viewport height */
}
main {
-webkit-flex: 1 0 0; /* Safari 6.1+ */
-ms-flex: 1 0 0; /* IE 10 */
flex: 1 0 0; /* Grow to fill space */
overflow-y: auto; /* Add scrollbar */
height: 100%; /* Needed to fill space in IE */
}
header, footer {
-webkit-flex: 0 0 auto; /* Safari 6.1+ */
-ms-flex: 0 0 auto; /* IE 10 */
flex: 0 0 auto;
}
/* Make it look a little nicer */
body {
margin: 0;
background-color: #8080ff;
}
header {
background-color: #80ff80;
}
footer {
background-color: #ff8080;
}
p {
margin: 1.25rem;
}
<body>
<header>
<p>header</p>
</header>
<main>
<article>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pellentesque lobortis augue, in porta arcu dapibus dapibus. Suspendisse vulputate tempus venenatis. Pellentesque ac euismod urna. Donec dui odio, ullamcorper in posuere eu, laoreet sed nisl. Sed vitae vestibulum leo. Maecenas mattis lacus eget nisl malesuada, quis semper urna ornare. Praesent id mauris nec neque aliquet dignissim.</p>
<p>Morbi varius dolor at lorem aliquet lacinia. Aliquam id lacinia quam. Sed vel libero felis. Etiam et pellentesque sem. Aenean bibendum, ante quis luctus tincidunt, elit mauris volutpat nisi, et tempus lectus sapien in mauris. Aliquam condimentum nisl ut elit accumsan hendrerit. Morbi mollis turpis est, id tincidunt ipsum rhoncus eget. Fusce in feugiat lacus. Quisque vel massa magna. Mauris varius congue nisl, vitae pellentesque diam ultricies at. Sed ac nibh ac diam tristique venenatis non nec nisl. Vivamus enim eros, pretium at iaculis nec, pharetra non sem. Aenean ac imperdiet odio.</p>
<p>Morbi varius dolor at lorem aliquet lacinia. Aliquam id lacinia quam. Sed vel libero felis. Etiam et pellentesque sem. Aenean bibendum, ante quis luctus tincidunt, elit mauris volutpat nisi, et tempus lectus sapien in mauris. Aliquam condimentum nisl ut elit accumsan hendrerit. Morbi mollis turpis est, id tincidunt ipsum rhoncus eget. Fusce in feugiat lacus. Quisque vel massa magna. Mauris varius congue nisl, vitae pellentesque diam ultricies at. Sed ac nibh ac diam tristique venenatis non nec nisl. Vivamus enim eros, pretium at iaculis nec, pharetra non sem. Aenean ac imperdiet odio.</p>
</article>
</main>
<footer>
<p>footer</p>
</footer>
</body>
For more information on how to use flexbox see these guides:
有关如何使用 flexbox 的更多信息,请参阅以下指南:
- https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes
- https://css-tricks.com/snippets/css/a-guide-to-flexbox/
- https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes
- https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Pure CSS Solution 2 - Display Table [Old solution]:
纯 CSS 方案 2 - 显示表格【旧方案】:
This can also be done by using the CSS display: table;
property (see W3 Specs).
这也可以通过使用 CSSdisplay: table;
属性来完成(参见 W3 规范)。
The HTML:
HTML:
<div id="screen">
<div id="header"></div>
<div id="content">
<div id="content_frame">
<div id="content_wrap"></div>
</div>
</div>
<div id="footer"></div>
</div>
The CSS:
CSS:
html, body, #screen, #content, #content_frame {
height: 100%; /* Make #screen viewport height and #content fill space */
}
#screen {
display: table;
}
#header, #content, #footer {
display: table-row;
}
#content_frame {
overflow-y: auto; /* Add scrollbar */
position: relative;
}
#content_wrap {
position: absolute; /* Fix problem with overflow in FF */
}
The overflow property is unreliable on css table elements and their children, so I had to nest the content. In this case I was forced to nest twice and use position: absolute;
in order to make it work in Firefox. Maybe someone else can come up with a more elegant solution to avoid this 'divitis'.
css table 元素及其子元素的 overflow 属性不可靠,因此我不得不嵌套内容。在这种情况下,我被迫嵌套两次并使用position: absolute;
以使其在 Firefox 中工作。也许其他人可以想出一个更优雅的解决方案来避免这种“分裂”。
Here is a functioning jsfiddle.
这是一个正常运行的jsfiddle。
Warning:This does not appear to work in Opera 12! The content div takes up 100% of the parent's height which causes the rows to overflow the table (as they did in firefox).
警告:这在 Opera 12 中似乎不起作用!内容 div 占据父级高度的 100%,这会导致行溢出表(就像在 Firefox 中所做的那样)。
回答by John Christensen
Do you need to have the center div change size? If you're just trying to make sure that it appears that its background (#8080ff) appears between the header and the footer, why not just have the containing div's background be #8080ff. The header and footer background would override that, and the rest of the div's background would be correct.
你需要让中心div改变大小吗?如果您只是想确保它的背景 (#8080ff) 出现在页眉和页脚之间,为什么不将包含 div 的背景设为 #8080ff。页眉和页脚背景将覆盖它,而 div 背景的其余部分将是正确的。
回答by rpetrich
Absolute positioning is messing you up. Try something like this:
绝对定位让你一团糟。尝试这样的事情:
HTML:
HTML:
<div id="wrapper">
<div id="header">
header
</div>
<div id="content">
content
</div>
<div id="footer">
footer
</div>
</div>
CSS:
CSS:
#wrapper {
width: 200px;
height: 200px;
overflow: visible;
background: #e0e0ff;
}
#header {
background: #80ff80;
}
#content {
background: #8080ff;
}
#footer {
background: #ff8080;
}
edit: perhaps I misunderstood, do you want everything to fit into the 200x200px box or do you want the box to increase its height to fit the content?
编辑:也许我误解了,您是希望所有内容都适合 200x200 像素的框还是希望框增加其高度以适合内容?
回答by busse
Does the parent need to stay at a fixed height?
父母需要保持固定的高度吗?
<div style="position : relative; width : 200px; background-color : #e0e0ff; overflow : hidden;">
<div style="float: left; clear: left; background-color: #80ff80;">
header
</div>
<div style="float: left; clear: left; background-color: #8080ff; overflow : auto; ">
content (how to position it?)
<BR />taller
<BR />taller
<BR />taller
<BR />taller
<BR />taller
<BR />taller
<BR />taller
<BR />taller
</div>
<div style="float: left; clear: left; background-color: #ff8080;">
footer
<BR />taller
</div>
if the height of the parent is fixed, this is the closest I'd know how to get to it offhand -- still not exactly right if those color blocks (as opposed to just text) are truly important and weren't just for illustrating the boundaries of the DIVs:
如果父级的高度是固定的,这是我知道的最接近它的方法——如果这些色块(而不只是文本)真的很重要并且不仅仅是为了说明,那么仍然不完全正确DIV 的边界:
<div style="position : relative; width : 200px; height : 200px; background-color : #e0e0ff; overflow : hidden;">
<div style="float: left; clear: left; background-color: #80ff80; ">
header <BR .> taller
</div>
<div style="float: left; clear: left; background-color: #8080ff; overflow : auto; ">
content (how to position it?)<BR /> and another line
</div>
<div style="background-color: #ff8080; position : absolute; bottom : 0px; left :0; right : 0;">
footer <BR /> taller
</div>