100% 宽度的 HTML 表格,在 tbody 内垂直滚动 [英] HTML table with 100% width, with vertical scroll inside tbody

查看:28
本文介绍了100% 宽度的 HTML 表格,在 tbody 内垂直滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何为

设置 100% 宽度并仅在 内垂直滚动一些高度?

table {宽度:100%;显示:块;}头{显示:内联块;宽度:100%;高度:20px;}身体{高度:200px;显示:内联块;宽度:100%;溢出:自动;}

<头><tr><th>头1</th><th>Head 2</th>第 3 个头第 4 个头<th>头5</th></tr></thead><tr><td>内容1</td><td>内容2</td><td>内容3</td><td>内容4</td><td>内容5</td></tr></tbody></table>

我想避免添加一些额外的 div,我想要的只是像这样的简单表格,当我尝试更改显示时,table-layoutposition 等等CSS 表中的内容在 100% 宽度下无法正常工作,仅在 px 中具有固定宽度.

解决方案

为了使

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

由于我们更改了 tbodydisplay 属性,我们也应该更改 thead 元素的该属性以防止破坏表格布局.

所以我们有:

thead, tbody { display: block;}身体{高度:100px;/* 仅用于演示 */溢出-y:自动;/* 触发垂直滚动 */溢出-x:隐藏;/* 隐藏水平滚动 */}

Web 浏览器将 theadtbody 元素显示为 row-group(table-header-grouptable-row-group) 默认.

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

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

自动宽度列

这是上述逻辑的 jQuery 版本:

//如果需要,更改选择器var $table = $('table'),$bodyCells = $table.find('tbody tr:first').children(),颜色宽度;//获取tbody列宽数组colWidth = $bodyCells.map(function() {返回 $(this).width();}).得到();//设置列的宽度$table.find('thead tr').children().each(function(i, v) {$(v).width(colWidth[i]);});

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

.

<小时>

浏览器支持和替代方案

我已经通过新版本的主要网络浏览器(包括 IE10+)在 Windows 7 上测试了上述两种方法,并且有效.

但是,它.

100% 宽度的表格

在这种方法中,table 的宽度为 100% 并且对于每个 thtdwidth 属性的值应小于 100%/列数.

另外,我们需要减小theadwidth作为垂直滚动条width的值.

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

table {宽度:100%;边框间距:0;}thead, tbody, tr, th, td { 显示:块;}头 tr {/* 倒退 */宽度:97%;/* 减去滚动条宽度 */宽度:-webkit-calc(100% - 16px);宽度:-moz-calc(100% - 16px);宽度:计算(100% - 16px);}tr:after {/* 清除浮动 */内容: ' ';显示:块;可见性:隐藏;清楚:两者;}身体{高度:100px;溢出-y:自动;溢出-x:隐藏;}tbody td, thead th {宽度:19%;/* 19% 小于 (100%/5 cols) = 20% */向左飘浮;}

这是在线演示.

注意:这种方法会失败如果每一列的内容都断线,即每个单元格的内容应该足够短.

<小时>

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

这是 jsFiddle 演示 v2.

旧版本:jsFiddle Demo v1

How can I set for <table> 100% width and put only inside <tbody> vertical scroll for some height?

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>

I want to avoid adding some additional div, all I want is simple table like this and when I trying to change display, table-layout, position and much more things in CSS table not working good with 100% width only with fixed width in px.

解决方案

In order to make <tbody> element scrollable, we need to change the way it's displayed on the page i.e. using display: block; to display that as a block level element.

Since we change the display property of tbody, we should change that property for thead element as well to prevent from breaking the table layout.

So we have:

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 browsers display the thead and tbody elements as row-group (table-header-group and table-row-group) by default.

Once we change that, the inside tr elements doesn't fill the entire space of their container.

In order to fix that, we have to calculate the width of tbody columns and apply the corresponding value to the thead columns via JavaScript.

Auto Width Columns

Here is the jQuery version of above logic:

// 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]);
});    

And here is the output (on Windows 7 Chrome 32):

WORKING DEMO.

Full Width Table, Relative Width Columns

As the Original Poster needed, we could expand the table to 100% of width of its container, and then using a relative (Percentage) width for each columns of the table.

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

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

Since the table has a (sort of) fluid layout, we should adjust the width of thead columns when the container resizes.

Hence we should set the columns' widths once the window is resized:

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

The output would be:

WORKING DEMO.


Browser Support and Alternatives

I've tested the two above methods on Windows 7 via the new versions of major Web Browsers (including IE10+) and it worked.

However, it doesn't work properly on IE9 and below.

That's because in a table layout, all elements should follow the same structural properties.

By using display: block; for the <thead> and <tbody> elements, we've broken the table structure.

Redesign layout via JavaScript

One approach is to redesign the (entire) table layout. Using JavaScript to create a new layout on the fly and handle and/or adjust the widths/heights of the cells dynamically.

For instance, take a look at the following examples:

Nesting tables

This approach uses two nested tables with a containing div. The first table has only one cell which has a div, and the second table is placed inside that div element.

Check the Vertical scrolling tables at CSS Play.

This works on most of web browsers. We can also do the above logic dynamically via JavaScript.

Table with fixed header on scroll

Since the purpose of adding vertical scroll bar to the <tbody> is displaying the table header at the top of each row, we could position the thead element to stay fixed at the top of the screen instead.

Here is a Working Demo of this approach performed by Julien.
It has a promising web browser support.

And here a pure CSS implementation by Willem Van Bockstal.


The Pure CSS Solution

Here is the old answer. Of course I've added a new method and refined the CSS declarations.

Table with Fixed Width

In this case, the table should have a fixed width (including the sum of columns' widths and the width of vertical scroll-bar).

Each column should have a specific width and the last column of thead element needs a greater width which equals to the others' width + the width of vertical scroll-bar.

Therefore, the CSS would be:

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 */
}

Here is the output:

WORKING DEMO.

Table with 100% Width

In this approach, the table has a width of 100% and for each th and td, the value of width property should be less than 100% / number of cols.

Also, we need to reduce the width of thead as value of the width of vertical scroll-bar.

In order to do that, we need to use CSS3 calc() function, as follows:

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;
}

Here is the Online Demo.

Note: This approach will fail if the content of each column breaks the line, i.e. the content of each cell should be short enough.


In the following, there are two simple example of pure CSS solution which I created at the time I answered this question.

Here is the jsFiddle Demo v2.

Old version: jsFiddle Demo v1

这篇关于100% 宽度的 HTML 表格,在 tbody 内垂直滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