CSS -为什么不工作的百分比高度?

为什么height的百分比值不起作用,而width的百分比值却可以呢?

例如:

<div id="working"></div>
<div id="not-working"></div>
#working{
width:80%;
height:140px;
background:orange;
}
#not-working{
width:80%;
height:30%;
background:green;
}

#working的宽度最终是视口的80%,但#not-working的高度最终是0。

312452 次浏览

你需要给它一个有高度的容器。Width使用视口作为默认宽度

块元素的高度默认为块内容的高度。假设是这样的:

<div id="outer">
<div id="inner">
<p>Where is pancakes house?</p>
</div>
</div>

#inner将增长到足够高以包含段落,而#outer将增长到足够高以包含#inner

当你以百分比的形式指定高度或宽度时,这是相对于元素的父元素的百分比。在width的情况下,除非另有指定,否则所有块元素都与它们的父元素一样宽,一直到<html>;因此,块元素的宽度与它的内容无关,并且width: 50%会产生一个定义良好的像素数。

然而,块元素的高度取决于内容,除非你指定了一个特定的高度。因此,在涉及高度的父元素和子元素之间存在反馈,并且height: 50%不会产生一个定义良好的值,除非你通过给父元素一个特定的高度来打破反馈循环。

没有内容,高度就没有值来计算百分比。但是,如果没有指定父元素,宽度将从DOM中获取百分比。(用你的例子)把第二个div放在第一个div里面,会呈现一个结果…在下面的例子…

<div id="working">
<div id="not-working"></div>
</div>

第二个div的高度是第一个div的30%。

我认为你只需要给它一个父容器…即使容器的高度是用百分比定义的。 这个接缝工作得很好:JSFiddle

html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.wrapper {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 50%;
}

height属性中的百分比值有点复杂,并且widthheight属性实际上彼此的行为不同。让我带你参观一下规格。

height属性:

让我们来看看CSS快照2010规范中关于height:

百分比是根据生成框的包含块的高度计算的。如果包含块的高度没有明确指定(即,它取决于内容高度),并且该元素不是绝对定位,则该值计算为'auto'。根元素上的高度百分比是相对于初始包含块. xml的。注意:对于绝对定位的元素,其包含的块是基于块级元素的,百分比是根据该元素的填充框的高度计算的。

好的,让我们一步一步地把它拆开:

百分比是根据生成框的包含块的高度计算的。

什么是包含块?这有点复杂,但对于默认static位置的普通元素来说,它是:

最近的块容器祖先盒

或者用英语来说,是它的父方框。(知道fixedabsolute的位置是什么也是非常值得的,但我忽略了这一点,以保持答案简短。)

举两个例子:

.
<div   id="a"  style="width: 100px; height: 200px; background-color: orange">
<div id="aa" style="width: 100px; height: 50%;   background-color: blue"></div>
</div>

.
<div   id="b"  style="width: 100px;              background-color: orange">
<div id="bb" style="width: 100px; height: 50%; background-color: blue"></div>
</div>

在这个例子中,包含#aa的块是#a,以此类推,#b#bb。到目前为止,一切顺利。

height规范的下一句话是我在这个答案的介绍中提到的复杂性:

如果包含块的高度为没有显式指定(即,它取决于内容高度),且该元素不是绝对定位的,则该值计算为'auto'. 0。

啊哈!包含块的高度是否已明确指定很重要!

  • #aa的情况下,height:200px的50%为100px
  • 但是height:auto的50%是auto,在#bb的情况下是0px,因为没有auto可以展开的内容

正如规范所说,包含块是否被绝对定位也很重要,但让我们继续width

width属性:

那么它对width的工作方式相同吗?让我们来看看规范:

百分比是根据生成的框的包含块的宽度计算的。

看看这些熟悉的例子,从前面的例子中调整为改变width而不是height:

.
<div   id="c"  style="width: 200px; height: 100px; background-color: orange">
<div id="cc" style="width: 50%;   height: 100px; background-color: blue"></div>
</div>

.
<div   id="d"  style="            height: 100px; background-color: orange">
<div id="dd" style="width: 50%; height: 100px; background-color: blue"></div>
</div>

  • #cc的情况下,width:200px的50%为100px
  • width:auto的50%是width:auto最终值的50%,不像height,没有特殊的规则来区别对待这种情况。

现在,这里是棘手的地方:auto意味着不同的东西,部分取决于它是为width还是height指定的!对于height,它只是意味着适合内容*所需的高度,但对于widthauto实际上更复杂。您可以从代码片段中看到,在这种情况下,它最终是视口的宽度。

规范说明了宽度的自动值是什么?

宽度取决于其他属性的值。请参阅下面的部分。

哇,这没什么用。为了省事,我找到了我们用例的相关部分,标题为“计算宽度和边距”,副标题为"正常流中的块级、非替换元素":

以下约束必须在其他属性的使用值之间保持:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' =包含块的宽度

好,所以width加上相关的边距、边框和填充边框必须全部加起来等于包含块的宽度(继承了height的工作方式)。再来一句说明:

如果'width'被设置为'auto',则任何其他'auto'值都将变为'0','width'将从由此产生的等式中得到。

啊哈!因此在本例中,width:auto的50%是视口的50%。希望现在一切都有意义了!


脚注

至少在这种情况下是如此。spec好吧,现在一切都有点意义了。

另一个选择是为div添加样式

<div style="position: absolute; height:somePercentage%; overflow:auto(or other overflow value)">
//to be scrolled
</div>

这意味着一个元素的定位相对于最近的定位祖先。