我怎么能设置为<表> 100%的宽度,只把里面<tbody>垂直滚动一些高度?

table { width: 100%; display:block; } thead { display: inline-block; width: 100%; height: 20px; } tbody { height: 200px; display: inline-block; width: 100%; overflow: auto; } <table> <thead> <tr> <th>Head 1</th> <th>Head 2</th> <th>Head 3</th> <th>Head 4</th> <th>Head 5</th> </tr> </thead> <tbody> <tr> <td>Content 1</td> <td>Content 2</td> <td>Content 3</td> <td>Content 4</td> <td>Content 5</td> </tr> </tbody> </table>

我想避免添加一些额外的div,我想要的只是这样一个简单的表,当我试图改变显示,表布局,位置和CSS表中的更多东西时,100%宽度只在px中固定宽度工作不好。


当前回答

在制作body & head显示块后,添加一个固定宽度到td,可以很好地工作,我们也可以使用slimscroll插件使滚动条美观。

<!DOCTYPE html> <html> <head> <title> Scrollable table </title> <style> body { font-family: sans-serif; font-size: 0.9em; } table { border-collapse: collapse; border-bottom: 1px solid #ddd; } thead { background-color: #333; color: #fff; } thead,tbody { display: block; } th,td { padding: 8px 10px; border: 1px solid #ddd; width: 117px; box-sizing: border-box; } tbody { height: 160px; overflow-y: scroll } </style> </head> <body> <table class="example-table"> <thead> <tr> <th> Header 1 </th> <th> Header 2 </th> <th> Header 3 </th> <th> Header 4 </th> </tr> </thead> <tbody> <tr> <td> Row 1- Col 1 </td> <td> Row 1- Col 2 </td> <td> Row 1- Col 3 </td> <td> Row 1- Col 4 </td> </tr> <tr> <td> Row 2- Col 1 </td> <td> Row 2- Col 2 </td> <td> Row 2- Col 3 </td> <td> Row 2- Col 4 </td> </tr> <tr> <td> Row 3- Col 1 </td> <td> Row 3- Col 2 </td> <td> Row 3- Col 3 </td> <td> Row 3- Col 4 </td> </tr> <tr> <td> Row 4- Col 1 </td> <td> Row 4- Col 2 </td> <td> Row 4- Col 3 </td> <td> Row 4- Col 4 </td> </tr> <tr> <td> Row 5- Col 1 </td> <td> Row 5- Col 2 </td> <td> Row 5- Col 3 </td> <td> Row 5- Col 4 </td> </tr> <tr> <td> Row 6- Col 1 </td> <td> Row 6- Col 2 </td> <td> Row 6- Col 3 </td> <td> Row 6- Col 4 </td> </tr> <tr> <td> Row 7- Col 1 </td> <td> Row 7- Col 2 </td> <td> Row 7- Col 3 </td> <td> Row 7- Col 4 </td> </tr> <tr> <td> Row 8- Col 1 </td> <td> Row 8- Col 2 </td> <td> Row 8- Col 3 </td> <td> Row 8- Col 4 </td> </tr> <tr> <td> Row 9- Col 1 </td> <td> Row 9- Col 2 </td> <td> Row 9- Col 3 </td> <td> Row 9- Col 4 </td> </tr> <tr> <td> Row 10- Col 1 </td> <td> Row 10- Col 2 </td> <td> Row 10- Col 3 </td> <td> Row 10- Col 4 </td> </tr> <tr> <td> Row 11- Col 1 </td> <td> Row 11- Col 2 </td> <td> Row 11- Col 3 </td> <td> Row 11- Col 4 </td> </tr> <tr> <td> Row 12- Col 1 </td> <td> Row 12- Col 2 </td> <td> Row 12- Col 3 </td> <td> Row 12- Col 4 </td> </tr> <tr> <td> Row 13- Col 1 </td> <td> Row 13- Col 2 </td> <td> Row 13- Col 3 </td> <td> Row 13- Col 4 </td> </tr> <tr> <td> Row 14- Col 1 </td> <td> Row 14- Col 2 </td> <td> Row 14- Col 3 </td> <td> Row 14- Col 4 </td> </tr> <tr> <td> Row 15- Col 1 </td> <td> Row 15- Col 2 </td> <td> Row 15- Col 3 </td> <td> Row 15- Col 4 </td> </tr> <tr> <td> Row 16- Col 1 </td> <td> Row 16- Col 2 </td> <td> Row 16- Col 3 </td> <td> Row 16- Col 4 </td> </tr> </tbody> </table> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-slimScroll/1.3.8/jquery.slimscroll.min.js"></script> <script> $('.example-table tbody').slimscroll({ height: '160px', alwaysVisible: true, color: '#333' }) </script> </body> </html>

其他回答

CSS-only

Chrome, Firefox, Edge(和其他常青树浏览器)

简单位置:粘;上图:0;第th元素:

/* Fix table head */ .tableFixHead { overflow: auto; height: 100px; } .tableFixHead th { position: sticky; top: 0; } /* Just common table stuff. */ table { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; } th { background:#eee; } <div class="tableFixHead"> <table> <thead> <tr><th>TH 1</th><th>TH 2</th></tr> </thead> <tbody> <tr><td>A1</td><td>A2</td></tr> <tr><td>B1</td><td>B2</td></tr> <tr><td>C1</td><td>C2</td></tr> <tr><td>D1</td><td>D2</td></tr> <tr><td>E1</td><td>E2</td></tr> </tbody> </table> </div>

PS:如果你需要边界的TH元素TH {box-shadow: 1px 1px 0 #000;Border-top: 0;}将会有帮助(因为默认的边框不会在滚动上正确绘制)。

对于上面的一个变体,为了适应IE11,只使用了一点JS,请参阅下面的答案:固定标题和可滚动正文

使用“overflow: scroll”时,必须在头部和尾部设置“display:block”。这会打乱它们之间的列宽。但随后你可以用Javascript复制标题行,并将其作为隐藏行粘贴到tbody中,以保持准确的col宽度。

$('.myTable thead > tr')
    .clone()
    .appendTo('.myTable tbody')
    .addClass('hidden-to-set-col-widths')
;

http://jsfiddle.net/Julesezaar/mup0c5hk/

    <table class="myTable">
        <thead>
            <tr>
                <td>Problem</td>
                <td>Solution</td>
                <td>blah</td>
                <td>derp</td>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    <p>
      Some text to here
    </p>

css:


    table {
      background-color: #aaa;
      width: 100%;
    }
    
    thead,
    tbody {
      display: block; // Necessary to use overflow: scroll
    }
    
    tbody {
      background-color: #ddd;
      height: 150px;
      overflow-y: scroll;
    }
    
    tbody tr.hidden-to-set-col-widths,
    tbody tr.hidden-to-set-col-widths td {
      visibility: hidden;
      height: 0;
      line-height: 0;
      padding-top: 0;
      padding-bottom: 0;
    }
    
    td {
      padding: 3px 10px;
    }

使用“block”tbody强制列正确显示的Css解决方案

这个解决方案仍然需要计算和设置的宽度的jQuery

table.scroll tbody,
table.scroll thead { display: block; }

table.scroll tbody {
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 300px;
}

table.scroll tr {
    display: flex;
}

table.scroll tr > td {
    flex-grow: 1;
    flex-basis: 0;
}

Jquery / Javascript

var $table = $('#the_table_element'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

$table.addClass('scroll');

// Adjust the width of thead cells when window resizes
$(window).resize(function () {

    // Get the tbody columns width array
    colWidth = $bodyCells.map(function () {
        return $(this).width();
    }).get();

    // Set the width of thead columns
    $table.find('thead tr').children().each(function (i, v) {
        $(v).width(colWidth[i]);
    });

}).resize(); // Trigger resize handler

为了使<tbody>元素可滚动,我们需要改变它在页面上的显示方式,即使用display: block;将其显示为块级元素。

既然我们改变了tbody的显示属性,我们也应该改变thead元素的显示属性,以防止破坏表格布局。

所以我们有:

thead, tbody { display: block; }

tbody {
    height: 100px;       /* Just for the demo          */
    overflow-y: auto;    /* Trigger vertical scroll    */
    overflow-x: hidden;  /* Hide the horizontal scroll */
}

Web浏览器默认将header和tbody元素显示为row-group (table-header-group和table-row-group)。

一旦我们改变了它,里面的tr元素就不会填满它们容器的整个空间。

为了解决这个问题,我们必须计算tbody列的宽度,并通过JavaScript将相应的值应用到标题列。

自动宽度列

下面是上述逻辑的jQuery版本:

// Change the selector if needed
var $table = $('table'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
    return $(this).width();
}).get();

// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
    $(v).width(colWidth[i]);
});

下面是输出(在Windows 7 Chrome 32上):

工作演示。

全宽表,相对宽度列

根据原始海报的需要,我们可以将表格扩展到其容器宽度的100%,然后对表格的每列使用相对(百分比)宽度。

table {
    width: 100%; /* Optional */
}

tbody td, thead th {
    width: 20%;  /* Optional */
}

由于表格具有(某种)流体布局,因此当容器调整大小时,我们应该调整标题列的宽度。

因此,一旦窗口调整大小,我们应该设置列的宽度:

// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
    /* Same as before */
}).resize(); // Trigger the resize handler once the script runs

