如何实现只有tbody滚动的高度100%表格

23

是否可以使用CSS滚动100%高度的表格内容而不是标题,并仅在tbody内容侧面显示滚动条而不是标题行?谢谢!


你可以做到,但需要使用固定宽度列。Sgs3为此提供了两种解决方案。否则,你将需要使用JavaScript/jQuery。 - Jeremy A. West
相关链接:https://dev59.com/G4_ea4cB1Zd3GeqPVv97 - AlikElzin-kilaka
9个回答

7

我希望现在不会太晚,而且您还活着。自那时以来情况已经改善了很多 :)

您可以使用:

table {
  display: inline-grid;
  grid-template-areas: 
  "head-fixed" 
  "body-scrollable";
}

thead {
  grid-area: head-fixed;
}

tbody {
  grid-area: body-scrollable;
  overflow: auto;
  height: calc(100vh - 55px);
}

在JSFiddle上具有100%高度和固定标题的可滚动表格(tbody): http://jsfiddle.net/gengns/p3fzdc5f/


这似乎是一个相当优雅的解决方案。然而,thead列的宽度与相应的td元素的宽度不匹配。我需要对这些元素应用固定宽度来解决这个问题吗? - dabs
1
@dabs 谢谢你的赞美(简洁和可靠性)。是的,滚动 tbody 的方式很酷。说到 width,你需要修复一个最小值 th:first-of-type, td:first-of-type { min-width: 50px; }。但是,你可以使用 CSS Grid 并使用不同的 grid-template-areas 来使 thtd 占用相同的空间:)也许在这种情况下,你更喜欢避免使用 table。希望这能帮助到你。 - gengns

6
表格是比较棘手的问题。我猜你想用它们来进行语义和回退,但它们有些不灵活。
幸运的是,有些人在大约2005年就已经找到了不止一种实现可滚动效果的好方法。

http://www.cssplay.co.uk/menu/tablescroll.html

他们仍然需要额外的HTML标记来实现,第二个表格有效地使用了嵌套表格,但回退/普通HTML看起来像一个普通的平面表格。
方法#1
外部带有填充的div,用于创建元素的“字段”。内部div使内部表格可滚动。 thead表行绝对定位以使其保持在body上方,页脚也是如此。因为内部div是overflow:auto并且定义了高度,所以其余的表行会在可滚动区域内排成一行。
方法#2
外部表格是普通表格,标题和页脚通常被设计。但是,外部表格的tbody仅包含一行,一列,并在其中包含另一个表格。该列具有定义的高度和overflow:auto,因此其中的表(仅具有内容)将在其中滚动。

3
在这两种情况下,单个列的尺寸都是手动设置的。目前还没有看到一种方法可以做到这一点,并且仍然让浏览器自动布局表格。 - Michael Slade
@MichaelSlade 这是为了使标题与其相应的列正确对齐...不幸的是,也许出乎意料的是,HTML表格并没有考虑到这些机制。我想,最终如果你想在HTML中使用更动态的布局系统并使用表格结构,你将不得不使用一些JS来同步标题/列。我认为设置宽度是一个小代价。 - sg3s
仅需指出方法#2的另一件事,可能很明显,但您还需要将外部/第一个表格的唯一行的colspan添加到第二个表格的列数以匹配。 - Wak

3
一个JavaScript的解决方案是使用“浮动表头”。将整个表格放在一个设置了overflow属性的div中,然后JavaScript会克隆表格标题并将其放置在div的顶部,有点类似于苹果的界面。
一个jQuery示例可以参考http://fixedheadertable.com/ 请注意,如果您对表格进行其他操作,如客户端排序、过滤等,则这变得非常复杂。

1
该链接显示“抱歉,您在此博客中查找的页面不存在”。 - Shadow The Spring Wizard
1
我已将链接从http://slackers.se/2009/jquery-floating-header-plugin更改为等效插件http://fixedheadertable.com/。@Shadow Wizard - 感谢您指出这一点。 - GlennG

1
你可以使用flex display来实现,不需要硬编码大小。 这里有一个例子,展示如何在表格中使用固定头和可滚动内容。代码:
<html style="height: 100%">
  <head>
    <meta charset=utf-8 />
    <title>Fixed Header in table</title>
    <!-- Reset browser defaults -->
    <link rel="stylesheet" href="reset.css">
  </head>
  <body style="height: 100%">
  <table style="display: flex; height: 100%; flex-direction: column">
    <thead>
      <tr>
        <td>HEADER<br/>------------</td>
      </tr>
    </thead>
    <tbody style="flex: 1; overflow: auto">
        <tr>
          <td>
          <div>
              CONTENT - START<br/>
              <script>
              for (var i=0 ; i<1000 ; ++i) {
                document.write(" Very long content!");
              }
              </script>
              <br/>CONTENT - END
          </div>
        </td>
      </tr>
    </tbody>
  </table>
  </body>
