在下面的示例中,在桌面视图上,我想删除的.main-content
元素底部有额外的空间。我有一种感觉,它与height: 100%
有关,flex-basis
但不确定。flex-shrink
不起作用,即使它起作用,也可能会弄乱布局。
有人可以解释一下浏览器如何解释此布局并创建额外的空间。
html,
body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
margin: 0;
}
main {
flex-grow: 1;
}
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100%;
}
header,
footer,
[class^="sidebar-"],
.main-content {
box-sizing: border-box;
padding: 1rem;
}
header,
footer {
background-color: lightgreen;
}
.sidebar-nav {
background-color: lightblue;
}
.sidebar-content {
background-color: lightyellow;
}
.sidebar-right {
background-color: lightpink;
}
.main-content {
background-color: lightgray;
}
@media( min-width: 48em) {
.sidebar-nav,
.sidebar-content {
width: 26%;
margin-right: 8%;
}
.main-content,
.sidebar-right {
flex-basis: 100%;
}
.main-content {
width: 66%;
}
.sidebar-right {
margin-left: 2rem;
width: 20%;
}
.sidebar-right+.main-content {
width: calc( 66% - ( 20% + 2rem));
}
}
/* Ordering of Page Layout */
.sidebar-nav {
order: 1;
}
.main-content {
order: 2;
}
.sidebar-content {
order: 3;
}
.sidebar-right {
order: 4;
}
@media( min-width: 48em) {
.sidebar-content {
order: 2;
}
.main-content {
order: 3;
}
}
<header>
Header
</header>
<main>
<div class="container">
<div class="sidebar-nav">
Sidebar Navigation
</div>
<div class="sidebar-content">
Sidebar Content
</div>
<div class="sidebar-right">
Right Sidebar
</div>
<div class="main-content">
Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content
</div>
</div>
</main>
<footer>
Footer
</footer>
解决方案
将min-height: 0
或overflow: auto
(它们基本相同(添加到main
和.main-content
。
main {
flex-grow: 1;
min-height: 0; /* new */
}
.main-content {
order: 2;
overflow: auto; /* new */
}
在Chrome,Firefox和Edge上进行了测试。
body {
display: flex;
flex-direction: column;
height: 100vh;
margin: 0;
}
main {
flex-grow: 1;
min-height: 0; /* new */
}
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100%;
}
header,
footer,
[class^="sidebar-"],
.main-content {
box-sizing: border-box;
padding: 1rem;
}
header,
footer {
background-color: lightgreen;
}
.sidebar-nav {
background-color: lightblue;
}
.sidebar-content {
background-color: lightyellow;
}
.sidebar-right {
background-color: lightpink;
}
.main-content {
background-color: lightgray;
}
@media(min-width: 48em) {
.sidebar-nav,
.sidebar-content {
width: 26%;
margin-right: 8%;
}
.main-content,
.sidebar-right {
flex-basis: 100%;
}
.main-content {
width: 66%;
}
.sidebar-right {
margin-left: 2rem;
width: 20%;
}
.sidebar-right+.main-content {
width: calc(66% - (20% + 2rem));
}
}
/* Ordering of Page Layout */
.sidebar-nav {
order: 1;
}
.main-content {
order: 2;
overflow: auto; /* new */
}
.sidebar-content {
order: 3;
}
.sidebar-right {
order: 4;
}
@media(min-width: 48em) {
.sidebar-content {
order: 2;
}
.main-content {
order: 3;
}
}
<header>
Header
</header>
<main>
<div class="container">
<div class="sidebar-nav">
Sidebar Navigation
</div>
<div class="sidebar-content">
Sidebar Content
</div>
<div class="sidebar-right">
Right Sidebar
</div>
<div class="main-content">
Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content
</div>
</div>
</main>
<footer>
Footer
</footer>
js小提琴演示
问题#1:Flex最小尺寸算法
弹性项目不能小于沿主轴的内容大小。flex-direction: column
中弹性项目的默认设置是min-height: auto
。您可以使用min-height: 0
覆盖此设置,或者,如果需要滚动条,overflow: auto
。
此处的完整解释:为什么弹性项目不会缩小超过内容大小?
问题#2:百分比高度使用不可靠
根据规范,要使百分比高度按预期工作,它必须在父级上具有定义的高度。例如,您的.container
元素具有以下 CSS:
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 100%;
}
然而,.container
的父级是main
,没有定义高度。
main {
flex-grow: 1;
}
这会导致浏览器之间的行为不一致和不可靠。
如果没有在父级上定义高度,浏览器应根据规范,使用height: auto
(默认设置(呈现元素。
但是,实际上,不同的浏览器具有不同的呈现行为。有些人坚持规范。其他人试图猜测作者的意图(这被称为干预(。
此外,现在一些浏览器接受父母的弹性长度作为身高百分比儿童的充分参考。然而,它是不一致和不可靠的。
处理此设置的最佳方法是确保在父母身上设置高度,以便具有百分比身高的孩子有一个明确的参考点。并确保使用height
属性,因为在某些浏览器/情况下flex-basis
并不总是可靠的。
这里的完整解释:Chrome/Safari没有填充100%的弹性父母的高度