提问者:小点点

带有水平滚动条和垂直滚动条的固定标题表


我一直在努力解决HTML/CSS粘滞头+滚动条的问题。我们正在创建一个程序,一旦containersize达到某个点(取决于用户的分辨率),就需要滚动条显示出来。

我在表中的第二列上强制设置一个min-width,因此表在某个点停止递减,并强制容器保持在某个宽度。容器上的溢出显示水平滚动条。一切正常。一旦我为垂直滚动添加了第二个滚动条,事情就会变得一团糟。有人有解决这个问题的办法吗?我想在.table-body上有一个垂直滚动条,但滚动条必须在outercontainer上可见。

固定标题表有没有好的HTML/CSS解决方案?我已经搜索了一个星期,但只能找到jQuery插件的这种行为。

这是我当前的HTML:

<!DOCTYPE html>
<html>
<head>
    <title>fixed header prototyping</title>
    <link rel="stylesheet" href="css/style.css">
</head>

<body>
<div class="outer-container"> <!-- absolute positioned container -->
<div class="inner-container">

    <div class="table-header">
        <table id="headertable" width="100%" cellpadding="0" cellspacing="0">
            <thead>
                <tr>
                    <th class="header-cell col1">One</th>
                    <th class="header-cell col2">Two</th>
                    <th class="header-cell col3">Three</th>
                    <th class="header-cell col4">Four</th>
                    <th class="header-cell col5">Five</th>
                </tr>
            </thead>
        </table>
    </div>

    <div class="table-body">
        <table id="bodytable" width="100%" cellpadding="0" cellspacing="0">
            <tbody>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
</div>



</body>
</html>

而我的CSS看起来是这样的:

body {
    margin:0;
    padding:0;
    height: 100%;
    width: 100%;
}
table {
    border-collapse: collapse; /* make simple 1px lines borders if border defined */
}
tr {
    width: 100%;
}

.outer-container {
    background-color: #ccc;
    position: absolute;
    top:0;
    left: 0;
    right: 300px;
    bottom:40px;
    overflow: hidden;

}
.inner-container {
    width: 100%;
    height: 100%;
    position: relative;
    overflow-x: scroll;
    overflow-y:hidden;
}
.table-header {
    float:left;
    width: 100%;
}
.table-body {
    float:left;
    height: 100%;
    width: inherit;
    overflow-y: scroll;
}
.header-cell {
    background-color: yellow;
    text-align: left;
    height: 40px;
}
.body-cell {
    background-color: blue;
    text-align: left;
}
.col1, .col3, .col4, .col5 {
    width:120px;
    min-width: 120px;
}
.col2 {
    min-width: 300px;
}

JSFiddle示例-http://jsfidle.net/w8urm/

提前谢谢伙计们!


共2个答案

匿名用户

这不是一件容易的事。我想出了一个脚本解决方案。(我不认为这是使用纯CSS可以做到的)

HTML与您发布的内容保持不变,CSS略有变化,添加了JQuery代码。

在IE10,IE9,IE8,FF,Chrome上测试的工作小提琴

顺便说一句:如果你有独特的元素,为什么不用ID而不是类呢?我认为它给出了更好的选择器性能。

工作原理说明:inner-container将跨越outer-container的整个空间(所以基本上不需要他),但我把他留在了那里,所以您不需要更改DOM。

table-header相对定位,没有滚动(overflow:hiddit),我们稍后会处理他的滚动。

table-body必须跨越inner-container的其余高度,所以我使用了一个脚本来确定要固定他的高度。(当你重新调整窗口大小时,它会动态变化)如果没有固定的高度,滚动将不会出现,因为div将会变大。注意,这部分可以在没有脚本的情况下完成,如果您固定头高度并使用CSS3(如答案末尾所示)

现在只需要每次滚动时将头部与正文一起移动。这是由分配给scroll事件的函数完成的。

CSS(其中一些是从您的样式中复制的)

*
{
    padding: 0;
    margin: 0;
}

body
{
    height: 100%;
    width: 100%;
}
table
{
    border-collapse: collapse; /* make simple 1px lines borders if border defined */
}
.outer-container
{
    background-color: #ccc;
    position: absolute;
    top:0;
    left: 0;
    right: 300px;
    bottom: 40px;
}

.inner-container
{
    height: 100%;
    overflow: hidden;
}

.table-header
{
    position: relative;
}
.table-body
{
    overflow: auto;
}

.header-cell
{
    background-color: yellow;
    text-align: left;
    height: 40px;
}
.body-cell 
{
    background-color: blue;
    text-align: left;
}
.col1, .col3, .col4, .col5
{
    width:120px;
    min-width: 120px;
}
.col2
{
    min-width: 300px;
}