输出将是:

工作演示。


浏览器支持和替代方案

我在Windows 7上通过主流浏览器的新版本(包括IE10+)测试了上述两种方法,它们都有效。

但是,它在IE9及以下版本上不能正常工作。

这是因为在表格布局中,所有元素都应该遵循相同的结构属性。

通过使用display: block;对于<thead>和<tbody>元素,我们破坏了表的结构。

通过JavaScript重新设计布局

一种方法是重新设计(整个)表布局。使用JavaScript动态创建新布局,动态处理和/或调整单元格的宽度/高度。

例如,看看下面的例子:

jQuery .floatThead()插件(浮动/锁定/粘滞表头插件) jQuery可滚动表插件。(源代码在github) jQuery .FixedHeaderTable()插件(源代码在github) 数据表垂直滚动的例子。

嵌套表

这种方法使用两个包含div的嵌套表。第一个表只有一个包含div的单元格,而第二个表被放置在div元素中。

在CSS Play中检查垂直滚动表。

这适用于大多数浏览器。我们还可以通过JavaScript动态地执行上述逻辑。

在滚动上具有固定标题的表

由于向<tbody>添加垂直滚动条的目的是在每行的顶部显示表头,因此我们可以将thead元素定位为固定在屏幕的顶部。

下面是Julien对这种方法的工作演示。 它有一个很有前途的网络浏览器支持。

