【问题标题】:How to make a table in a flex layout scrolling?如何在 flex 布局中滚动表格?
【发布时间】:2020-06-19 22:50:47
【问题描述】:

我尝试了许多不同的方法来使表格主体滚动,同时具有固定的表格标题 - 它们都没有真正令人满意,所以最后我最终使用了一个表格作为标题,并使用了第二个表格作为正文,即放置在滚动容器中。只要我给包含表格主体的可滚动容器一个固定的高度,这就行了。

现在我想要一个灵活的高度,所以我正在尝试使用 flex:

/* SOME BASE CSS SETTINGS */

* {
  box-sizing: border-box;
}

body,
html {
  color: white;
  width: 100%;
  height: 100%;
  padding: 0px;
  margin: 0px;
}


/* A FLEX COLUMN CONTAINER */

.flexContainer {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}


/* FLEX ELEMENT THAT SHOULD GROW TO FIT THE AVAILABLE SPACE */

.flexGrow {
  flex-grow: 1;
}


/* SECTION ONE IS HIDDEN, BUT EXISTS IN REAL LIFE */

#S1 {
  display: none;
  visibility: hidden;
}

#S1>header {
  background-color: red;
  min-height: 450px;
}

#S1>main {
  background-color: green;
  overflow: auto;
  min-height: calc(100% - 550px);
  max-height: calc(100% - 550px);
}

#S1>footer {
  background-color: blue;
  min-height: 100px;
}


/* SECTION 2 IS VISIBLE */

#S2>header {
  background-color: red;
  min-height: 150px;
}

#S2>main {
  background-color: green;
  /* If I remove this, MAIN won't be displayed beside NAV */
  display: inline-block;
  /* If I remove this, the document body will scroll :( */
  min-height: calc(100% - 250px);
  max-height: calc(100% - 250px);
}

#S2>main>div {
  flex-direction: row;
}

#S2>main>div>nav {
  background-color: black;
  min-width: 450px;
}

#S2>main>div>section {
  background-color: teal;
  width: 100%;
  height: 100%;
  /* If I remove this, the body will scroll the big table of sub section 1! */
  overflow: auto;
}

#S2>footer {
  background-color: blue;
  min-height: 100px;
}


/* SUB SECTION 1 IS VISIBLE */

#SS1 {
  border: 5px solid green;
}

#SS1>div {
  background-color: turquoise;
  border: 5px solid turquoise;
}

#SS1>div>.table {
  /* Why does this overflow!? It should only fill the available space. */
  background-color: violet;
  border: 5px solid violet;
  width: 100%;
}

#SS1>div>.table>.container {
  background-color: wheat;
  border: 5px solid wheat;
}

#SS1>div>.table>.container>.header {
  background-color: silver;
  border: 5px solid silver;
  width: 100%;
  height: 40px;
}

#SS1>div>.table>.container>.data {
  background-color: yellowgreen;
  border: 5px solid yellowgreen;
  width: 100%;
}

#SS1>div>.table>.container>.data>.container {
  background-color: cadetblue;
  border: 5px solid cadetblue;
  width: 100%;
  height: 100%;
  /* This scrolling should be applied to have a fixed header and a scrolling body - but instead the sub section is scrolling :S */
  overflow-y: auto;
}

#SS1>div>.table>.container>.data>.container>.body {
  background-color: brown;
  border: 5px solid brown;
  width: 100%;
}

#SS1>div>.table>.container>.data>.container>.body tr {
  height: 200px;
  /* Ensure the table data will overflow */
}

#SS1>div>.table td {
  width: 150px;
}

#SS1>div>.table td:nth-child(2) {
  width: auto;
}


/* SUB SECTION 2 IS HIDDEN, BUT EXISTS IN REAL LIFE */

#SS2 {
  display: none;
  visibility: hidden;
}
<!DOCTYPE html>

<body>
  <section id="S1" class="flexContainer">
    <header>S1 HEADER</header>
    <main class="flexGrow">S1 MAIN</main>
    <footer>S1 FOOTER</footer>
  </section>
  <section id="S2" class="flexContainer">
    <header>S2 HEADER</header>
    <main class="flexGrow">
      <div class="flexContainer">
        <nav>S2 NAV</nav>
        <section id="SS1" class="flexGrow">
          <div class="flexContainer">
            <h1>S2 SECTION 2</h1>
            <div class="table flexGrow">
              <div class="container flexContainer">
                <table class="header">
                  <thead>
                    <tr>
                      <td>Column 1</td>
                      <td>Column 2</td>
                      <td>Column 3</td>
                      <td>Column 4</td>
                      <td>Column 5</td>
                    </tr>
                  </thead>
                </table>
                <div class="data flexGrow">
                  <div class="container">
                    <table class="body">
                      <tbody>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                      </tbody>
                    </table>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </section>
        <section id="SS2">S2 SECTION 2</section>
      </div>
    </main>
    <footer>S2 FOOTER</footer>
  </section>
</body>

但是结果有几个问题:

  1. 紫色容器应该只适合可用空间,但不能溢出!
  2. 黄绿色容器也一样
  3. cadet blue 容器包含表格并且应该滚动,因为表格确实溢出 - 但它不会滚动