jQuery

$(document).ready(function () {
    setTableBody();
    $(window).resize(setTableBody);
    $(".table-body").scroll(function ()
    {
        $(".table-header").offset({ left: -1*this.scrollLeft });
    });
});

function setTableBody()
{
    $(".table-body").height($(".inner-container").height() - $(".table-header").height());
}

如果您不关心固定头高度(我看到您在CSS中固定了单元格的高度),那么如果您使用CSS3:shorter Fiddle(这在IE8上行不通),可以跳过部分脚本

匿名用户

这里有一个解决方案,它也不是CSS唯一的解决方案。它与Avrahamcool的解决方案类似,因为它使用了几行jQuery,但它所做的只是根据其父tbody向右滚动的距离来更改tbody的宽度,而不是更改高度和移动标题。

这个解决方案的另一个好处是它可以使用语义上有效的HTML表。

它在所有最近的浏览器版本(IE10,Chrome和FF)上都很好用,就是这样,滚动功能在旧版本上被打破了。

但是如果您使用的是语义上有效的HTML表,就可以挽救局面,确保表仍然正确显示,只有滚动功能不能在较旧的浏览器上工作。

这里有一个jsfiddle用于演示。

CSS

table {
    width: 300px;
    overflow-x: scroll;
    display: block;
}
thead, tbody {
    display: block;
}
tbody {
    overflow-y: scroll;
    overflow-x: hidden;
    height: 140px;
}
td, th {
    min-width: 100px;
}

JS

$("table").on("scroll", function () {
    $("table > *").width($("table").width() + $("table").scrollLeft());
});

我需要一个版本,它在IE9中很好地降级(没有滚动,只是一个正常的表)。在这里张贴小提琴,因为它是一个改进的版本。您需要做的只是在tr上设置一个高度。

额外的CSS使该解决方案在IE9中良好地降级

tr {
    height: 25px; /* This could be any value, it just needs to be set. */ 
}

下面的jsfiddle演示了该解决方案在IE9版本中的良好降级。

编辑:更新的小提琴链接,以链接到一个版本的小提琴,其中包含修正的问题,在评论中提到。我只是添加了一个最新和最好版本的片段:

null

$('table').on('scroll', function() {
  $("table > *").width($("table").width() + $("table").scrollLeft());
});
html {
  font-family: verdana;
  font-size: 10pt;
  line-height: 25px;
}

table {
  border-collapse: collapse;
  width: 300px;
  overflow-x: scroll;
  display: block;
}

thead {
  background-color: #EFEFEF;
}

thead,
tbody {
  display: block;
}

tbody {
  overflow-y: scroll;
  overflow-x: hidden;
  height: 140px;
}

td,
th {
  min-width: 100px;
  height: 25px;
  border: dashed 1px lightblue;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
      <th>Column 3</th>
      <th>Column 4</th>
      <th>Column 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>AAAAAAAAAAAAAAAAAAAAAAAAAA</td>
      <td>Row 1</td>
      <td>Row 1</td>
      <td>Row 1</td>
      <td>Row 1</td>
    </tr>
    <tr>
      <td>Row 2</td>
      <td>Row 2</td>
      <td>Row 2</td>
      <td>Row 2</td>
      <td>Row 2</td>
    </tr>
    <tr>
      <td>Row 3</td>
      <td>Row 3</td>
      <td>Row 3</td>
      <td>Row 3</td>
      <td>Row 3</td>
    </tr>
    <tr>
      <td>Row 4</td>
      <td>Row 4</td>
      <td>Row 4</td>
      <td>Row 4</td>
      <td>Row 4</td>
    </tr>
    <tr>
      <td>Row 5</td>
      <td>Row 5</td>
      <td>Row 5</td>
      <td>Row 5</td>
      <td>Row 5</td>
    </tr>
    <tr>
      <td>Row 6</td>
      <td>Row 6</td>
      <td>Row 6</td>
      <td>Row 6</td>
      <td>Row 6</td>
    </tr>
    <tr>
      <td>Row 7</td>
      <td>Row 7</td>
      <td>Row 7</td>
      <td>Row 7</td>
      <td>Row 7</td>
    </tr>
    <tr>
      <td>Row 8</td>
      <td>Row 8</td>
      <td>Row 8</td>
      <td>Row 8</td>
      <td>Row 8</td>
    </tr>
    <tr>
      <td>Row 9</td>
      <td>Row 9</td>
      <td>Row 9</td>
      <td>Row 9</td>
      <td>Row 9</td>
    </tr>
    <tr>
      <td>Row 10</td>
      <td>Row 10</td>
      <td>Row 10</td>
      <td>Row 10</td>
      <td>Row 10</td>
    </tr>
  </tbody>
</table>