根据 CSS2.1 规范中的描述,当 'table-layout' 特性的计算值为 'auto' (初始值) 时代表表格将采用自动表格布局。列的宽度由以下条目决定:(仅列举与本文有关内容)
得到了每一列的最大和最小宽度后,列的宽度如下列所述影响最终表格的宽度:(仅列举与本文有关内容)
若 'table' 或者 'inline-table' 元素的 'width' 特性拥有明确的计算值 (W) 而不是 'auto',则特性的值为 "W" 与 "所有的列要求的最小宽度之和加上单元格间距或边框 (MIN)" 这两个值中的较大者。若 W 大于 MIN,多余的宽度应被分配到各列中。
关于 自动表格布局 的更多信息,请参考 CSS2.1 规范 17.5.2.2 Automatic table layout。
若表格内各列没有明确设定宽度,即其 'width' 特性为默认的 'auto',表格最终渲染时各列的计算宽度会由于单元格内容的差异在不同浏览器中出现不同的计算后的列宽。
此问题可能导致表格的列宽在不同浏览器中出现非常大的差异,严重情况下可能影响页面整体布局。
所有浏览器 |
---|
分析以下代码:td_width_auto.html
<!DOCTYPE html> <html> <head> <style> * { margin:0; font:18px/2 'Trebuchet MS'; } .info td { text-align:center; } table { width:300px; } </style> <script> function $(id) { return document.getElementById(id); } window.onload = function () { for (var k = 1; k <= 3; k++) { for (var i = 1; i <= 4; i++) { $('c' + k + i + 'i').innerHTML = $('c' + k + i).offsetWidth; $('c' + k + i + 'i').width = $('c' + k + i).offsetWidth; } } } </script> </head> <body> <table cellpadding="0" cellspacing="0"> <tr> <td id="c11" style="background:palegreen;"><div style="width:100px;">DIV 100px</div></td> <td id="c12" style="background:goldenrod;"> <div style="float:left; width:20px; height:20px; background:#ccc;"></div> <div style="float:left; width:20px; height:20px; background:#bbb;"></div> <div style="float:left; width:20px; height:20px; background:#aaa;"></div> </td> <td id="c13" style="background:palegreen;"><div style="width:100px;">DIV 100px</div></td> <td id="c14" style="background:goldenrod;"> <div style="float:left; width:20px; height:20px; background:#ccc;"></div> <div style="float:left; width:20px; height:20px; background:#bbb;"></div> <div style="float:left; width:20px; height:20px; background:#aaa;"></div> <div style="float:left; width:20px; height:20px; background:#999;"></div> <div style="float:left; width:20px; height:20px; background:#888;"></div> </td> </tr> </table> <table class="info" cellpadding="0" cellspacing="0"> <tr> <td id="c11i"></td> <td id="c12i"></td> <td id="c13i"></td> <td id="c14i"></td> </tr> </table> <table cellpadding="0" cellspacing="0"> <tr> <td id="c21" style="background:palegreen;"><div style="width:100px;">DIV 100px</div></td> <td id="c22" style="background:goldenrod;"> <div style="float:left; width:30px; height:20px; background:#ccc;"></div> <div style="float:left; width:30px; height:20px; background:#bbb;"></div> </td> <td id="c23" style="background:palegreen;"><div style="width:100px;">DIV 100px</div></td> <td id="c24" style="background:goldenrod;"> <div style="float:left; width:30px; height:20px; background:#ccc;"></div> <div style="float:left; width:40px; height:20px; background:#bbb;"></div> <div style="float:left; width:30px; height:20px; background:#aaa;"></div> </td> </tr> </table> <table class="info" cellpadding="0" cellspacing="0"> <tr> <td id="c21i"></td> <td id="c22i"></td> <td id="c23i"></td> <td id="c24i"></td> </tr> </table> <table cellpadding="0" cellspacing="0"> <tr> <td id="c31" style="background:palegreen;"><div style="width:100px;">DIV 100px</div></td> <td id="c32" style="background:goldenrod;"> <div style="float:left; width:20px; height:20px; background:#ccc;"></div> <div style="float:left; width:20px; height:20px; background:#bbb;"></div> <div style="float:left; width:20px; height:20px; background:#aaa;"></div> <div style="float:left; width:20px; height:20px; background:#999;"></div> <div style="float:left; width:20px; height:20px; background:#888;"></div> <div style="float:left; width:20px; height:20px; background:#777;"></div> </td> <td id="c33" style="background:palegreen;"><div style="width:100px;">DIV 100px</div></td> <td id="c34" style="background:goldenrod;"> <div style="float:left; width:20px; height:20px; background:#ccc;"></div> <div style="float:left; width:20px; height:20px; background:#bbb;"></div> <div style="float:left; width:20px; height:20px; background:#aaa;"></div> <div style="float:left; width:20px; height:20px; background:#999;"></div> <div style="float:left; width:20px; height:20px; background:#888;"></div> <div style="float:left; width:20px; height:20px; background:#777;"></div> </td> </tr> </table> <table class="info" cellpadding="0" cellspacing="0"> <tr> <td id="c31i"></td> <td id="c32i"></td> <td id="c33i"></td> <td id="c34i"></td> </tr> </table> </body> </html>
上述代码中 3 组表格结构相似,均为 4 列没有设定宽度的 TD 元素,第 1、3 列的 TD 中包含一个宽度 100px 的 DIV 元素,第 2、4 列的 TD 中包含若干宽度较小的浮动元素。
这段代码在不同浏览器中运行结果如下:
IE6 IE7 IE8 Firefox Opera | Chrome Safari |
---|---|
可见,各浏览器之间对于此种情形下的列的宽度计算存在算法差异。
尤其在第 3 组中,第 2、4 列中的内容完全相同,在 IE6 IE7 IE8 Firefox Opera 中,浏览器平均分配了列宽。而在 Chrome Safari 中,则出于浏览器内部某种算法而使得列的最终计算宽度与其他浏览器出现了非常大的差异。
下面根据第 3 组表格的数据,参照 CSS2.1 规范来计算列的宽度:
第一列 | 第二列 | 第三列 | 第四列 | |
---|---|---|---|---|
最小列宽 | 100px | 20px | 100px | 20px |
最大列宽 | 100px | 120px | 100px | 120px |
表格宽度 (W) | 300px | |||
所有的列要求的最小宽度之和加上单元格间距或边框 (MIN) | 240px | |||
表格最终宽度 |
max(300px, 240px) = 300px
多余的宽度应被分配到各列中 |
而 CSS2.1 规范并没有明确说明多余宽度的分配算法,所以这里不同浏览器之间出现了差异。
在表格布局中应明确的为各列设定一个明确的宽度。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.10 Chrome 8.0.552.11 dev Safari 5.0.2 Opera 10.63 |
测试页面: | td_width_auto.html |
本文更新时间: | 2010-10-22 |
TABLE TR 表格 列 width 宽度 auto