屏幕滚动时 Flex 切断边框
Flex cut off border when screen scroll
您好,我有以下 HTML 代码(这里是 "working" example)
<div class="layout">
<main class="main">
<nav class="menu">
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
和风格:
.layout {
height: 100vh;
display: flex;
flex-direction: column;
}
.main {
display: flex;
}
.menu {
display: flex;
border-right: solid 3px red;
width: 258px;
flex-direction: column;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
问题是在Chrome上,当屏幕高度小于左侧菜单并出现滚动条时,向下移动滚动条时不会呈现菜单右边框(红色)。期望的行为是在垂直菜单的末尾绘制红色边框(因此如果我们移动滚动条,我们应该总是看到红色边框)。怎么做?
我不知道为什么 chrome 会这样,但我们至少可以有两种解决方案:
- 将
.layout
class 中的 height: 100vh;
更改为 min-height: 100vh;
- 将
flex: 1 0 auto;
添加到.main
class
可能有人可以解释为什么 chrome 会这样以及为什么上述解决方案有效?
我也想知道为什么我改变了
<div><div class="menu__item">Item</div></div>
到 <div class="menu__item">Item</div>
所有项目都将被压缩到屏幕大小? (在这种情况下,滚动条(和问题)将消失,但不是以可接受的方式)
这是块元素的默认行为。它们变得与其 parent 一样高或一样宽,另一方面,内联元素随着内容而增长。
有几种解决方案可以使 红色边框 大小随内容变化,这里有 3 种,我在其中使用了您自己的答案中提到的 2 来解释它们的工作原理:
将其移动到 main
children。之所以可行,是因为 flex 项目的行为类似于内联块,并随着内容的增长而增长。
使最外层的高度不固定,在本例中为 layout
,改为使用 min-height
。这项工作是因为 flex 容器现在允许高于全视口。
main
不允许增长但允许收缩,因为flex item默认值为flex: 0 1 auto
,所以设置为flex: 1 0 auto
这些条款被交换了。
堆栈片段 1
.layout {
height: 100vh;
display: flex;
flex-direction: column;
}
.main {
display: flex;
}
.menu {
display: flex;
width: 258px;
flex-direction: column;
}
.menu > div {
border-right: solid 3px red;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
<div class="layout">
<main class="main">
<nav class="menu">
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
堆栈片段 2
.layout {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.main {
display: flex;
}
.menu {
display: flex;
width: 258px;
flex-direction: column;
border-right: solid 3px red;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
<div class="layout">
<main class="main">
<nav class="menu">
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
堆栈片段 3
.layout {
height: 100vh;
display: flex;
flex-direction: column;
}
.main {
flex: 1 0 auto;
display: flex;
}
.menu {
display: flex;
width: 258px;
flex-direction: column;
border-right: solid 3px red;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
<div class="layout">
<main class="main">
<nav class="menu">
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
当谈到为什么额外的 div
包裹在 menu__item
工作时,是因为默认情况下弹性项目总是尝试 shrink-to-fit 因为它默认为 flex: 0 1 auto
,但同时不会小于其内容,因为它是额外的 div
即 flex 项目, 有一个大小的内容,它可以。
当您使用上面的选项 3 时,它将在没有 div
包装器的情况下开始工作,因为现在允许 main
随其内容增长,这将使 menu__item
以保持其高度。
堆栈片段
.layout {
height: 100vh;
display: flex;
flex-direction: column;
}
.main {
flex: 1 0 auto;
display: flex;
}
.menu {
display: flex;
width: 258px;
flex-direction: column;
border-right: solid 3px red;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
<div class="layout">
<main class="main">
<nav class="menu">
<div class="menu__item">Item</div>
<div class="menu__item">Item</div>
<div class="menu__item">Item</div>
<div class="menu__item">Item</div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
您好,我有以下 HTML 代码(这里是 "working" example)
<div class="layout">
<main class="main">
<nav class="menu">
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
和风格:
.layout {
height: 100vh;
display: flex;
flex-direction: column;
}
.main {
display: flex;
}
.menu {
display: flex;
border-right: solid 3px red;
width: 258px;
flex-direction: column;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
问题是在Chrome上,当屏幕高度小于左侧菜单并出现滚动条时,向下移动滚动条时不会呈现菜单右边框(红色)。期望的行为是在垂直菜单的末尾绘制红色边框(因此如果我们移动滚动条,我们应该总是看到红色边框)。怎么做?
我不知道为什么 chrome 会这样,但我们至少可以有两种解决方案:
- 将
.layout
class 中的height: 100vh;
更改为min-height: 100vh;
- 将
flex: 1 0 auto;
添加到.main
class
可能有人可以解释为什么 chrome 会这样以及为什么上述解决方案有效?
我也想知道为什么我改变了
<div><div class="menu__item">Item</div></div>
到 <div class="menu__item">Item</div>
所有项目都将被压缩到屏幕大小? (在这种情况下,滚动条(和问题)将消失,但不是以可接受的方式)
这是块元素的默认行为。它们变得与其 parent 一样高或一样宽,另一方面,内联元素随着内容而增长。
有几种解决方案可以使 红色边框 大小随内容变化,这里有 3 种,我在其中使用了您自己的答案中提到的 2 来解释它们的工作原理:
将其移动到
main
children。之所以可行,是因为 flex 项目的行为类似于内联块,并随着内容的增长而增长。使最外层的高度不固定,在本例中为
layout
,改为使用min-height
。这项工作是因为 flex 容器现在允许高于全视口。main
不允许增长但允许收缩,因为flex item默认值为flex: 0 1 auto
,所以设置为flex: 1 0 auto
这些条款被交换了。
堆栈片段 1
.layout {
height: 100vh;
display: flex;
flex-direction: column;
}
.main {
display: flex;
}
.menu {
display: flex;
width: 258px;
flex-direction: column;
}
.menu > div {
border-right: solid 3px red;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
<div class="layout">
<main class="main">
<nav class="menu">
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
堆栈片段 2
.layout {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.main {
display: flex;
}
.menu {
display: flex;
width: 258px;
flex-direction: column;
border-right: solid 3px red;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
<div class="layout">
<main class="main">
<nav class="menu">
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
堆栈片段 3
.layout {
height: 100vh;
display: flex;
flex-direction: column;
}
.main {
flex: 1 0 auto;
display: flex;
}
.menu {
display: flex;
width: 258px;
flex-direction: column;
border-right: solid 3px red;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
<div class="layout">
<main class="main">
<nav class="menu">
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
<div><div class="menu__item">Item</div></div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>
当谈到为什么额外的 div
包裹在 menu__item
工作时,是因为默认情况下弹性项目总是尝试 shrink-to-fit 因为它默认为 flex: 0 1 auto
,但同时不会小于其内容,因为它是额外的 div
即 flex 项目, 有一个大小的内容,它可以。
当您使用上面的选项 3 时,它将在没有 div
包装器的情况下开始工作,因为现在允许 main
随其内容增长,这将使 menu__item
以保持其高度。
堆栈片段
.layout {
height: 100vh;
display: flex;
flex-direction: column;
}
.main {
flex: 1 0 auto;
display: flex;
}
.menu {
display: flex;
width: 258px;
flex-direction: column;
border-right: solid 3px red;
}
.menu__item {
height: 340px;
width: 240px;
margin: 10px;
background: #aaaaaa;
}
<div class="layout">
<main class="main">
<nav class="menu">
<div class="menu__item">Item</div>
<div class="menu__item">Item</div>
<div class="menu__item">Item</div>
<div class="menu__item">Item</div>
</nav>
<section class="main__content">
Some Content
</section>
</main>
</div>