常见样式问题五、表格宽度自动计算规则

本文详细解析了HTML表格在固定布局和自动布局模式下的宽度计算规则,包括所有列未定义宽度、部分列定义宽度等情况下的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表格注意点:

  • 如果表格单元width为数值,width表示的是content的宽度;如果表格单元width为百分比,width表示的是content + padding + border的宽度。
  • 表格border-collapse为collapse时,各列含border的列宽之和 >= 实际表格宽度。
  • 固定布局的表格,只有首行的列设置的宽度有效,第二行及之后设置的宽度不起作用;自动布局的表格,所有行的列设置宽度都会影响列的最终宽度。
先设定几个通用的变量:
  • definedTdWidth:所有定义了宽度(数值、百分比)的列的宽度之和。包含content、border、padding的单元格宽度。
  • numTdWidth:所有定义了数值宽度(数值、百分比)的列的宽度之和。包含content、border、padding的单元格宽度。
  • tableWidth:表格宽度

一、表格固定布局

下面的代码将作为固定布局的表格的例子。不同情况会设置不同的样式。

<style>
.table1{table-layout:fixed; border-collapse:collapse; border:1px solid black; }
th{border:1px solid black; padding: 4px;}
</style>
<table class='table1'>
  <tr>
     <th class='col1'>col1col1col1col1第一列</th>
     <th class='col2'>col2col2这是第二列</th>
     <th class='col3'>col3这是第三列。这是第三列。</th>
     <th class='col4'>这是第四列</th>
  </tr>
</table>

1、所有列宽度未定义

1)表格的宽度也没有定义

根据内容的大小来设置表格的宽度(内容长度越长,宽度越长)。但最后表格总宽度不会超出父元素。比如上面这段代码效果如下:


2)表格的宽度已定义

均分宽度,使每列的宽度相等。上面那段代码加上样式:

.table1{width:500px;}

效果如下图所示(宽度均分。可以看到第一列和第二列文字还重叠了,这是默认不允许单词内换行)


2、所有列都定了宽度,同时所有列宽度之和小于表格宽度(definedTdWidth< tableWidth)

实测结果是将表格宽度与列宽和的差值,按每列宽度(含padding、border)所占比分配。即每列加上宽度:(table_width - tdWidth_includeBorder) * (含border的列宽度/tdWidth_includeBorder)(疑问:CSS权威指南上是说两者差值/列数,把这个宽度加到每列上。和实践不一致

增加样式如下:

.table1{width:600px;}
.col1, .col2{width:40px;}
.col3, .col4{width:100px;}

按照公式计算第一、二列加上差值 = (600 - 320) * (50 / 320) = 43.75。同样方式,第三、四列应加差值96.25。

效果如下图所示。下图中标注的宽度是指实际content的宽度,不包含padding、border。将实际content宽度和定义content宽度相减,差值和按公式计算出来的差不多。

3、所有列都定了宽度,同时所有列宽度之和大于表格宽度(definedTdWidth > tableWidth)

每列的宽度为自身定义的宽度,表格的宽度为所有列宽度总和(会超出表格定义的宽度)

.table1{width:100px;}
.col1, .col2, .col3, .col4{width:150px;}

效果如下图所示。下图中标注的宽度是指content的宽度。

4、部分列定了宽度,同时定了宽度的列的宽度之和小于表格宽度(definedTdWidth< tableWidth)

定义宽度的列的宽度为自身定义的宽度,其他没有定义宽度的列的宽度=(tableWidth - tdWidth_includeBorder)/未定义列数。

增加样式如下:

.table1{width:600px;}
.col1, .col2{width:100px;}

效果如下图所示。下图中标注的宽度是指实际content的宽度。


5、部分列定义了宽度,同时定义了宽度的列的宽度之和 > 表格宽度(definedTdWidth< tableWidth)

定义宽度的列的实际宽度为自身定义的宽度,其他没有定义宽度的列宽度为0。因为未定义宽度的列宽度 = (tableWidth - definedTdWidth) /  未定义宽度的列数。平均分配后的宽度小于零,因此没有定义宽度的列的宽度为0。

设置样式如下:

.table1{width:400px}
.col1,.col2{width:200px}

效果如下图。图中第三列和第四列没有边框,重叠在一块,因为第三、四列宽度为0:


6、部分列宽度是百分比

1)如果部分列宽度是百分比,部分列是数值,且定义数值宽度的列宽度和 > 表格宽度 (definedTdWidth > tableWidth)。

