如何在 flex 布局滚动中制作 table?

How to make a table in a flex layout scrolling?

我尝试了很多不同的方法来实现 table body 滚动,同时有一个固定的 table header - none 有效真的很令人满意,所以最后我最终为 header 使用了一个 table,为 body 使用了第二个 table,它被放置在一个滚动容器中。这有效,只要我给包含 table body 的可滚动容器一个固定的高度。

现在我想要一个灵活的高度,所以我正在尝试使用 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. 紫罗兰容器应仅适合可用的 space,但不能溢出!
  2. 同黄绿色容器
  3. cadet blue 容器包含 table 并且应该滚动,因为 table 会溢出 - 但它不会滚动

还有一些我真的不知道的东西like/understand:

最后对我来说最重要的是:如何避免绿松石容器滚动而强制学员蓝色容器滚动溢出内容?

编辑:感谢 "David says reinstate Monica" 重新格式化 HTML & CSS :) 感谢 G-Cyrillus 我能够只需将 min-height:0px; 添加到 flexGrow CSS class 即可得到我想要的。当然,我会过度使用固定的 table header 解决方案来变得粘稠...

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

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 安全值。

此外,您可以尝试 position:sticky;,而不是将 table 分成 2 个表,打破 table-layouttheadtbody 结合在一起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>