屏幕滚动时 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 会这样,但我们至少可以有两种解决方案:

  1. .layout class 中的 height: 100vh; 更改为 min-height: 100vh;
  2. flex: 1 0 auto;添加到.mainclass

可能有人可以解释为什么 chrome 会这样以及为什么上述解决方案有效?

我也想知道为什么我改变了 <div><div class="menu__item">Item</div></div><div class="menu__item">Item</div> 所有项目都将被压缩到屏幕大小? (在这种情况下,滚动条(和问题)将消失,但不是以可接受的方式)

这是块元素的默认行为。它们变得与其 parent 一样高或一样宽,另一方面,内联元素随着内容而增长。

有几种解决方案可以使 红色边框 大小随内容变化,这里有 3 种,我在其中使用了您自己的答案中提到的 2 来解释它们的工作原理:

  1. 将其移动到 mainchildren。之所以可行,是因为 flex 项目的行为类似于内联块,并随着内容的增长而增长。

  2. 使最外层的高度不固定,在本例中为 layout,改为使用 min-height。这项工作是因为 flex 容器现在允许高于全视口。

  3. 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,但同时不会小于其内容,因为它是额外的 divflex 项目, 有一个大小的内容,它可以。

当您使用上面的选项 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>