CSS2.1 规范中对 'table-layout:fixed' 这种固定布局算法有更具体的描述,这种算法下,表格的宽度应显式的由 'width' 特性指定。如果其 'width' 为 'auto',则代表将使用自动算法 ('table-layout:auto') 对表格布局。
在固定表格布局算法中,各列的宽度也有规定:
所以,表格的实际宽度是 TABLE 元素的 'width' 设定宽度和各列宽 (加上单元格间隔或边框) 之和的较大值。若表格比各列之和更宽,则多余的空间 (或宽度) 将被分配到所有列中。
关于固定表格布局,请参照 CSS2.1 规范 17.5.2.1 Fixed table layout。
各浏览器中固定表格布局下对 TD TH 的宽度作用位置有差异,Firefox Opera IE7(S) IE8(S)1 中 TD TH 的宽度始终作用在 content box 上,而 Chrome Safari IE6 IE7(Q) IE8(Q) 作用在 border box。
注 1:IE 部分版本中从单元格溢出的内容会被自动剪裁,参见:RX1002: IE6 IE7 IE8(Q) 中从单元格溢出的内容会被自动剪裁,在本文中忽略此问题。
各浏览器中固定表格布局下对 TD TH 元素的宽度作用位置有差异,在不同浏览器下页面布局出现混乱。
所有浏览器 |
---|
本文均以两列的布局为例,分四部分讨论分析差异。
分析以下代码:fixed_1_width_1_auto.html
<!DOCTYPE html> <html> <head> <style> body { font-family:consolas; } table { table-layout:fixed; width:120px; } td { background:wheat; padding:5px; } td div { background:#eee; } </style> </head> <body> <table cellspacing="0" cellpadding="0"> <tr> <td id="td1" style="border:5px solid plum;"> <div id="d1">A</div> </td> <td id="td2" style="width:70px; border:5px solid coral;"> <div id="d2">B</div> </td> </tr> </table> <div id="info"></div> <script> function $(id) { return document.getElementById(id); } $("info").innerHTML = "A:" + $("d1").offsetWidth + "...B:" + $("d2").offsetWidth; </script> </body> </html>
以上代码 TABLE 元素采用固定表格布局,只给一列 TD 元素设置宽度,且该宽度未超过 TABLE 的宽度,另一列未设置宽度。
这段代码在各浏览器环境中的表现如下:
Firefox Opera IE6(S) IE7(S) IE8(S) | Chrome Safari IE6(Q) IE7(Q) IE8(Q) |
---|---|
可见,
分析以下代码:fixed_2_width.html
<!DOCTYPE html> <html> <head> <style> body { font-family:consolas; } table { table-layout:fixed; width:120px; } td { background:wheat; } </style> </head> <body> <table id="table1" cellspacing="0" cellpadding="0"> <tr> <td id="td11" style="width:30px; border:5px solid plum;">A</td> <td id="td12" style="width:90px; border:5px solid coral;">B</td> </tr> </table> <div id="info1"></div> <br /> <table id="table2" cellspacing="0" cellpadding="0"> <tr> <td id="td21" style="width:30px; border:5px solid plum;">A</td> <td id="td22" style="width:70px; border:5px solid coral;">B</td> </tr> </table> <div id="info2"></div> <br /> <table id="table3" cellspacing="0" cellpadding="0"> <tr> <td id="td31" style="width:30px; border:5px solid plum;">A</td> <td id="td32" style="width:50px; border:5px solid coral;">B</td> </tr> </table> <div id="info3"></div> <script> function $(id) { return document.getElementById(id); } var w11 = $("td11").clientWidth, w12 = $("td12").clientWidth, w21 = $("td21").clientWidth, w22 = $("td22").clientWidth, w31 = $("td31").clientWidth, w32 = $("td32").clientWidth, wt1 = $("table1").offsetWidth, wt2 = $("table2").offsetWidth; wt3 = $("table3").offsetWidth; $("info1").innerHTML = "A:30/" + w11 + ", B:90/" + w12 + ", TABLE:120/" + wt1; $("info2").innerHTML = "A:30/" + w21 + ", B:70/" + w22 + ", TABLE:120/" + wt2; $("info3").innerHTML = "A:30/" + w31 + ", B:50/" + w32 + ", TABLE:120/" + wt3; </script> </body> </html>
以上代码 TABLE 元素采用固定表格布局,同时为两列 TD 元素设置了宽度。
第一组中 TD 元素的 'width' 特性值分别为 30px、90px,刚好等于 TABLE 元素设定的宽度;
第二组中 TD 元素的 'width' 特性值分别为 30px、70px,刚好等于 TABLE 元素减去单元格边框后的宽度;
第三组中 TD 元素的 'width' 特性值分别为 30px、50px,加上其 border 仍然小于 TABLE 元素设定的宽度。
这段代码在各浏览器环境中的表现如下:
Firefox Opera IE6(S) IE7(S) IE8(S) | Chrome Safari IE6(Q) IE7(Q) IE8(Q) |
---|---|
本例中得到的结论和上一个测试样例相同。此外,
出现小于表格设定的宽度的情况时,各浏览器均会尝试根据列设定的宽度按比例重新分配列的宽度,只不过仍然是因为各浏览器在固定表格布局下 TD、TH 元素的作用位置差异,会导致重新分配后的列的宽度在各浏览器中不同。
上述分析的均为原生 TD、TH 元素,下面分析 'display' 特性值为 'table-cell' 的元素在各浏览器中宽度作用位置差异。
分析以下代码:table-cell.html
<!DOCTYPE html> <html> <head> <style> body { font-family:consolas; } </style> </head> <body> <div style="display:table; table-layout:fixed; width:120px;"> <div style="display:table-row;"> <div style="display:table-cell; border:5px solid plum; padding:5px; background:wheat;"> <div id="d1" style="background:#eee;">A</div> </div> <div style="display:table-cell; width:70px; border:5px solid coral; padding:5px; background:wheat;"> <div id="d2" style="background:#eee;">B</div> </div> </div> </div> <div id="info"></div> <br /> <br /> <div style="display:table; table-layout:fixed; width:120px;" id="table1"> <div style="display:table-row;"> <div style="display:table-cell; width:30px; border:5px solid plum; background:wheat;" id="td11">A</div> <div style="display:table-cell; width:90px; border:5px solid coral;background:wheat;" id="td12">B</div> </div> </div> <div id="info1"></div> <br /> <div style="display:table; table-layout:fixed; width:120px;" id="table2"> <div style="display:table-row;"> <div style="display:table-cell; width:30px; border:5px solid plum; background:wheat;" id="td21">A</div> <div style="display:table-cell; width:70px; border:5px solid coral;background:wheat;" id="td22">B</div> </div> </div> <div id="info2"></div> <br /> <div style="display:table; table-layout:fixed; width:120px;" id="table3"> <div style="display:table-row;"> <div style="display:table-cell; width:30px; border:5px solid plum; background:wheat;" id="td31">A</div> <div style="display:table-cell; width:50px; border:5px solid coral;background:wheat;" id="td32">B</div> </div> </div> <div id="info3"></div> <script> function $(id) { return document.getElementById(id); } var w11 = $("td11").clientWidth, w12 = $("td12").clientWidth, w21 = $("td21").clientWidth, w22 = $("td22").clientWidth, w31 = $("td31").clientWidth, w32 = $("td32").clientWidth, wt1 = $("table1").offsetWidth, wt2 = $("table2").offsetWidth; wt3 = $("table3").offsetWidth; $("info").innerHTML = "A:" + $("d1").offsetWidth + "...B:" + $("d2").offsetWidth; $("info1").innerHTML = "A:30/" + w11 + ", B:90/" + w12 + ", TABLE:120/" + wt1; $("info2").innerHTML = "A:30/" + w21 + ", B:70/" + w22 + ", TABLE:120/" + wt2; $("info3").innerHTML = "A:30/" + w31 + ", B:50/" + w32 + ", TABLE:120/" + wt3; </script> </body> </html>
这段代码模拟了上面两节中的测试样例,只是将 TABLE 元素用 'display' 特性值为 'table' 的 DIV 元素代替,将 TR 元素用 'display' 特性值为 'table-row' 的 DIV 元素代替,将 TH、TD 元素用 'display' 特性值为 'table-cell' 的 DIV 元素代替1。
这段代码在各浏览器环境中的表现如下:
Firefox Opera IE8(S)2 | Chrome Safari |
---|---|
通过截图可见,'display' 特性值为 'table-cell' 的元素对于宽度作用位置的差异与上两节中原生 TD、TH 元素的结论相同。即 Chrome Safari 固定表格布局下对 'display' 特性值为 'table-cell' 的元素的宽度作用在 border box 上。IE8(S) Firefox Opera 固定表格布局下对 'display' 特性值为 'table-cell' 的元素的宽度作用在 content box 上。
注 1: 根据 CSS2.1 规范,TABLE 元素的 'display' 特性默认值为 'table',TD、TH 元素的 'display' 特性默认值为 'table-cell';
注 2: 由于 IE6 IE7 IE8(Q) 不支持 display:table-cell,故下面的分析不再考虑这些浏览器。
上述分析的测试代码中表格均为 "分离的边框模型",即 'border-collapse' 特性值为默认的 'separate'。下面将分析 "重合的边框模型" (border-collapse: collapse) 下的表格。
分析以下代码:collapse.html
<!DOCTYPE html> <html> <head> <style> body { font-family:Consolas; margin:0; } table { table-layout:fixed; width:120px; border-collapse:collapse; } td { background:wheat; } </style> </head> <body> <br /><br /><br /> <table id="table1" cellspacing="0" cellpadding="0"> <tr> <td id="td11" style="width:80px; border:20px solid plum;">A</td> <td id="td12" style="width:120px; border:20px solid coral;">B</td> </tr> </table> <div id="info1"></div> <div style="background:brown; height:3px; overflow:hidden;"></div> <br /><br /><br /> <table id="table2" cellspacing="0" cellpadding="0"> <tr> <td id="td21" style="width:40px; border:20px solid plum;">A</td> <td id="td22" style="width:60px; border:20px solid coral;">B</td> </tr> </table> <div id="info2"></div> <div style="background:brown; height:3px; overflow:hidden;"></div> <br /><br /><br /> <table id="table3" cellspacing="0" cellpadding="0"> <tr> <td id="td31" style="width:24px; border:20px solid plum;">A</td> <td id="td32" style="width:36px; border:20px solid coral;">B</td> </tr> </table> <div id="info3"></div> <div style="background:brown; height:3px; overflow:hidden;"></div> <br /><br /><br /> <table id="table4" cellspacing="0" cellpadding="0"> <tr> <td id="td41" style="width:40px; border:50px solid plum;">A</td> <td id="td42" style="width:79px; border:50px solid coral;">B</td> </tr> </table> <div id="info4"></div> <div style="background:brown; height:3px; overflow:hidden;"></div> <br /><br /><br /> <table id="table5" cellspacing="0" cellpadding="0"> <tr> <td id="td51" style="width:40px; border:50px solid plum;">A</td> <td id="td52" style="width:81px; border:50px solid coral;">B</td> </tr> </table> <div id="info5"></div> <div style="background:brown; height:3px; overflow:hidden;"></div> <script> function $(id) { return document.getElementById(id); } var wt1 = $("table1").offsetWidth, wt2 = $("table2").offsetWidth; wt3 = $("table3").offsetWidth; wt4 = $("table4").offsetWidth; wt5 = $("table5").offsetWidth; $("info1").innerHTML = "TABLE:120/" + wt1; $("info2").innerHTML = "TABLE:120/" + wt2; $("info3").innerHTML = "TABLE:120/" + wt3; $("info4").innerHTML = "TABLE:120/" + wt4; $("info5").innerHTML = "TABLE:120/" + wt5; </script> </body> </html>
这段代码在各浏览器环境中的表现如下:
Firefox Opera IE6(S) IE7(S) IE8(S)1 | Chrome Safari | IE6(Q) IE7(Q) IE8(Q) |
---|---|---|
CSS2.1 规范中并没有明确说明固定表格布局 (table-layout: fixed) 下单元格的宽度作用位置以及具体算法,所以各浏览器出现了较大的差异。
注 1: 忽略各浏览器在某些位置的边框颜色渲染差异,具体请参见相关问题链接。
在 'table-layout:fixed' 这种固定布局算法下的表格中,可以为表格最后一列不设置宽度,尽量消除由算法差异带来的列的宽度差异,防止不同浏览器之间表格实际计算的宽度不同。
此外,在使用表格时,应尽量避免恰恰以来单元格的某个特性宽度值进行布局,这很可能导致某些浏览器中由于单元格宽度算法差异导致的意外折行或者内容溢出等现象。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.10 Chrome 7.0.517.17 dev Safari 5.0.2 Opera 10.62 |
测试页面: |
fixed_1_width_1_auto.html
fixed_2_width.html table-cell.html collapse.html |
本文更新时间: | 2010-09-25 |
table-layout 表格 布局 fixed 固定 TD 宽度