宽度为数值的列先保持,未定义宽度的列宽度值为0。表格宽度与数值宽度列宽度之和的差值,在定义了百分比的列按比例分配。即列宽度 = (tableWidth - numTdWidth) * (列宽度百分比 /  列宽度百分比之和)。如果表格剩下的宽度为0,那宽度是百分比的列的计算宽度为0。

增加样式代码如下:

.table1{width:800px;}
.col1,.col2{width:200px}
.col3{width:50%;}
.col4{width:100%;}
效果如下图所示,第一、二列“content宽度”基本保持定义的宽度( 猜测微 小的差异应该是跟浏览器计算宽度舍入有关,具体原理不是很清楚)。第三列“实际总宽度”(渲染后实际显示宽度)约等于第四列的1/2。


2)如果全部列都定义了宽度,但部分列宽度是百分比,且定义数值宽度的列宽度和 < 表格宽度(tdWidth_includeBorder > table_width)
将表格宽度减去列宽度和,将差值在百分比宽度的列中分摊,按列 百分比宽度占所有百分比之和分配 即列宽度 = ( tableWidth - numTdWidth) * (列宽度百分比 /  列宽度百分比之和)。
如果分摊完后,百分比宽度的列宽度已超期百分比对应的值,则修正为按百分比计算的值。接下来再把剩余的宽度按列宽度占比分配到所有列中。
增加样式代码如下:
.table1{width:800px;}
.col1,.col2{width:200px}
.col3{width:10%;}
.col4{width:20%;}
效果如下图所示。下图中第三列“实际总宽度”约等于第四列的1/2。


3)如果部分列定义数值宽度,部分列定义百分比,部分列未定义宽度,且列宽和 < 表格宽度。

将表格宽度减去列宽度和,差值在未定义宽度的列中均分。即列宽度 = ( tableWidth - tdWidth_includeBorder)/ 未定义宽度的列数量。
增加样式代码如下:
.table1{width:800px;}
.col1{width:200px;}
.col3{width:10%;}
.col4{width:20%;}
效果如下图所示。
二、表格自动布局

最小列宽度:自动布局中,最小列宽度=max(显示内容所需最小宽度,定义的宽度)。显示内容所需最小宽度是指满足条件下允许的最小宽度(比如词间不允许换行,那所需最小宽度就是最长的词)。

下面的代码将作为自动布局的表格的例子。不同情况会设置不同的样式。

<style>
.table1{table-layout:auto; border-collapse:collapse; border:1px solid black; }
th{border:1px solid black; padding: 4px;}
</style>
<table class='table1'>
  <tr>
     <th class='col1'>col1col1col1col1第一列</th>
     <th class='col2'>col2col2这是第二列</th>
     <th class='col3'>col3这是第三列。这是第三列。</th>
     <th class='col4'>这是第四列</th>
  </tr>
</table>

1、所有列都未定义宽度

每一列的宽度完全由里面的内容所决定。如果设置了表格宽度,表格宽度大于列宽度和,那会把表格宽度与列宽度和的差值按列宽度比例进行分配。

不额外设置样式,效果如下:


2、所有列都定义了宽度,最小列宽度之和<表格宽度

表格宽度与最小列宽度之和差值,按最小列宽度比例进行分配。

增加样式代码如下:

.table1{width:600px;}
.col1, .col2,.col3, .col4{width:40px;}

效果如下图所示:

3、所有列都定义了宽度,最小列宽度之和>表格宽度
计算显示内容所需最小宽度,先保证每列满足内容所需最小宽度。
1)如果内容所需最小宽度和 > 表格宽度,那每列会保持内容所需最小宽度

增加样式如下:

.table1{width:100px;}
.col1, .col2,.col3, .col4{width:120px;}

效果如下图所示。下图中各列的content宽度分别为:第一列134px,第二列67px,第三列34px,第四列16px。


2)如果内容所需最小宽度和 < 表格宽度,那这两者之间的差值会按一定方式分摊到未达到定义宽度的列
计算各列内容所需宽度与定义宽度的差值,记为diff。将表格宽度与最小宽度和的差值按照各列diff比值来分摊。
.table1{width:400px;}
.col1, .col2,.col3, .col4{width:120px;}

效果如下图所示。下图中各列的content宽度分别为:第一列134px,第二列91px,第三列74px,第四列64px。


4、部分列定义了宽度,最小列宽度之和<表格宽度

