为什么我的div元素的百分比高度不起作用?

87

我有两个高度为90%的

,但显示效果不同。

我尝试将它们放在一个外层的

中,但没有帮助。而且,在Firefox、Chrome、Opera和Safari中都是相同的问题。

有人能解释一下我为什么会遇到这个问题吗?

以下是我的代码:

<div style="height: 90%">
    <div ng-controller="TabsDataCtrl" style="width: 20%; float: left;">
        <tabset>
            <tab id="tab1" heading="{{tabs[0].title}}" ng-click="getContent(0)" active="tabs[0].active"
               disabled="tabs[0].disabled">
            </tab>


            <tab id="tab2" heading="{{tabs[2].title}}" ng-click="getContent(2)" active="tabs[2].active"
                 disabled="tabs[2].disabled">
            </tab>
        </tabset>
    </div>

    <div id="leaflet_map" ng-controller="iPortMapJobController">
        <leaflet center="center" markers="markers" layers="layers" width="78%"></leaflet>
    </div>
</div>
2个回答

209

使用CSS的height属性和百分比值

当使用百分比值时,CSS的height属性是相对于元素的包含块计算的。

假设您的body元素具有height: 1000px,那么一个height: 90%的子元素将获取900px。

如果未为包含块设置显式高度(并且子元素没有绝对定位),则百分比高度的子元素将没有可以参考的高度,并且高度将由内容和其他属性确定。

从规范中可以看到:

10.5 内容高度:height 属性

percentage
指定百分比高度。该百分比是相对于生成的盒子的包含块的高度计算的。如果未明确指定包含块的高度且此元素未绝对定位,则该值计算为 "auto"。

auto
高度取决于其他属性的值。

因此,如果要在

中使用百分比高度,请指定所有父元素的高度,包括根元素(例如,html, body {height:100%;}

请注意,min-heightmax-height不可用。必须使用height属性。

以下是一个小结:

John: 我想将我的

的高度设置为100%
Jane: 百分之百的参考是什么?
John: 它的容器,也就是上一级父元素。
Jane: 好的。那么
的父元素的高度是多少?
John: 没有设置。自适应的,我猜测。由内容驱动。
Jane: 所以,你希望该
具有未知变量的100%高度?
John: [沉默]
Jane: 嘿,约翰,我能有其中50%吗?
John: 百分之五十的参考是什么?
Jane: 没错!
Jane: 百分比是相对值。您总是必须问 "参考于什么的百分之几?"。通过为每个父元素直到bodyhtml声明显式高度,您为具有百分比高度的每个子元素建立了一个参考框架,从而使高度有效。

示例

假设您希望

的高度为其父元素的50%。

这样是行不通的:

<article>
    <section>
        <div style="height:50%"></div>
    </section>
</article>

这也不会:

<article>
    <section style="height:100%">
        <div style="height:50%"></div>
    </section>
</article>

这个也不会:

<article style="height:100%">
    <section style="height:100%">
        <div style="height:50%"></div>
    </section>
</article>

这个也会失败:

<body style="height:100%">
    <article style="height:100%">
        <section style="height:100%">
            <div style="height:50%"></div>
        </section>
    </article>
</body>

现在,它终于能正常工作了:

<html style="height:100%">
    <body style="height:100%">
        <article style="height:100%">
            <section style="height:100%">
                <div style="height:50%"></div>
            </section>
        </article>
    </body>
 </html>

这个也可以工作:

<article>
    <section style="height: 500px">
        <div style="height:50%"></div>
    </section>
</article>

但不包括这个:

<article>
    <section style="min-height: 500px">
        <div style="height:50%"></div>
    </section>
</article>

示例代码


使用100vh

正如您所见,百分比高度有点棘手。您可以通过简单地使用视口百分比高度来避免复杂性(即永远不必考虑父元素)。每当您想要一个框具有与视口相同的高度时,请使用height: 100vh而不是height: 100%。不需要其他任何东西。

绝对定位的例外情况

规范中所述,绝对定位的元素是百分比高度规则的例外情况。更多详细信息请参见:将100%高度应用于嵌套的非弹性元素


2
@Bjango,是的,那是不正确的。HTML元素通常默认为height: auto(内容的高度),而不是height: 100%。另一方面,块级元素的宽度默认为width: 100%(父元素的宽度)。 - Michael Benjamin
1
这里有更详细的解释:https://dev59.com/JHI_5IYBdhLWcg3wAd82#46546152 - Michael Benjamin
2
哈哈,阅读完这个回答的总结部分后,我感觉自己好像刚读完《Head First CSS》一书。干得好! - Nico Van Belle
1
@Michael_B 哎呀,我真没想到你几天后还会回复哈哈。非常感谢你的回复。好的,我会发布一个关于这个问题的正式问题,因为我已经做了一些研究,它不是任何重复的内容(你可能已经注意到了)。在那个帖子上见,我会在这里用链接提醒你。 - Marius Mucenicu
1
非常感谢您的答复!我的问题在于链条中有一个min-height,我毫不知情,这导致了子元素的 height: 100% 失败。 - Geoff Davids
显示剩余13条评论

46

使用vh(视窗高度)替代百分比。它将获取浏览器的高度并相应地调整大小,例如:

height:90vh;

试试这段代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div id ="wrapper">
    <div id="tabs" ng-controller="TabsDataCtrl">
        <tabset>
            <tab id="tab1" heading="{{tabs[0].title}}" ng-click="getContent(0)" active="tabs[0].active"
               disabled="tabs[0].disabled">
            </tab>


            <tab id="tab2" heading="{{tabs[2].title}}" ng-click="getContent(2)" active="tabs[2].active"
                 disabled="tabs[2].disabled">
            </tab>
        </tabset>
    </div>

    <div id="leaflet_map" ng-controller="iPortMapJobController">
        <leaflet center="center" markers="markers" layers="layers"></leaflet>
    </div>
    </div>
</body>
</html>

使用 CSS

<style>
    #wrapper{height:60vh;}
    #tabs {width:20% float:left; height:60vh; overflow-y:scroll; overflow-x:hidden;}
    #leaflet-map{width:78%; height:60vh; overflow-y:scroll;  overflow-x:hidden;}
</style>

2
它没有产生任何区别 - victor
我稍微修改了CSS,现在它看起来像这样:#wrapper { height: 90vh; }#tabs { width: 20%; float: left; height: 90vh; overflow-y: scroll; overflow-x: hidden; }#leaflet-map { width: 78%; float: right; overflow-y: scroll; overflow-x: hidden; } - victor

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