表格注意点:
- 如果表格单元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%;}
.table1{width:800px;}
.col1,.col2{width:200px}
.col3{width:10%;}
.col4{width:20%;}
3)如果部分列定义数值宽度,部分列定义百分比,部分列未定义宽度,且列宽和 < 表格宽度。
.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;}
效果如下图所示:
计算显示内容所需最小宽度,先保证每列满足内容所需最小宽度。
增加样式如下:
.table1{width:100px;}
.col1, .col2,.col3, .col4{width:120px;}
效果如下图所示。下图中各列的content宽度分别为:第一列134px,第二列67px,第三列34px,第四列16px。
计算各列内容所需宽度与定义宽度的差值,记为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、部分列定义了宽度,最小列宽度之和>表格宽度
增加样式如下:
.table1{width:300px;}
.col3, .col4{width:120px;}
效果如下图所示。下图中各列的content宽度分别为:第一列134px,第二列67px,第三列34px,第四列16px。
增加样式如下:
.table1{width:300px;}
.col3, .col4{width:120px;}
效果如下图,下图中各列的content宽度分别为:第一列134px,第二列67px,第三列84px,第四列78px。
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、自动布局
自动布局一定会保证所有列内容所需最小宽度。然后先尽量保持定义百分比宽度的列宽度,再尽量保持定义数值宽度的列宽度。
- 如果定义数值、百分比宽度的列宽度和大于表格宽度,先缩减到内容所需最小宽度。再将剩余宽度按列修正百分比占总的修正百分比的比值进行分摊。分摊后如果还有剩余百分比宽度,并且有未定义的列,将剩余宽度按列未定义列的内容最大长度(即内容不换行时的长度)比例进行分摊;如果没有未定义的列,将差值按照一定方法来分摊(内容所需宽度与定义宽度的差值比值)到定义数值宽度的列。;
- 如果定义数值、百分比宽度的列宽度和小于表格宽度,在满足最小内容宽度前提下,尽量保持定义百分比宽度的列宽度。剩余宽度分摊按列内容最大长度(即内容不换行时的长度)比例分配到到未定义的列。如果没有未定义的列,剩余宽度按列宽度所占比分摊到定义数值宽度的列。
五、参考文章