将垂直滚动条应用于内容框,而不是主体/视口

Apply vertical scrollbar to content box, not body / viewport

我有一个包含动态内容的网站,我希望其中的一个部分填充屏幕的剩余高度,但需要注意的是,如果该部分中的内容会导致页面高度超过视口高度,我想将它的部分高度停止在屏幕的底部边缘,并为该部分添加一个垂直滚动条。

我正在使用 CSS Flexbox。这是标记和 CSS:

的一个非常简化的版本

body, div, h1, h2, html, p {
  margin: 0;
  padding: 0;
}

body,
html {
  height: 100%;
}

.siteContainer {
  background: gold;
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

.contentContainer {
  background: lightblue;
  display: flex;
  flex: 1;
  flex-direction: column;
}

.subcontentContainer {
  background: pink;
  flex: 1;
  overflow-y: scroll;
}
<div class="siteContainer">
  <h1>Header</h1>
  <div class="contentContainer">
    <h2>Subheader</h2>
    <div class="subcontentContainer">
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
    </div>
  </div>
</div>

假设您的屏幕有一定高度,您应该会看到粉红色部分占据了大部分屏幕,并且文本不应垂直离开屏幕。

但是,如果您多次复制并粘贴 <p>Some text here.</p> 部分以使文本离开屏幕,您将看到视口滚动条已启用。

虽然我不想使用视口滚动条,但我想在屏幕的底部边缘停止内容(大概是 overflow-y 或类似的东西)并在粉红色部分添加滚动条而不是视口滚动条。

仅使用 CSS 是否可行?如果可行,如何实现?谢谢。

如果将 overflow-y: hidden 设置为正文,外部滚动条将消失。

将高度从 bodysiteContainer 设置为 100vh

html {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

body {
  margin: 0;
  padding: 0;
  height: 100vh;
  overflow-y: hidden;  
}

body,
div,
h1,
h2,
html,
p {
  margin: 0;
  padding: 0;
}

.siteContainer {
  background: gold;
  display: flex;
  flex-direction: column;
  min-height: 100%;
  height: 100vh;
}

.contentContainer {
  background: lightblue;
  display: flex;
  flex: 1;
  flex-direction: column;
}

.subcontentContainer {
  background: pink;
  flex: 1;
  overflow-y: auto;
}
<div class="siteContainer">
  <h1>Header</h1>
  <div class="contentContainer">
    <h2>Subheader</h2>
    <div class="subcontentContainer">
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
    </div>
  </div>
</div>

问题归结为:flex: 1 在你的代码中。

flex: 1 是一个 shorthand 规则,转换为:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0

因为您使用的是列方向容器,所以 flex-basis 代表 height。因此,您已将弹性项目设置为 height: 0.

但是overflow属性只能在容器有设置高度的情况下才能工作

来自 MDN:

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

嗯,对于某些浏览器,flex-basis: 0 可能不足以满足这些条件,因此不会发生溢出。

为确保您的布局能够跨浏览器可靠地工作,请在溢出元素上设置一个高度(任意高度)。将此添加到您的代码中:

.subcontentContainer {
   flex: 1 1 1px;
 }

.siteContainer {
  background: gold;
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.contentContainer {
  background: lightblue;
  display: flex;
  flex: 1;
  flex-direction: column;
}

.subcontentContainer {
  background: pink;
  flex: 1 1 1px; /* ADJUSTMENT */
  overflow-y: auto;
}

body,
div,
h1,
h2,
html,
p {
  margin: 0;
  padding: 0;
}
<div class="siteContainer">
  <h1>Header</h1>
  <div class="contentContainer">
    <h2>Subheader</h2>
    <div class="subcontentContainer">
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
      <p>Some text here.</p>
    </div>
  </div>
</div>