使用CSS实现带有可滚动表格主体的100%高度布局

3

我有一个100%高度的布局,分成三个部分:头部、内容、底部。

我想在内容区域内显示一个具有100%高度的表格,并希望表格主体具有垂直滚动条以便查看表格内容。

怎么做呢?

似乎我不能将tbody的高度设置为100%并且拥有一个滚动条?

html, body {
     height: 100%;
     padding: 0;
     margin: 0;
}
 #container {
     display: table;
     width: 100%;
     height: 100%;
     border: 1px solid red;
     text-align: center;
}
 #container > div {
     display: table-row;
     width: 100%;
}
 #container > div > div {
     display: table-cell;
     width: 100%;
     border-radius:10px;
}
 #header > div {
     height:50px;
     border:solid 2px #aaa;
}
 #content > div {
     height: 100%;
     background:#f0f4f0;
     border:solid 2px #5a5;
}
 #footer > div {
     height:50px;
     border:solid 2px #a55;
}
 table {
     table-layout:fixed;
     margin:auto;
}
 th, td {
     padding:5px 10px;
     border:1px solid #000;
}
 thead, tfoot {
     background:#f9f9f9;
     display:table;
     width:100%;
     width:calc(100% - 18px);
}
 tbody {
     height:400px;
     overflow:auto;
     overflow-x:hidden;
     display:block;
     width:100%;
}
 tbody tr {
     display:table;
     width:100%;
     table-layout:fixed;
}
 
<div id="container">
    <div id="header">
        <div>header</div>
    </div>
    <div id="content">
        <div>
            <table>
                <thead>
                    <tr>
                        <th scope="col">Header 1</th>
                        <th scope="col">Header 2</th>
                        <th scope="col">Header 3</th>
                        <th scope="col">Header 4</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Cell2 content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                    <tr>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                        <td>Cell content</td>
                    </tr>
                </tbody>
                <tfoot>
                    <tr>
                        <td>Footer 1</td>
                        <td>Footer 2</td>
                        <td>Footer 3</td>
                        <td>Footer 4</td>
                    </tr>
                </tfoot>
            </table>
        </div>
    </div>
    <div id="footer">
        <div>footer</div>
    </div>
</div>


1
尝试一下这个 https://codepen.io/daveoncode/pen/LNomBE - Viira
我想在内容区域内显示一个高度为100%的表格,那么为什么你要将其高度应用为400像素而不是只使用100%呢? - Rainbow
如果我应用了100%,滚动条就无法工作。 - nullException
@nullException 你是否愿意使用flex-box解决方案? - Danny
2个回答

1
我必须使用JavaScript来完成这个任务,但也许有人能想出一个纯CSS的解决方案。
页面的主要部分
我正在使用flexbox来定位页面的头部(header),主体(main)和页脚(footer)部分,使主体(main)可以占据尽可能多的垂直空间。
body {
  display: flex;
  flex-direction: column;
}

main {
  flex: 1;
}

表格

我将 table 设置为在 main 区域中占据 100% 的高度和宽度,并将每个 tr 元素设置为显示 flex,以便它们的所有直接子元素可以平均分配空间:

table {
  width: 100%;
  height: 100%;
}

tr {
  display: flex;
}
tr > * {
  flex: 1;
}

我已将 tbody 元素设置为 display: block,这将允许内容在溢出时可滚动:
tbody {
  display: block;
  overflow-y: scroll;
}
tbody tr {
  height: 40vh; // for demonstrating the scrolling of the tbody
}

我随后使用一些 JavaScript 代码来设置 tbody 元素的高度,请在下面的注释中查找文档:

setTbodyHeight();
window.addEventListener("resize", setTbodyHeight);