首先保证各列内容所需最小宽度,然后保证列的百分比宽度,再保证列的数值宽度。如果有剩余,把剩余按内容最大长度(即内容不换行时的长度)分摊到未定义的列。
增加样式如下:

.table1{width:500px;}
.col1, .col4{width:100px;}

效果如图所示,第二、三列未定义宽度,第三列宽度大于第二列。


5、部分列定义了宽度,最小列宽度之和>表格宽度

1)如果内容所需最小宽度和 > 表格宽度,那每列会保持内容所需最小宽度

增加样式如下:

.table1{width:300px;}
.col3, .col4{width:120px;}

效果如下图所示。下图中各列的content宽度分别为:第一列134px,第二列67px,第三列34px,第四列16px。


2)如果内容所需最小宽度和 < 表格宽度, 那这两者之间的差值会按一定方式分摊到未达到定义宽度的列

增加样式如下:

.table1{width:300px;}
.col3, .col4{width:120px;}
效果如下图,下图中各列的content宽度分别为:第一列134px,第二列67px,第三列84px,第四列78px。

6、存在列宽度定义为百分比

1)如果最小列宽度和>表格宽度

其他列尽量按内容所需最小宽度显示。内容所需最小宽度和与表格宽度有差值的,这个差值分摊到宽度为百分比的列。

如果百分比总和大于100%,进行修正,从第一个定义百分比的列开始修正:

  • 第一列百分比>100%,第一列修正百分比=100%;
  • 第一列百分比+第二列百分比>100%,第二列修正百分比=(100%-第一列百分比);
  • 第一列百分比+第二列百分比 + 第三列百分比>100%,第三列修正百分比=(100%-第一列百分比-第二列百分比)

以此类推。

从第一个百分比的列开始分配,定义百分比的列宽度 = min(内容所需最小宽度 + 差值,表格宽度 * 百分比)。

如果第一列加上分摊的值超过了表格宽度*百分比。分摊剩余宽度之前要重新修正百分比,把第二列当成第一列,按照前面的修正方法重新修正。

增加样式如下:

.table1{width:500px}
.col1{width:250px;}
.col2{width:50%}
.col3{width:40%}
.col4{width:60%}

经计算后,第2-4列修正百分比为50%,40%,10%。

效果如下图,下图中各列的content宽度分别为:第一列134px,第二列170px,第三列128px,第四列31px。


2)如果最小列宽度和<表格宽度

在满足内容所需最小宽度的前提下,宽度保持百分比对应的宽度。剩余宽度在定义数值宽度、未定义宽度的列中均摊。

增加样式如下:

.table1{width:800px}
.col1{width:400px;}
.col2,.col4,.col3{width:10%}

效果如下图所示,下图中各列的content宽度分别为:第一列553px,第2-4列70px。


四、总结

1、固定布局

固定布局一定会保证定义数值宽度的列宽度。然后先尽量保持设置了定义百分比宽度的列宽度。最后再设置未定义宽度的列。

  • 定义数值、百分比宽度的列宽度和如果小于表格宽度,会减少百分比宽度的列。如果调整后还是小于,会调大表格宽度,保持数值宽度的列宽度;
  • 定义数值、百分比宽度的列宽度和如果大于表格宽度,会将宽度分摊到未定义宽度的列。如果不存在未定义列,会将按各列宽度占比宽度进行分摊。

2、自动布局

自动布局一定会保证所有列内容所需最小宽度。然后先尽量保持定义百分比宽度的列宽度,再尽量保持定义数值宽度的列宽度。

  • 如果定义数值、百分比宽度的列宽度和大于表格宽度,先缩减到内容所需最小宽度。再将剩余宽度按列修正百分比占总的修正百分比的比值进行分摊。分摊后如果还有剩余百分比宽度,并且有未定义的列,将剩余宽度按列未定义列的内容最大长度(即内容不换行时的长度)比例进行分摊;如果没有未定义的列,将差值按照一定方法来分摊(内容所需宽度与定义宽度的差值比值)到定义数值宽度的列。
  • 如果定义数值、百分比宽度的列宽度和小于表格宽度,在满足最小内容宽度前提下,尽量保持定义百分比宽度的列宽度。剩余宽度分摊按列内容最大长度(即内容不换行时的长度)比例分配到到未定义的列。如果没有未定义的列,剩余宽度按列宽度所占比分摊到定义数值宽度的列。

五、参考文章

1、关于html表格单元格宽度的计算规则





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值