如何在不指定父元素高度的情况下强制子元素 div 高度为父元素 div 的 100%?

737
我有一个网站,其结构如下:
<div id="header"></div>

<div id="main">
  <div id="navigation"></div>
  <div id="content"></div>
</div>

<div id="footer"></div>

导航栏在左侧,内容区域在右侧。内容区域的信息通过 PHP 动态获取,因此每次加载页面时都不同。

我该如何垂直缩放导航栏,以使其高度与内容区域的高度相同,无论加载哪个页面?


2
在父元素上使用display: table,在子元素上使用display: table-cell。这将使子元素与父元素一样长。请参见https://dev59.com/cWEh5IYBdhLWcg3wMA0t。 - user31782
16
你可以为 div#main 设置 display: flex; align-items: stretch;,但不要对 div#content 使用 height: 100% - Ihor
31个回答

657

对于家长:

display: flex;

你应该添加一些前缀, http://css-tricks.com/using-flexbox/.

正如@Adam Garner所指出的,align-items: stretch;是不必要的。它的使用也是针对父元素而非子元素。如果你想定义子元素的伸展,可以使用align-self。

.parent {
  background: red;
  padding: 10px;
  display:flex;
}

.other-child {
  width: 100px;
  background: yellow;
  height: 150px;
  padding: .5rem;
}

.child {  
  width: 100px;
  background: blue;
}
<div class="parent">
  <div class="other-child">
    Only used for stretching the parent
  </div>
  <div class="child"></div>
</div>


5
IE11 不完全支持 flexbox 和高度属性。点击这里的“已知问题”查看:http://caniuse.com/#feat=flexbox - adamdport
@SuperUberDuper 好的,你可以在Bootstrap中使用它,像这样:https://jsfiddle.net/prdwaynk/ 但如果我是你,我会使用基础框架,它已经准备好使用Flexbox了:http://foundation.zurb.com/sites/docs/xy-grid.html BS4也将拥有Flexbox,但它仍处于alpha版本,而且我认为基础框架更好。 - Aiphee
10
如果您使用了align-items: center,那么需要拉伸的项目应该使用align-self: normal - Dominic
19
这不是正确的答案,因为这需要设置父元素的高度。问题中说“不指定父元素的高度”? - Lying_cat
9
@Aiphee 给你点了反对票,因为似乎你没有看到原问题中 无需设置父元素高度 这部分内容,但是你的“解决方案”却恰好做了这件事。 - tylerism
显示剩余4条评论

203

注意: 本解答适用于不支持Flexbox标准的旧版浏览器。对于现代方法,请参见: https://dev59.com/G3NA5IYBdhLWcg3wBpBm#23300532


我建议你查看使用跨浏览器CSS和无需Hack实现等高列

基本上,以兼容浏览器的方式使用CSS来做这件事不是很容易(但在表格中很简单),所以最好找到一个合适的预打包解决方案。

此外,答案取决于您需要100%高度还是等高。通常是等高的。如果要求100%高度,则答案略有不同。


8
container2上加上边框border:1px solid blue之后,问题就出现了:蓝色边框会在前两列显示,而不是只在第二列显示,这并不符合我们的预期。 - Julien Kronegg
@bfritz,更好的解决方案是使用display:table - Siler

112

这是一个设计师经常遇到的令人沮丧的问题。窍门在于您需要在CSS中将BODY和HTML的高度设置为100%。

html,body {
    height:100%;
}

这段看似没用的代码是为了向浏览器定义100%的含义。虽然有些令人沮丧,但这是最简单的方法。


11
但这并不总是有效,例如如果在绝对定位元素内有一个相对定位元素,它就不再强制具有布局。 - tim
1
另外,如果你想要在窗口右侧摆脱滚动条(在Firefox v28中出现),给窗口留些空间:html { height: 100%; } body { height: 98%; } - Chris Middleton
80
只有当所有父级元素的高度设为100%时,此方法才会生效。仅对html和body元素设置高度是不够的,所有父级元素都必须定义高度。 - RaduM
我同意你的观点,但这似乎回答了一个不同的问题。OP是在谈论整个页面吗?从现在的阅读方式来看,它似乎只是关于父元素高度的100%,这可能不是页面或视口。 - Michael Scheper
谢谢,我在不知道它的实际作用的情况下,已经将相同的代码用于其他项目。如果你只将height: 100%应用于body,它是不起作用的,这对我来说有点令人沮丧。 - Akash Kumar Seth
2
不适用于普通的div。 - Lying_cat

