问题描述
固定表格布局下的各浏览器对与表格宽度计算算法不同。
造成的影响
1. 内容溢出
列的宽度不够容纳其内容时,IE6 IE7 IE8(Q) 会将溢出的内容隐藏,而其他浏览器则会根据单元格的 'overflow' 属性决定是否隐藏溢出内容,这时候溢出单元格的内容有可能与其他单元格的文字重叠。
2. 列的实际宽度不是设定宽度
有浏览器对于 TABLE 元素均是将宽度作用于 'border-box',但是对于 TD 元素的宽度的作用范围在不同浏览器中却产生了差异,而 IE(Q) Chrome Safari 中的处理更接近标准,即单元格与表格一样,其宽度均作用于 border-box 。
由于单元格边白的影响,当我们为一组列设定宽度后,其实际运行效果不一定与设定宽度相符。这有可能造成一系列的问题,如内容溢出、内容折行等。这时应尽量避免设置单元格的 'padding',若需要单元格内容需要留有空白,可以为其添加子元素 DIV,为 DIV 元素设置 margin 达到相同的效果。
受影响的浏览器
所有浏览器 |
---|
问题分析
1. 表格的宽度算法table-layout介绍
CSS2 中的 'table-layout' 属性定义了两种不同的表格宽度计算方式,根据 W3C CSS2.1 规范第 17.5.3 节中的描述, 'table-layout' 属性值有 'auto' 与 'fixed',对应两种不同的计算方法,'auto'为缺省值。
- “auto”(自动算法)适用于任何表格布局,CSS规范并没有明确规定用户端在表格布局时必须遵守何种算法,此种算法反映了传统HTML表格的特征,每列的宽度是由各列单元格中没有折行的最宽的内容设定的,自动算法有时会较慢,因为它需要在下载完整个表格并访问表格中所有的内容后才能决定表格的最终布局。
- 'fixed'(固定布局算法)适用于固定表格布局,这是一种快速算法,表格的水平布局不依赖于单元格的内容,而只依赖于表格的宽度,列的宽度以及边框或单元格的间隔。使用固定布局算法,用户端在下载完第一行后就可以开始表格布局,后续行的单元格不影响列宽。
1.1. 固定布局算法概述
CSS 规范中对 'table-layout:fixed' 这种固定布局算法有更具体的描述,这种算法下,表格的宽度应显式的由 'width' 属性指定。如果其 width 为 auto,则代表将使用自动算法('table-layout:auto')对表格布局。
在固定表格布局算法中,各列的宽度也有规定:
- 若列元素的宽度不为auto,则该列的宽度即为该指定值;
- 如果单元格扩展到若干个列(rowspan属性),宽度将在列内平分;
- 其它列平均分配剩下的表格水平空间(减去边框或单元格间隔)。
所以,表格的实际宽度是 TABLE 元素的 'width' 设定宽度和各列宽(加上单元格间隔或边框)之和的较大值。若表格比各列之和更宽,则多余的空间(或宽度)将被分配到所有列中。
上述内容仅规定了最一般情况下对于 'table-layout:fixed' 时表格宽度计算所应遵循的基本规范。而对于列宽设定为百分数及像素单位时,单元格包含边白(padding),或者 TABLE 元素设置了 cellpadding 及 cellspacing 属性时等复杂情况,规范并没有明确说明浏览器端应该遵循的一些基本算法。下面将就这些较复杂的情况分析各浏览器对固定布局算法的表格、单元格宽度的计算。
由于在 IE6(SQ) IE7(SQ) IE8(Q) 中TD元素内容溢出 BUG,所以为了简化情况,下面的测试样例只讨论算法的差别,不再对 IE 的 BUG 进行截图。各浏览器对于计算后的宽度为小数时,由于精度不同带来的 1px 的差异不再进行分别讨论。
2. 各浏览器对于固定布局下的表格宽度计算算法差异
由于 W3C 规范中并没有明确说明宽度算法,各浏览器根据各自的理解进行宽度计算,而浏览器之间出现差异主要体现在表格元素设置的宽度与单元格设置的宽度之和不符时,各浏览器的算法差异。
测试代码中均在 TD 元素内加了一层 DIV 元素,目的是通过 TD 与 DIV 背景色区分出 TD 元素的实际可用宽度,即 TD 内可以容纳内容的实际宽度。
2.1. 宽度设定为百分比
2.1.1. 算法分类
<table style="width:200px; table-layout:fixed; background:darkkhaki;" cellpadding="0" cellspacing="0"> <tr> <td style="width:10%; background:plum;"> <!-- 【TD1】 --> <div style="background:pink;">AAA</div> </td> <td style="width:30%; background:dodgerblue; padding-left:50px;"> <!-- 【TD2】 --> <div style="background:lightblue;">BBB</div> </td> <td style="width:60%; background:crimson;"> <!-- 【TD3】 --> <div style="background:gold;">CCC</div> </td> </tr> </table>
这段代码在各浏览器环境中的表现如下:
IE6 IE7 IE8(Q) | |
---|---|
IE8(S) Chrome Safari Opera | |
Firefox |
从上面截图中可以明显看出,Firefox与其他浏览器对于单元格设置了padding后的算法不同,而IE6/7及IE8混杂模式与Chrome的区别仅仅是对于TD元素中的内容溢出后浏览器是否隐藏溢出的内容。W3C CSS2.1规范第17.5.2.1节 中有明确的规定:
In this manner, the user agent can begin to lay out the table on