将子 div 高度限制为父容器高度
restrict child div height to parent container height
我希望 graph div 的高度一直延伸到它的父级(graph-container) 容器,但不能超出它。我已经尝试将 graph 的 高度设置为 100% 并继承,但它们都会导致它延伸超过它的父容器的底部边缘(我不想使用溢出:隐藏)。有没有办法在 graph 上设置高度 属性 以便它自动将其高度设置为正确的值?
当前输出:
我想要的:
当前代码:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 20px;
}
.wrapper {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
}
.graph-container {
border: 3px solid black;
height: 60vh;
width: 70vw;
margin-top: 10vh;
}
.graph {
height: 100%;
width: 100%;
border: 3px solid red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrapper">
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>
</div>
</body>
</html>
我还想提出一个使用 calc()
的解决方案。即:
height: calc(100% - 23px);
其中 23px 是 h1
标签 (font-size: 20px
),边框 graph
class 是 3 像素 (border: 3px solid red
)。
在此示例中,子项 div 的高度将完全适合父项 div。
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 20px;
}
.wrapper {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
}
.graph-container {
border: 3px solid black;
height: 60vh;
width: 70vw;
margin-top: 10vh;
}
.graph {
height: calc(100% - 23px);
width: 100%;
border: 3px solid red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrapper">
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>
</div>
</body>
</html>
你看到的溢出是因为已经有一个元素占用了parent的一些space,所以height: 100%
加上其他元素的高度将明显超过 parents 高度。
有不同的方法可以解决这个问题。
我推荐以下两种方式之一:
不过,您也可以通过以下方式解决它们:
- CSS
calc()
- JavaScript
CSS弹性框
parent 需要 display: flex
和 flex-direction: column
将其 children 排成一列。
要长满剩余space的child需要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 网格
parent需要display: grid
和grid-template-rows: auto 1fr
。
grid-template-rows: auto 1fr
让第二个child占据剩下的space,也就是另一个children得到各自的space后剩下的space没有 fr
单位定义。
这里,<h1>
得到了它需要的space,剩下的space全部给了.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
的关系
与 一样,您可以猜测 height
(仅适用于小尺寸!)等于 font-size
。
这并不总是正确的,因为 height
实际上取决于 line-height
,这又取决于当前使用的字体。
问题,图文并茂
例如,对于给定字体,line-height
大约比 font-size
高 1.05
倍。由于浏览器无法显示小于 px
的单位,小数位被有效地截断了。
这使得等式仅适用于 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
值):
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
-值):
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
-属性 本身而不是依赖 font-size
或 line-height
与 [=39 相同=](它 apparently 并不总是)。这将我们带到...
使用 CSS 自定义属性
您将第二个 child 的高度设置为剩余的 space 和 calc(100% - TITLE_HEIGHT)
其中 TITLE_HEIGHT
是另一个 child 的高度,<h1>
.
我们可以使用CSS Custom properties设置高度来减少“幻数”的数量,这使得以后重构代码更容易,也许已经更容易阅读了。
我使用 --title-height
作为高度。
自定义属性只能在元素本身及其children中访问,这意味着我们需要在它们的parent.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时,我们需要设置parent的高度以及<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
响应,我们需要观察 parent 是否使用 ResizeObserver
.
调整大小
每次 parent 调整大小时,重新计算 .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>
我希望 graph div 的高度一直延伸到它的父级(graph-container) 容器,但不能超出它。我已经尝试将 graph 的 高度设置为 100% 并继承,但它们都会导致它延伸超过它的父容器的底部边缘(我不想使用溢出:隐藏)。有没有办法在 graph 上设置高度 属性 以便它自动将其高度设置为正确的值?
当前输出:
我想要的:
当前代码:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 20px;
}
.wrapper {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
}
.graph-container {
border: 3px solid black;
height: 60vh;
width: 70vw;
margin-top: 10vh;
}
.graph {
height: 100%;
width: 100%;
border: 3px solid red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrapper">
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>
</div>
</body>
</html>
我还想提出一个使用 calc()
的解决方案。即:
height: calc(100% - 23px);
其中 23px 是 h1
标签 (font-size: 20px
),边框 graph
class 是 3 像素 (border: 3px solid red
)。
在此示例中,子项 div 的高度将完全适合父项 div。
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 20px;
}
.wrapper {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
}
.graph-container {
border: 3px solid black;
height: 60vh;
width: 70vw;
margin-top: 10vh;
}
.graph {
height: calc(100% - 23px);
width: 100%;
border: 3px solid red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrapper">
<div class="graph-container">
<h1>Graph Container</h1>
<div class="graph">Graph</div>
</div>
</div>
</body>
</html>
你看到的溢出是因为已经有一个元素占用了parent的一些space,所以height: 100%
加上其他元素的高度将明显超过 parents 高度。
有不同的方法可以解决这个问题。
我推荐以下两种方式之一:
不过,您也可以通过以下方式解决它们:
- CSS
calc()
- JavaScript
CSS弹性框
parent 需要 display: flex
和 flex-direction: column
将其 children 排成一列。
要长满剩余space的child需要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 网格
parent需要display: grid
和grid-template-rows: auto 1fr
。
grid-template-rows: auto 1fr
让第二个child占据剩下的space,也就是另一个children得到各自的space后剩下的space没有 fr
单位定义。
这里,<h1>
得到了它需要的space,剩下的space全部给了.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
的关系
与 height
(仅适用于小尺寸!)等于 font-size
。
这并不总是正确的,因为 height
实际上取决于 line-height
,这又取决于当前使用的字体。
问题,图文并茂
例如,对于给定字体,line-height
大约比 font-size
高 1.05
倍。由于浏览器无法显示小于 px
的单位,小数位被有效地截断了。
这使得等式仅适用于 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
值):
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
-值):
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
-属性 本身而不是依赖 font-size
或 line-height
与 [=39 相同=](它 apparently 并不总是)。这将我们带到...
使用 CSS 自定义属性
您将第二个 child 的高度设置为剩余的 space 和 calc(100% - TITLE_HEIGHT)
其中 TITLE_HEIGHT
是另一个 child 的高度,<h1>
.
我们可以使用CSS Custom properties设置高度来减少“幻数”的数量,这使得以后重构代码更容易,也许已经更容易阅读了。
我使用 --title-height
作为高度。
自定义属性只能在元素本身及其children中访问,这意味着我们需要在它们的parent.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时,我们需要设置parent的高度以及<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
响应,我们需要观察 parent 是否使用 ResizeObserver
.
每次 parent 调整大小时,重新计算 .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>