98

我发现将两个列设置为 display: table-cell; 而不是 float: left; 可以很好地解决问题。


11
微软公司自己不再支持它,如果这能帮助任何人说服他们的客户... - Heraldmonkey
4
这应该是被采纳的答案。时代已经变化,这个答案在所有浏览器中都适用(在Safari 5.1.17中有一个小问题)。只需两行CSS代码,即可立即获得您想要的效果,我想不到任何缺点。 - callmetwan
7
举起这个答案,伙计们用力! - user764357
这是最好的答案。是的,我们可以制作一个表格来做到这一点,但它不是表格数据,相反,我们将div视为表格单元格...太棒了! - Derokorian
这实际上为我指明了另一种情况的正确方向。如果有人在Firefox或Edge中无法使用既是正方形div又是flex容器的情况下遇到问题,只需记住将:before元素设置为display: table即可。不要问我为什么,但它可以解决问题。 - CGodo
虽然聪明,但使用display: table-cell等解决布局问题的解决方案已经被flexbox取代。 - csvan

65

如果你不介意在内容div出现意外缩短的情况下导航div被裁剪,那么至少有一种简单的方法:

#main {
position: relative;
}

#main #navigation {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 10em; /* or whatever */
}

#main #content {
margin: 0;
margin-left: 10em; /* or whatever width you set for #navigation */
}

否则,还可以使用伪列技术


2
非常感谢,你救了我的一天。我不知道可以同时定义顶部和底部,并且它会这样工作。 - rubish
这将使容器的内容停止调整大小。 - DreamWave
1
+1 是因为它明确回答了 OP 的问题:“如何在不指定父 Div 高度的情况下强制子 Div 占满父 Div 的 100%?”我的问题不需要列(虽然在问题详情中提到,但不在主标题中),而是一个 div 在另一个 div 后面。这个答案适用于两种应用程序。 - Luke

35
#main {
    overflow: hidden;
}
#navigation, #content {
    margin-bottom: -1000px;
    padding-bottom: 1000px;
}

我必须说我一直在寻找这种解决方案。非常简单,显而易见,但没有人想到。祝贺@Roman! - Greg0ry
非常感谢!我认为这也是许多类似CSS问题的解决方案,其中使用溢出和百分比宽度/高度限制区域的元素经常会推动外部布局 - 所有这些都是由底部边距引起的。 - Kenneth Ellested

16

使用jQuery:

$(function() {
    function unifyHeights() {
        var maxHeight = 0;
        $('#container').children('#navigation, #content').each(function() {
            var height = $(this).outerHeight();
            // alert(height);
            if ( height > maxHeight ) {
                maxHeight = height;
            }
        });
        $('#navigation, #content').css('height', maxHeight);
    }
    unifyHeights();
});

25
这里可以使用Math.max()函数。 - alex
1
我在某些情况下无法让CSS工作,真的只需要一个快速修复。这可能不是最“标准”的方法,但这完全可以完成任务。谢谢!:-] - user131441
1
当使用JQuery的css函数时,您无法像使用纯CSS解决方案时那样区分屏幕和打印媒体。因此,您可能会遇到打印问题。 - Julien Kronegg

16
#main {
   display: table;
} 
#navigation, #content {
   display: table-cell;
}

请看这个示例


这正是我正在做的事情,想要添加一个答案。我也使用了 height: 100%,但事实证明它并不需要。 - jcubic
在现代网站中,不建议使用CSS布局中的表格。 - joshwcorbett

15

height : <百分比> 只有在所有父节点都指定了像素、ems等固定高度的情况下才能生效。这些高度值应该在顶层设置,以便高度可以级联到您的元素。

您可以像 @Travis 所述那样将 html 和 body 元素指定为 100%,以使页面高度级联到您的节点。


14

经过长时间的搜索和尝试,除了以下方法外,没有解决我的问题:

style = "height:100%;"

在子元素上应用以下样式:

对于父元素,请应用此样式:

.parent {
    display: flex;
    flex-direction: column;
}

此外,我正在使用Bootstrap,这并没有破坏我的响应式设计。


2
我必须删除 flex-direction: column; 才能让它对我起作用。 - Richard Hedges

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接