允许一个网格项目滚动固定 header 和侧边栏

Allow one grid item to scroll with fixed header and sidebar

我有一个两列两行的网格布局。一个粘性左侧导航,一个粘性 header,以及将位于网格右下角的内容。

我现在所拥有的差不多了,但是我希望 .content div 在内容超出屏幕时使用滚动。我以为我可以只使用 overflow: auto,但那行不通。我所拥有的是关闭的吗?

body {
  margin: 0;
  overflow: hidden;
}

.page {
  display: grid;
  grid-template-rows: 55px auto;
  grid-template-columns: 20vh auto;
  grid-template-areas: "nav header" "nav content";
}

.nav {
  grid-area: nav;
  background-color: blue;
}

.header {
  grid-area: header;
  background-color: grey;
}

.content {
  grid-area: content;
  height: 1000px; // This is dynamic
  background-color: red;
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
  <div>

JS fiddle

我已经包含了更改日志以查看需要更改代码的位置以便理解。下面还提供了完整的代码片段。希望这就是你所期待的。

更改日志

*删除body { overflow: hidden; }

*更改.page { grid-template-columns: 3.5rem auto; }

*已添加

.nav { position: fixed;
      top: 0;
      bottom:0;}

*已添加

.header {  position: fixed;
      margin-left: 3.5rem;
      width: 100%;
      height: 3.5rem; }

完整代码

body {
  margin: 0;
}

.page {
  display: grid;
  grid-template-rows: 55px auto;
  grid-template-columns: 3.5rem auto;
  grid-template-areas:
    "nav header"
    "nav content";
}

.nav {
  position: fixed;
  top: 0;
  bottom:0;
  grid-area: nav;
  background-color: blue;

}

.header {
  grid-area: header;
  background-color: grey;
  position: fixed;
  margin-left: 3.5rem;
  width: 100%;
  height: 3.5rem;
}

.content {
  grid-area: content;
  height: 1000px;
  background-color: red;
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
<div>

浏览器支持不是 100%,但实际使用粘性而不是固定定位呢? (现已在 Chrome 中测试)您无需处理硬编码边距。

您仍然需要处理的问题之一是,当侧边栏 (.nav > div) 中的内容高于您的视口时该怎么办。

body {
  margin: 0;
}

.page {
  display: grid;
  grid-template-rows: 55px auto;
  grid-template-columns: 3.5rem auto;
  grid-template-areas: "nav header" "nav content";
}

.nav {
  grid-area: nav;
  background-color: blue;
}

.nav > div {
  position: sticky;
  top: 0;
}

.header {
  grid-area: header;
  background-color: grey;
  position: sticky;
  top: 0;
  min-height: 3.5rem;
}

.content {
  grid-area: content;
  min-height: 1000px;
  background-color: red;
}
<div class="page">
  <div class="nav">
    <div>Side nav</div>
  </div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
<div>

要使 overflow: auto 正常工作(即要呈现滚动条),浏览器需要一个触发器。此触发器通常是强制溢出条件的高度/宽度限制,从而启动滚动条。

触发条件因浏览器而异。它们还因 CSS 技术而异,例如 flex、网格和块布局。

在这种特殊情况下,有几个逻辑位置可以建立溢出条件,但其中 none 有效。

  1. 您可以像您尝试的那样定位网格项目:

    .content {
       height: 1000px
       overflow: auto;
    }
    

    但是没用。流体项目上没有滚动条。

body {
  margin: 0;
  /* overflow: hidden; */
}

.page {
  display: grid;
  grid-template-rows: 55px auto;
  grid-template-columns: 20vh auto;
  grid-template-areas: "nav header" 
                       "nav content";
}

.nav {
  grid-area: nav;
  background-color: aqua;
}

.header {
  grid-area: header;
  background-color: lightgrey;
}

.content {
  grid-area: content;
  height: 1000px;
  overflow: auto;
  background-color: red;
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
  <div>

  1. 正如我测试的那样,您可以定位行本身:

    .page {
       display: grid;
       grid-template-rows: 55px 1000px;
    }
    
    .content {
       overflow: auto;
    }
    

    但这也不管用。流体项目上仍然没有滚动条。

body {
  margin: 0;
  /* overflow: hidden; */
}

.page {
  display: grid;
  grid-template-rows: 55px 1000px;
  grid-template-columns: 20vh auto;
  grid-template-areas:
    "nav header"
    "nav content";
}

.nav {
  grid-area: nav;
  background-color: aqua;
}

.header {
  grid-area: header;
  background-color: lightgrey;
}

.content {
  overflow: auto;
  grid-area: content;
  background-color: red;
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <h1>title</h1>
  </div>
  <div>

  1. 所以我定位了一个child的grid item。叮叮叮!成功了。

    无需固定定位。无需粘性定位。这适用于所有支持网格布局的浏览器。

body {
  margin: 0;
}

.page {
  display: grid;
  grid-template-rows: 55px calc(100vh - 55px);  /* height limitation on second row */
  grid-template-columns: 20vh auto;
  grid-template-areas: "nav header" 
                       "nav content";
}

.nav {
  grid-area: nav;
  background-color: aqua;
}

.header {
  grid-area: header;
  background-color: lightgrey;
}

.content {
  grid-area: content;
  background-color: red;
  overflow: auto;                          /* overflow condition on parent */
}

article {
  height: 1000px;                          /* height set on child; triggers scroll */
}
<div class="page">
  <div class="nav">Side nav</div>
  <div class="header">Header</div>
  <div class="content">
    <article><!-- new section for content -->
      <h1>title</h1>
    </article>
  </div>
  <div>

jsFiddle demo