这里是Willem Van Bockstal的纯CSS实现。


纯CSS解决方案

这是老答案。当然,我已经添加了一个新方法并改进了CSS声明。

固定宽度的表格

在这种情况下,表应该有一个固定的宽度(包括列的宽度和垂直滚动条的宽度)。

每一列都应该有一个特定的宽度,头元素的最后一列需要一个更大的宽度,它等于其他的宽度+垂直滚动条的宽度。

因此,CSS将是:

table {
    width: 716px; /* 140px * 5 column + 16px scrollbar width */
    border-spacing: 0;
}

tbody, thead tr { display: block; }

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 140px;
}

thead th:last-child {
    width: 156px; /* 140px + 16px scrollbar width */
}

输出如下:

工作演示。

100%宽度的表格

在这种方法中,表的宽度为100%,对于每个th和td, width属性的值应该小于100% / cols的个数。

同样,我们需要减少头部的宽度作为垂直滚动条宽度的值。

为了做到这一点,我们需要使用CSS3 calc()函数,如下所示:

table {
    width: 100%;
    border-spacing: 0;
}

thead, tbody, tr, th, td { display: block; }

thead tr {
    /* fallback */
    width: 97%;
    /* minus scroll bar width */
    width: -webkit-calc(100% - 16px);
    width:    -moz-calc(100% - 16px);
    width:         calc(100% - 16px);
}

tr:after {  /* clearing float */
    content: ' ';
    display: block;
    visibility: hidden;
    clear: both;
}

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 19%;  /* 19% is less than (100% / 5 cols) = 20% */
    float: left;
}

这里是在线演示。

注意:如果每一列的内容都换行了,这种方法就会失败,即每个单元格的内容应该足够短。


下面是我在回答这个问题时创建的两个纯CSS解决方案的简单示例。

下面是jsFiddle演示v2。

旧版本:jsFiddle Demo v1

在下面的解决方案中,表占用了100%的父容器,不需要绝对大小。它是纯CSS,使用flex布局。

这是它的样子:

可能的缺点:

垂直滚动条总是可见的,不管它是否是必需的; 表格布局是固定的-列不会根据内容宽度调整大小(你仍然可以显式地设置任何你想要的列宽度); 有一个绝对大小——滚动条的宽度,对于我能够检查的浏览器来说,它大约是0.9em。

HTML(缩短):

<div class="table-container">
    <table>
        <thead>
            <tr>
                <th>head1</th>
                <th>head2</th>
                <th>head3</th>
                <th>head4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            ...
        </tbody>
    </table>
</div>

CSS,为了清晰起见省略了一些装饰:

.table-container {
    height: 10em;
}
table {
    display: flex;
    flex-flow: column;
    height: 100%;
    width: 100%;
}
table thead {
    /* head takes the height it requires, 
    and it's not scaled when table is resized */
    flex: 0 0 auto;
    width: calc(100% - 0.9em);
}
table tbody {
    /* body takes all the remaining available space */
    flex: 1 1 auto;
    display: block;
    overflow-y: scroll;
}
table tbody tr {
    width: 100%;
}
table thead, table tbody tr {
    display: table;
    table-layout: fixed;
}

jsfiddle的完整代码

相同的代码在LESS,所以你可以混合在:

.table-scrollable() {
  @scrollbar-width: 0.9em;
  display: flex;
  flex-flow: column;

  thead,
  tbody tr {
    display: table;
    table-layout: fixed;
  }

  thead {
    flex: 0 0 auto;
    width: ~"calc(100% - @{scrollbar-width})";
  }

  tbody {
    display: block;
    flex: 1 1 auto;
    overflow-y: scroll;

    tr {
      width: 100%;
    }
  }
}