function setTbodyHeight() {
  // get the viewport height
  let viewportHeight = window.innerHeight;

  // calculate how much of the height the main should consume
  let headerHeight = getHeight("header");
  let footerHeight = getHeight("footer");

  let mainHeight = viewportHeight - (headerHeight + footerHeight);

  // from the main height calcuate how much space would be available if you subtracted the tfoot/thead height
  let theadHeight = getHeight("thead");
  let tfootHeight = getHeight("tfoot");

  let tbodyHeight = mainHeight - (theadHeight + tfootHeight);

  // set the height of the tbody to this value
  let tbody = document.querySelector("tbody");
  tbody.style.height = tbodyHeight + "px";

  function getHeight(elementName) {
    let element = document.querySelector(elementName);
    let elementCSS = window.getComputedStyle(element);

    let height = parseInt(elementCSS.getPropertyValue("height"));

    return height;
  }
}
/* IGNORE RULES FROM HERE.....*/

html,
body {
  height: 100%;
}

body {
  font-family: sans-serif;
  margin: 0;
}

header::after,
footer::after {
  content: "." attr(class);
}

tbody tr:nth-child(even) {
  background: firebrick;
  color: white
}

td {
  text-align: center;
}


/*.....TO HERE*/

body {
  display: flex;
  flex-direction: column;
}

main {
  flex: 1;
}

table {
  width: 100%;
  height: 100%;
}

tr {
  display: flex;
}

tr>* {
  flex: 1;
}

tbody {
  display: block;
  overflow-y: scroll;
}

tbody tr {
  height: 20vh;
}

tbody td {
  line-height: 20vh;
}
<header class="header"></header>
<main class="main">
  <table>
    <thead>
      <tr>
        <th>Heading</th>
        <th>Heading</th>
        <th>Heading</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
      </tr>
      <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
      </tr>
      <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
      </tr>
      <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
      </tr>
      <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
      </tr>
      <tr>
        <td>Data</td>
        <td>Data</td>
        <td>Data</td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td>Footer</td>
        <td>Footer</td>
        <td>Footer</td>
      </tr>
    </tfoot>
  </table>
</main>
<footer class="footer"></footer>


1
您的布局有点混乱。我认为包含太多div。使用flex进行了一些更改-因此表格容器将具有
display: flex;
flex-direction: column;
overflow: auto;

并且这个表格将具有 flex-grow: 1;

html,
body {
  height: 100%;
  padding: 0;
  margin: 0;
}

#container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  border: 1px solid red;
  text-align: center;
}

#container>div {
  width: 100%;
  display: flex;
  flex-direction: column;
}

#container>div>div {
  width: 100%;
  height: 100%;
  border-radius: 10px;
  overflow: auto;
}

#header {
  flex-basis: 50px;
  flex-grow: 0;
  flex-shrink: 0;
}

#header>div {
  height: 50px;
  border: solid 2px #aaa;
}

#content {
  flex-grow: 1;
}

#content>div {
  height: 100%;
  background: #f0f4f0;
  border: solid 2px #5a5;
  display: flex;
  flex-direction: column;
}

#footer{
  flex-basis: 50px;
  flex-grow: 0;
  flex-shrink: 0;
}

#footer>div {
  height: 50px;
  border: solid 2px #a55;
}

table {
  flex-grow: 1;
  table-layout: fixed;
  margin: auto;
}

th,
td {
  padding: 5px 10px;
  border: 1px solid #000;
}

thead,
tfoot {
  background: #f9f9f9;
  display: table;
  width: 100%;
  width: calc(100% - 18px);
}

tbody {
  overflow: auto;
  overflow-x: hidden;
  display: block;
  width: 100%;
}

tbody tr {
  display: table;
  width: 100%;
  table-layout: fixed;
}
<div id="container">
  <div id="header">
    <div>header</div>
  </div>
  <div id="content">
    <div>
      <table>
        <thead>
          <tr>
            <th scope="col">Header 1</th>
            <th scope="col">Header 2</th>
            <th scope="col">Header 3</th>
            <th scope="col">Header 4</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Cell2 content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
          <tr>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
            <td>Cell content</td>
          </tr>
        </tbody>
        <tfoot>
          <tr>
            <td>Footer 1</td>
            <td>Footer 2</td>
            <td>Footer 3</td>
            <td>Footer 4</td>
          </tr>
        </tfoot>
      </table>
    </div>
  </div>
  <div id="footer">
    <div>footer</div>
  </div>
</div>


如果@nullException解决了您的问题,请接受答案,谢谢 :) - Itay Gal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接