还有一些我不太喜欢/不理解的东西:

  • 为什么#S2&gt;maininline-block要显示在#S2&gt;nav旁边?
  • 为什么我必须给#S2&gt;main 一个高度?我假设高度适合可用高度,但如果我不给出高度,文档将滚动

最后对我来说最重要的是:如何避免turquoise容器的滚动,强制cadet blue容器滚动溢出的内容?

编辑:感谢“David says reinstate Monica”重新格式化 HTML 和 CSS :) 感谢 G-Cyrillus,我只需将 min-height:0px; 添加到 @987654328 即可获得我想要的东西@CSS 类。当然,我会过度使用我的固定表头解决方案以变得粘稠......

【问题讨论】:

    标签: html css scroll flexbox overflow


    【解决方案1】:

    您可以使用较少的覆盖并从模板和一些可重复使用的class(更容易添加 /remove 以测试最小规则)开始,然后填充模板。

    body {margin:0}
    .vh-100 {height:100vh}
    .flex {display:flex;}
    .flex-grow-1 {flex-grow:1;}
    .column {flex-flow:column;}
    .min-height-0 {min-height:0}
    .overflow-A{overflow:auto; }
    #test:hover {height:100vh;}
    
    section {background:tomato}
    header {background:gold}
    aside {background:lightblue;}
    footer {background:orange}
    #test {background:lightgreen}
    section section, header,aside,footer ,#test{padding:0.25em;}
    <section class="vh-100 flex column">
      <header>Section HEADER</header>
      <main class="flex-grow-1 flex min-height-0">
        <aside>
          <nav>Section NAV</nav>
        </aside>
        <section class="flex column flex-grow-1">
          <h1 >main header</h1>
          <div class="overflow-A flex-grow-1"> content to scroll if  needed
          <div id="test">test div to hover</div>
          </div>
        </section>
      </main>
      <footer>Section FOOTER</footer>
    </section>

    一旦你有了一个高效的布局和滚动元素,你就可以把它填满,也许可以考虑一个min-height 安全值。

    另外,将table 分成两个表,将table-layout 组合在一起theadtbody,您可以尝试position:sticky; for thead

    例子

    body {margin:0}
    .vh-100 {height:100vh}
    .w-100 {width:100%;}
    .minH-300 {min-height:300px;}/* make sure content don't get over squizzed */
    .flex {display:flex;}
    .flex-grow-1 {flex-grow:1;}
    .column {flex-flow:column;}
    .min-height-0 {min-height:0}
    .overflow-A{overflow:auto; }
    #test:hover {height:100vh;}
    
    section {background:tomato}
    header {background:gold}
    aside {background:lightblue;}
    footer {background:orange}
    table,td {border:solid;}
    
    .sticky-top {position:sticky;top:0;background:white}
    
    
    section section, header,aside,footer{padding:0.25em;}
    <section class="vh-100 flex column minH-300">
      <header>Section HEADER</header>
      <main class="flex-grow-1 flex min-height-0">
        <aside>
          <nav>Section NAV</nav>
        </aside>
        <section class="flex column flex-grow-1">
          <h1 >main header</h1>
          <div class="overflow-A flex-grow-1">
          
          <table class="header w-100">
            <thead class="sticky-top w-100">
              <tr>
                <td>Column 1</td>
                <td>Column 2</td>
                <td>Column 3</td>
                <td>Column 4</td>
                <td>Column 5</td>
              </tr>
            </thead>
    
            <tbody>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
              <tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
                <td>Cell 3</td>
                <td>Cell 4</td>
                <td>Cell 5</td>
              </tr>
            </tbody>
          </table>
          </div>
          <p>a paraph standing below scrolling div</p>
        </section>
      </main>
      <footer>Section FOOTER</footer>
    </section>

    【讨论】:

    • 第一:非常感谢!好消息:花了一些时间,但我终于明白了我的诀窍:height:100vhmin-height:0。坏消息:我仍然不明白为什么 :(min-height:0 对我来说毫无意义。对我来说,让烦人的结果变成令人满意的结果就像是一种黑客行为 - 但我觉得它不是应该的那样. min-height:0 的技术原因是什么 - 是否有任何参考资料可以解释这一点?
    • @nd_ min-height 或 overflow:hidden,让浏览器计算 flex 父级的高度,否则它不会节省一些内存 :( 让我搜索一个重复的
    • @nd_ 这里是一些解释stackoverflow.com/questions/36247140/…
    • 再次感谢!现在我明白了:) 顺便说一句。粘性标题适用于th,但不适用于thead - 但为此它就像魅力一样!所以我可以使用具有固定标题的单个表。到目前为止我尝试过的解决方案的问题是,当我使 tbody 可滚动时,一旦在 tbody 中显示滚动条,单元格宽度将不再与标题列宽度匹配。但是当我“坚持”粘性解决方案时,滚动条将出现在表格容器上,而不是表格主体上 - 所以它不会破坏布局。
    猜你喜欢
    • 2020-09-14
    • 2017-08-14
    • 1970-01-01
    • 2011-06-15
    • 2013-05-13
    • 1970-01-01
    • 2018-09-15
    • 2019-06-16
    • 2011-11-22
    相关资源
    最近更新 更多