嵌套网格中的溢出滚动中断

overflow scroll breaks in nested grid

我有两个 CSS-网格。一个在另一个中。我不希望整个页面滚动,而只希望嵌套网格的网格区域的内容滚动。此嵌套网格应填满所有可用 space。但是 overflow:scroll 在此嵌套网格中不起作用。

正如您在下面的简化示例中看到的那样,div 与 class .aside 完美地工作,而 div 与 .bottomleft 则没有滚动。

div-高度开始与 .main-container-div 断裂,但我不知道为什么。

真正让我困惑的是为什么在 .aside - div 中一切正常。我在这里看到的唯一区别是它不在嵌套网格中。

当然,如果 .bottom-left - div 或 .main-container 的第二行 - 网格被赋予固定高度,一切都会完美,但目标是使其可变.

我也尝试将各种 max-heightsheights 添加到其他父 div 中,但到目前为止没有成功。

谢谢!

https://jsfiddle.net/vs6c4gq9/3/

html,
body {
  height: 100%;
  overflow: hidden;
}

#root {
  height: 100%;
}

.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: auto auto;
  grid-template-areas: 'nav nav ' 'aside main';
  height: 100%;
}

.header {
  grid-area: nav;
  background-color: lightblue;
}

.main {
  grid-area: main;
  background-color: lightpink;
  height: 100%;
}

.aside {
  grid-area: aside;
  overflow-y: scroll;
}

.main-container {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: auto auto;
  grid-template-areas: 'topleft topright' 'bottomleft bottomright';
  height: 100%;
  
}

.topleft {
  grid-area: topleft;
}

.topright {
  grid-area: topright;
}

.bottomleft {
  grid-area: bottomleft;
  overflow-y: scroll;
  height: 100%;
}

.bottomright {
  grid-area: bottomright;
}
<div id="root">
  <div class="container">
    <div class="header">
      header
    </div>
    <div class="main">
      <div class="main-container">
        <div class="topleft">
          topleft
        </div>
        <div class="topright">
          topright
        </div>
        <div class="bottomleft">
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>

          <div>last</div>

        </div>
        <div class="bottomright">
          bottomright
        </div>
      </div>
    </div>
    <div class="aside">
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>last</div>
    </div>
  </div>
</div>

从某种意义上说,滚动功能似乎没有任何理由适用于一个元素 (.aside),但不适用于另一个元素 (.bottomleft),这是正确的。似乎没有任何 material 差异。一个元素是嵌套的网格容器。不过应该没关系。

但是,如果您放眼大局,两个滚动条都不应该工作

overflow属性一般需要固定长度才能产生滚动条。如果没有这样的限制,元素只会扩展以容纳内容,并且不可能发生溢出。

您的代码就是这种情况:两个溢出元素都设置为 height: auto

.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: auto auto; <-- second row (where 'aside' is placed) is
                                     set to content-based height
  grid-template-areas: 'nav nav ' 'aside main';
  height: 100%;
}

.main-container {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: auto auto; <-- second row (where 'bottomright' is placed) is
                                     also set to content-based height
  grid-template-areas: 'topleft topright' 'bottomleft bottomright';
  height: 100%;
}

现参照此规则,如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.

因此,您代码中的滚动功能在这两种情况下都应该失败。一个在至少一个浏览器中工作的事实表明异常或 intervention。无论哪种情况,我都认为它是不可靠的。

考虑 trade-off:牺牲 return 中的一些灵活性以获得更高的稳定性和安全性。这是您的代码的修改版本:

revised fiddle

.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: 25px calc(100vh - 25px); /* adjustment */
  grid-template-areas: 'nav nav ' 'aside main';
  height: 100vh;
}

.header {
  grid-area: nav;
  background-color: lightblue;
}

.main {
  grid-area: main;
  background-color: lightpink;
}

.aside {
  grid-area: aside;
  overflow-y: scroll;
}

.main-container {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: 25px calc(100vh - 50px);  /* adjustment */
  grid-template-areas: 'topleft topright' 'bottomleft bottomright';
}

.topleft {
  grid-area: topleft;
}

.topright {
  grid-area: topright;
}

.bottomleft {
  grid-area: bottomleft;
  overflow-y: scroll;
}

.bottomright {
  grid-area: bottomright;
}

body {
  margin: 0; /* remove default margins */
}
<div id="root">
  <div class="container">
    <div class="header">
      header
    </div>
    <div class="main">
      <div class="main-container">
        <div class="topleft">
          topleft
        </div>
        <div class="topright">
          topright
        </div>
        <div class="bottomleft">
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>
          <div>bottomleft</div>

          <div>last</div>

        </div>
        <div class="bottomright">
          bottomright
        </div>
      </div>
    </div>
    <div class="aside">
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>aside</div>
      <div>last</div>
    </div>
  </div>
</div>