</html>

如果需要完整的圣杯布局实现(包括头部、尾部、导航、侧边栏和内容),使用flex布局,请前往这里


@cryophoenix - 你为什么这么说?这是一个带有滚动条的屏幕截图:https://imgur.com/a/06pYIfl - AlikElzin-kilaka
@cryophoenix - 也许你的意思是它不能水平滚动? - AlikElzin-kilaka
可能我搞砸了什么。 - cryophoenix

1
据我所知,使用纯CSS是不可能实现的(至少不跨浏览器),但是使用jQuery插件可以实现,并且非常简单,例如jQuery.FixedTable

dotnetoutsource.com的链接已经失效。 - Rob Dawson
@Rob 谢谢你提醒,很多插件都会很快失效...我在其他地方找到了我想要的插件。 - Shadow The Spring Wizard

0

这很简单。以下是您想要做的事情:

CSS:

<style>
  article, aside, figure, footer, header, hgroup,
  menu, nav, section { display: block; }

  html, body{ width: 100%; height: 100%;}
  table{
    width: 100%;
    height: 100%;
    background-color: #aaa;
  }

  tbody{
    width: 100%;
    height: 100%;
    -display: block;
    background-color: #ccc;
    overflow-y: scroll;
    overflow-x: hidden;

  }

  td{
    width: 100px;
    height: 200px;
    background-color: #eee;
  }


</style>

HTML:

<table>

  <thead>
    <tr>
      <th>Month</th>
      <th>Savings</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>January</td>
      <td>$100</td>
    </tr>
    <tr>
      <td>February</td>
      <td>$80</td>
    </tr>
     <tr>
      <td>January</td>
      <td>$100</td>
    </tr>
    <tr>
      <td>February</td>
      <td>$80</td>
    </tr>
  </tbody>

</table>

顺便说一句,如果你想快速检查这段代码,可以使用jsbin.com。 - Joshua Robison

-1
如果在您的情况下可能的话,一个简单直接的替代方案是将标题放在一个单独的 div 中,将表格放在另一个具有适当高度的 div 中,并对该 div 应用以下属性。
overflow-x: hidden;
overflow-y: scroll;

我已经研究了这个问题,但是如何让容器div作为100%、头部div作为固定高度以及第二个内部div作为流体高度来填充剩余空间呢?谢谢。 - Matt
你不能为容器div设置固定高度吗? - Dienekes
不行,因为它是一个流体高度设计,要看起来像本地程序,我可以让它在固定高度下工作,但必须是流体的! - Matt

-1

我有一个类似的问题,只想让标题下的内容滚动并保留100%的剩余高度。以下是我的解决方法:

http://jsfiddle.net/ajkochanowicz/YDjsE/

这对于简单的用例可行。

#container {
  border: 1px solid red;
  width: 200px;
  height: 250px; /* This can be any height and everything fills in */
  padding-top: 55px;            
}
#something-else {
  height: 55px;
  width: 200px;
  background-color: green;
  margin-top:-55px;    
}
#overflow {
  border: 1px solid blue;
  width:198px;
  overflow-y: auto; 
  height: 100%;   
}

1
无法处理表格数据,因为标题列无法与正文列保持对齐。 - frenchmd
你能详细说明一下你的使用情况吗,@AlikElzin-kilaka? - Adam Grant
@AdamGrant,我希望内容能够到达页面底部。这就是100%的原因。 - AlikElzin-kilaka

-2
尝试使用这个CSS文件:
table{
    width: 100%;
    height: 400px;
    background-color: #aaa;
  }

  tbody{
     background-color: #CCCCCC;
    display: block;
    height: 400px;
    overflow-x: hidden;
    overflow-y: scroll;
    width: 100%;
  }

  td{
    width: 100px;
    height: 30px;
    background-color: #eee;
  }

thead {
    display: block;
    height: 30px;
    width: 100%;
}

在我的火狐浏览器上可以运行,其他地方没有测试过.. :)


这在Firefox中不起作用。对于标题比内容更长的情况,它会使标题栏的宽度小于内容的宽度。 - frenchmd
1
更改表格元素的显示属性会破坏表格结构的主要目的,我完全不建议采用这种方法。 - Wak
1
这是一个固定高度,不是100%。 - fmsf
如果你不考虑旧版浏览器,可以选择“vh”基础。 - Kamal

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