绝对定位、百分比高度和 flexbox
Absolute positioning, percentage heights and flexbox
我想要一个具有最大高度(例如其容器的 50%)的 flexbox 容器。很简单吧?
.container {
display: flex;
flex-direction: column;
border: 1px solid red;
overflow: hidden;
height: 50%;
position: absolute;
}
.list {
flex: 0 1 auto;
overflow: auto;
}
.fixed {
flex: 0 0 auto;
}
<div class="container">
<header class="fixed">Header</header>
<div class="list">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<footer class="fixed">Footer</footer>
</div>
可行,但删除 position: absolute
后会增大 50% 以上(并且宽度会发生变化)。这是为什么?
.container {
display: flex;
flex-direction: column;
border: 1px solid red;
overflow: hidden;
height: 50%;
}
.list {
flex: 0 1 auto;
overflow: auto;
}
.fixed {
flex: 0 0 auto;
}
<div class="container">
<header class="fixed">Header</header>
<div class="list">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<footer class="fixed">Footer</footer>
</div>
行为在规范中定义:
10.5 Content height: the height
property
<percentage>
Specifies a percentage height.
The percentage is calculated with respect to the height of the
generated box's containing block.
If the height of the containing block is not specified explicitly
(i.e., it depends on content height), and this element is not
absolutely positioned, the used height is calculated as if auto
was
specified.
所以,这里有两个要点:
当你的容器不是绝对定位的(即,它保持在流中)时,父级没有定义高度的事实意味着 height: 50%
解析为 height: auto
(内容的高度)。
如果您设置 body { height: 100vh }
,您的容器将占据 50% 的高度。
body {
height: 100vh;
}
.container {
display: flex;
flex-direction: column;
border: 1px solid red;
overflow: hidden;
height: 50%;
}
.list {
flex: 0 1 auto;
overflow: auto;
}
.fixed {
flex: 0 0 auto;
}
<div class="container">
<header class="fixed">Header</header>
<div class="list">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<footer class="fixed">Footer</footer>
</div>
当您的容器是绝对定位时,height: auto
规则不适用,height: 50%
按预期工作。
此外,流入块级元素占用其容器的宽度。一旦应用绝对定位——从文档流中移除元素——"take the width of the parent" 规则不再适用,你需要指定容器的宽度,或定义偏移属性(即 left
, right
, 等等).
.container {
display: flex;
flex-direction: column;
border: 1px solid red;
overflow: hidden;
height: 50%;
position: absolute;
/* new */
left: 0;
right: 0;
/* or this */
/* width: 100%; */
}
.list {
flex: 0 1 auto;
overflow: auto;
}
.fixed {
flex: 0 0 auto;
}
/* new */
* { box-sizing: border-box; }
<div class="container">
<header class="fixed">Header</header>
<div class="list">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<footer class="fixed">Footer</footer>
</div>
更多详情:
- Block elements consume the full width of their parent, by default.
我想要一个具有最大高度(例如其容器的 50%)的 flexbox 容器。很简单吧?
.container {
display: flex;
flex-direction: column;
border: 1px solid red;
overflow: hidden;
height: 50%;
position: absolute;
}
.list {
flex: 0 1 auto;
overflow: auto;
}
.fixed {
flex: 0 0 auto;
}
<div class="container">
<header class="fixed">Header</header>
<div class="list">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<footer class="fixed">Footer</footer>
</div>
可行,但删除 position: absolute
后会增大 50% 以上(并且宽度会发生变化)。这是为什么?
.container {
display: flex;
flex-direction: column;
border: 1px solid red;
overflow: hidden;
height: 50%;
}
.list {
flex: 0 1 auto;
overflow: auto;
}
.fixed {
flex: 0 0 auto;
}
<div class="container">
<header class="fixed">Header</header>
<div class="list">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<footer class="fixed">Footer</footer>
</div>
行为在规范中定义:
10.5 Content height: the
height
property
<percentage>
Specifies a percentage height.
The percentage is calculated with respect to the height of the generated box's containing block.
If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the used height is calculated as if
auto
was specified.
所以,这里有两个要点:
当你的容器不是绝对定位的(即,它保持在流中)时,父级没有定义高度的事实意味着
height: 50%
解析为height: auto
(内容的高度)。如果您设置
body { height: 100vh }
,您的容器将占据 50% 的高度。
body {
height: 100vh;
}
.container {
display: flex;
flex-direction: column;
border: 1px solid red;
overflow: hidden;
height: 50%;
}
.list {
flex: 0 1 auto;
overflow: auto;
}
.fixed {
flex: 0 0 auto;
}
<div class="container">
<header class="fixed">Header</header>
<div class="list">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<footer class="fixed">Footer</footer>
</div>
当您的容器是绝对定位时,
height: auto
规则不适用,height: 50%
按预期工作。此外,流入块级元素占用其容器的宽度。一旦应用绝对定位——从文档流中移除元素——"take the width of the parent" 规则不再适用,你需要指定容器的宽度,或定义偏移属性(即
left
,right
, 等等).
.container {
display: flex;
flex-direction: column;
border: 1px solid red;
overflow: hidden;
height: 50%;
position: absolute;
/* new */
left: 0;
right: 0;
/* or this */
/* width: 100%; */
}
.list {
flex: 0 1 auto;
overflow: auto;
}
.fixed {
flex: 0 0 auto;
}
/* new */
* { box-sizing: border-box; }
<div class="container">
<header class="fixed">Header</header>
<div class="list">
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<footer class="fixed">Footer</footer>
</div>
更多详情:
- Block elements consume the full width of their parent, by default.