你看到的溢出是因为已经有一个元素占用了父元素的一些空间,所以height: 100%加上另一个元素的高度显然会超过父元素的高度。
有不同的方法来解决这个问题。
我推荐以下两种方式之一:
但是,您也可以使用以下方式解决它们:
CSS 弹性盒
父级需要display: flex 和flex-direction: column 将其子级布置在一列中。
应该长大占用剩余空间的孩子需要flex-grow: 1。
/* Ignore; only for displaying the example */
* {
margin: 0;
font-size: 24px;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.graph-container, .graph {
border: 3px solid black;
box-sizing: border-box;
}
/* The answer */
.graph-container {
height: 60vh;
width: 70vw;
display: flex;
flex-flow: column; /* Shorthand for ('flex-direction' | 'flex-wrap') */
}
.graph {
flex-grow: 1;
border-color: red;
}
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>
CSS 网格
父母需要display: grid和grid-template-rows: auto 1fr。
grid-template-rows: auto 1fr 使第二个孩子占用在其他孩子获得各自未使用fr-unit 定义的空间后剩余的空间。
在这里,<h1> 获得了它需要的空间,所有剩余空间都交给了.graph。
/* Ignore; only for displaying the example */
* {
margin: 0;
font-size: 24px;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.graph-container, .graph {
border: 3px solid black;
box-sizing: border-box;
}
/* The answer */
.graph-container {
height: 60vh;
width: 70vw;
display: grid;
grid-template-rows: auto 1fr;
}
.graph {
border-color: red;
}
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>
CSS calc()
font-size 与 height 的关系
与solution of sergey kuznetsov 一样,您可以猜到height(仅适用于小尺寸!)等于font-size。
这并不总是正确的,因为height 实际上取决于line-height,这又取决于当前使用的字体。
问题,图解
例如,对于给定字体,line-height 大约是 1.05- 比 font-size 高。由于浏览器无法显示小于 px-unit 的值,因此有效地截断了小数位。
这使得该等式仅适用于 font-size 的小值,如下面的示例所示。
示例(toInt() 去掉小数位):
toInt(20px of 'font-size' * 1.05) = 20px of 'height'
toInt(60px of 'font-size' * 1.05) = 63px of 'height'
这意味着,虽然这有效(对于小的 font-size-values):
calc(100% - 20px - 3px)(20px 由于 font-size,3px 由于 border-width)
/* Ignore; only for displaying the example */
* {
margin: 0;
font-size: 24px;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.graph-container, .graph {
border: 3px solid black;
box-sizing: border-box;
}
/* The answer */
.graph-container {
height: 60vh;
width: 70vw;
}
h1 {
font-size: 20px;
}
.graph {
height: calc(100% - 20px - 3px);
display: block;
border-color: red;
}
<div class="graph-container">
<h1>Title</h1>
<div class="graph">Graph</div>
</div>
...这不起作用(对于伟大的font-size-values):
calc(100% - 60px - 3px)(60px 由于font-size,3px 由于border-width)
/* Ignore; only for displaying the example */
* {
margin: 0;
font-size: 24px;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.graph-container, .graph {
border: 3px solid black;
box-sizing: border-box;
}
/* The answer */
.graph-container {
height: 60vh;
width: 70vw;
}
h1 {
font-size: 60px;
}
.graph {
height: calc(100% - 60px - 3px);
display: block;
border-color: red;
}
<div class="graph-container">
<h1>Title</h1>
<div class="graph">Graph</div>
</div>
这就是为什么最好实际定义height-property 本身而不是依赖font-size 或line-height 与height 相同(显然并非总是如此)。这让我们...
使用 CSS 自定义属性
您使用calc(100% - TITLE_HEIGHT) 将第二个孩子的高度设置为剩余空间,其中TITLE_HEIGHT 是另一个孩子的高度<h1>。
我们可以使用CSS Custom properties 设置高度以减少“幻数”的数量,这使得以后重构代码更容易,也许已经更容易阅读了。
我使用--title-height 作为高度。
自定义属性只能在元素本身及其子元素中访问,这意味着我们需要在其父元素.graph-container 中定义它。
现在我们可以像这样使用var() 解析--title-height 的值:
var(--title-height)
/* Ignore; only for displaying the example */
* {
margin: 0;
font-size: 24px;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.graph-container, .graph {
border: 3px solid black;
box-sizing: border-box;
}
/* The answer */
.graph-container {
--title-height: 26px;
height: 60vh;
width: 70vw;
display: block;
}
h1 {
height: var(--title-height);
}
.graph {
height: calc(100% - var(--title-height));
display: block;
border-color: red;
}
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>
JavaScript
在使用JS时,我们需要设置父元素的高度以及<h1>-元素的高度,并计算.graph的剩余高度。剩余高度可以使用Element.style.height设置为.graph的高度。
/* The answer */
var container = document.querySelector('.graph-container');
var title = document.querySelector('h1');
var graph = document.querySelector('.graph');
var remainingHeight = container.clientHeight - title.clientHeight;
graph.style.height = remainingHeight + "px"; // Make sure it is of unit "px"
/* Ignore; only for displaying the example */
* {
margin: 0;
font-size: 24px;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.graph-container, .graph {
border: 3px solid black;
box-sizing: border-box;
}
.graph-container {
height: 60vh;
width: 70vw;
}
.graph {
border-color: red;
display: block;
}
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>
这种方法的问题是,一旦找到高度就会固定。这将使.graph 没有响应。为了实现.graph 是响应式的,我们需要观察父级是否使用ResizeObserver 调整了大小。
每次父级调整大小时,重新计算.graph的大小。
/* The answer */
var container = document.querySelector('.graph-container');
var title = document.querySelector('h1');
var graph = document.querySelector('.graph');
new ResizeObserver(() => {
graph.style.height = container.clientHeight - title.clientHeight + "px";
}).observe(container);
/* Ignore; only for displaying the example */
* {
margin: 0;
font-size: 24px;
}
html, body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.graph-container, .graph {
border: 3px solid black;
box-sizing: border-box;
}
.graph-container {
height: 60vh;
width: 70vw;
}
.graph {
border-color: red;
display: block;
}
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>