基于display:table的CSS布局让HTML元素和像table⼀样
当IE8发布时,它将⽀持很多新的CSS display属性值,包括与表格相关的属性值:table、table-row和table-cell,它也是最后⼀款⽀持这些属性值的主流浏览器。它标志着复杂CSS布局技术的结束,同时也给了HTML表格布局致命⼀击。最终,使⽤CSS布局来制作出类似于table布局的栅格将会变得⼗分迅速和简单。
⽹页元素应⽤上那些与表格相关的display属性值后,能够模仿出与表格相同的特性。我将会在该⽂中给⼤家演⽰这种⽅法给CSS布局带来的巨⼤影响。
使⽤CSS表格
CSS表格能够解决所有那些我们在使⽤绝对定位和浮动定位进⾏多列布局时所遇到的问题。例如,“display:table;”的CSS声明能够让⼀个HTML元素和它的⼦节点像table元素⼀样。使⽤基于表格的CSS布局,使我们能够轻松定义⼀个单元格的边界、背景等样式,⽽不会产⽣因为使⽤了table那样的制表标签所导致的语义化问题。
在深⼊了解这种⽅法之前,让我们先来写份HTML⽂档实例:
复制代码
代码如下:
<div id="wrapper">
<div id="main">
<div id="nav">? navigation column content…</div>
css表格样式<div id="extras">? news headlines column content…</div>
<div id="content">? main article content…</div>
</div>
</div>
这份HTML源代码满⾜了内容呈现⽅⾯的要求。先是导航栏,然后是附加栏,最后是内容栏。
我们同样需要将以下CSS样式应⽤上去:
复制代码
代码如下:
#main {
display: table;
border-collapse: collapse;
}
#nav {
display: table-cell;
width: 180px;
background-color: #e7dbcd;
}
#extras {
display: table-cell;
width: 180px;
padding-left: 10px;
border-right: 1px dotted #d7ad7b;
}
#content {
display: table-cell;
width: 380px;
padding-left: 10px;
}
这种基于表格的新CSS布局⽅式能够正确的在IE8、Firefox、Safari和Opera(译者注:包括FF2/FF3/Google都通过了测试)中显⽰出来。下⾯这张图⽚是它在IE8中的样⼦:
我们轻松实现了三栏等⾼布局,⽽⽆需使⽤伪造背景图⽚之类的技巧,更不⽤担⼼定位和清除浮动的问题!
它是怎样实现的?
你可以给HTML元素指定与表格相关的display属性值,使得它们像表格元素那样渲染。以下是这些可⽤的display属性值:table
使该元素按table样式渲染
table-row
使该元素按tr样式渲染
table-cell
使该元素按td样式渲染
table-row-group
使该元素按tbody样式渲染
table-header-group
使该元素按thead样式渲染
table-footer-group
使该元素按tfoot样式渲染
table-caption
使该元素按caption样式渲染
table-column
使该元素按col样式渲染
table-column-group
使该元素按colgroup样式渲染
等等……难道⽤table布局不是错的吗?
可能你会对我们上⾯给出的布局实例有点不爽——毕竟,正如我⾃⼰也是⼀名WEB标准化的拥护者,我们不都⼀直坚持不应该使⽤table来进⾏布局吗?
table元素在HTML当中是⼀个包含语义的标签:它描述什么是数据。因此,你只能⽤它来标记那些需要制表的数据,例如⼀张财务信息表。如果数据能够以电⼦表格的形式保存在你的电脑中,那它在HTML⽂档中很可能需要⽤到table标签进⾏标记。从另⼀⽅⾯来看,display的table属性值只是声明了某些元素在浏览器中的样式——它不包含语义。如果使⽤table元素来进⾏布局,它将会告诉客户端:这些数据是制表的。使⽤⼀些display属性被设置为table和table-cell之类的div标签,除了告诉客户端以某种特定的样式来渲染它们以外,不会告诉客户端任何语义,只要客户端能够⽀持这些属性值。
当然,我们同样还要注意,当我们真的需要制表数据的时候不要使⽤⼀⼤堆被声明为display:table;的div元素。
我们上⾯的那个例⼦是⼀个简单的单⾏三列布局,⽆需费尽⼼思,我们就能够使⽤这种技术轻松实现复杂的栅格布局。
匿名表格元素
CSS表格除了包含table布局的普通规则之外,同时还有着CSS table布局的超强特性:缺少的表格元素会被浏览器以匿名⽅式创建。CSS2.1规范中写道:
CSS2.1表格模型中的元素,可能不会全部包含在除HTML之外的⽂档语⾔中。这时,那些“丢失”的元素会被模拟出来,从⽽使得表格模型能够正常⼯作。所有的表格元素将会⾃动在⾃⾝周围⽣成所需的匿名table对象,使其符合table/inline-table、table-row、table-cell的三层嵌套关系。
这段话的意思是,如果我们为元素使⽤“display:table-cell;”属性,⽽不将其⽗容器设置为“display:table-row;”属性,浏览器会默认创建出⼀个表格⾏,就好像⽂档中真的存在⼀个被声明的表格⾏⼀样。
让我们⽤个简单的例⼦来研究下它的这⼀特性:以下是三栏栅格布局。我们将会⽤三份不同的HTML样例,⽽它们将表现出相
同的视觉效果。
⾸先,以下是能够⽣成三列布局样例的其中⼀份:
复制代码
代码如下:
<div class="container">
<div class="row">
<div class="cell">CELL A</div>
<div class="cell">CELL B</div>
<div class="cell">CELL C</div>
</div>
</div>
这份嵌套的div元素看起来不是那么让⼈兴奋,稍等⼀会,我们现在来做点什么。它的CSS样式也⾮常简单:
复制代码
代码如下:
.container {
display: table;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
width: 100px;
height: 100px;
border: 1px solid blue;
padding: 1em;
}
以上CSS给类名为container的元素定义了“display:table;”属性,类名为row的元素定义了“display:table-row;”,类名为cell的元素定义了“display:table-cell;”,同样还给它定义了边框、⾼度和宽度值。
以上HTML⽂档明确地为三个单元格定义了包含它的表格和表格⾏,使⽤到了所有我们创建的CSS类名。然⽽,我们可以减少这些标签,移除⼀⾏div元素试试:
复制代码
代码如下:
<div class="row">
<div class="cell">CELL A</div>
<div class="cell">CELL B</div>
<div class="cell">CELL C</div>
</div>
即使上⾯的代码遗漏了声明表格的那⼀⾏,浏览器仍将创建⼀个匿名的表格⾏。我们还可以移除更多的代码:
复制代码
代码如下:
<div class="cell">CELL A</div>
<div class="cell">CELL B</div>
<div class="cell">CELL C</div>
以上代码遗漏了声明表格和表格⾏的代码,浏览器同样会创建出这些匿名的盒对象。即使缺少这些标签元素,最终的效果仍然是⼀样的。
创建匿名表格元素的规则
这些匿名的盒对象不是⽤魔术变出来的,它们也不会⾃动往你的HTML源码中添加新的标签。为了完全发挥出匿名表格元素的优势,你最好能够对创建它们的规则有所了解。如果布局中调⽤了匿名元素,浏览器将会根据需要创建⼀个匿名的盒对象并将它的CSS display属性设置为table、table-row或table-cell中的⼀个。
如果某个元素已经被设置为“display:table-cell;”,⽽它的⽗节点(包含它的容器)没有被设置为“display:table-row;”属性,那么浏览器将会创建⼀个被设置为“display:table-row;”的匿名盒对象来嵌套它。并且与之相邻的属性为“display: table-cell;”的兄弟节点也都会被这个匿名盒对象所包含,直到碰到⼀个没有被设置为“display: table-cell;”的元素⽽结束这⼀⾏。以下是相关的代码样例:
复制代码
代码如下:
<div class="cell">CELL A</div>
<div class="cell">CELL B</div>
<div class="cell">CELL C</div>
<div>Not a cell</div>
上⾯的三个类名为“cell”的div元素均被设置为“display:table-cell;”,它们将会像⼀个单⾏表格的三个单元格⼀样并列排布。最后⼀个div元素则不会被包含在这⼀表格⾏当中,因为它没有被设置成“display:table-cell;”。
如果某个元素被设置为“display:table-row;”,⽽它的⽗节点没有被设置为“display:table;”(或者“display:table-row-group;”),浏览器将会创建⼀个被设置为“display:table;”的匿名盒对象来嵌套它,与之相邻的属性为“display: table-row;”的兄弟节点也都会被包含其中。同样,如果某个元素被设置为“display:table-row;”,但它的内部却缺少“display:table-cell;”的元素,那么⼀个匿名的table-cell将会被创建,⽤来包含该table-row中的所有元素。
请看以下代码:
复制代码
代码如下:
<div class="row">ROW A</div>
<div class="row">ROW B</div>
<div>Not a row</div>
上⾯两排类名为“row”的div元素被设置了“display:table-row;”属性,它们将会像单列表格中的两⾏⼀样依次排列。最后⼀个div 元素则不会包含在这个匿名的table中。
以此类推,如果某个元素的display属性值被设置为与表格相关的值,如table-row-group、table-header-group、 table-footer-group、table-column、table-column-group以及table-caption,但同时⼜没有⼀个被设置为“display:table;”的⽗元素,那么⼀个匿名的盒对象将会被创建⽤来包含该元素和它的某些兄弟节点。
其他有⽤的表格属性
当使⽤CSS表格时,因为这些元素遵从table布局的普通规则,所以你还可以给它们应⽤其它表格相关的CSS属性。下⾯是⼀些派得上⽤场的属性:
table-layout
将table-layout属性设置为fixed可以让浏览器按照固定算法来渲染单元格的宽度。这在固定宽度布局中⾮常有⽤,例如我们最上⾯的那段布局代码。
Border-collapse
和普通的HTML表格⼀样,你可以使⽤border-collapse属性来定义你的table布局元素之间使⽤何种形式的边框,是共⽤边框(赋值为collapse)还是使⽤各⾃独⽴的边框(赋值为separate)。
Border-spacing
如果你声明了“border-collapse:separate;”,那么你就可以使⽤border-spacing属性来定义相邻两个单元格边框间的距离。
制作完美的栅格
制作等⾼栅格对于传统CSS布局技术来说已经成为⼀个难题,然⽽使⽤合适的CSS表格则很容易实现。例如,如果我们想制作⼀个包含图⽚和标题的影像图库栅格(如下图),使⽤CSS表格很快就能搞定。
以下是我们这个影像图库的代码:
复制代码
代码如下:
<div class="grid">
<div class="row">
<div class="image"><img src="images/photo1.jpg" alt="A Lily" />
A lily in the gardens of The Vyne Country House</div>
<div class="image"><img src="images/photo3.jpg" alt="A Fuchsia plant" />
Fuchsia plant in my garden</div>
</div>
<div class="row">
<div class="image"><img src="images/photo2.jpg" alt="A crazy looking Allium flower" />
A crazy looking flower</div>
<div class="image"><img src="images/photo4.jpg" alt="A Robin sitting on a fence" />
This robin has been visiting our garden over the summer.
He is very friendly and doesn't seem to be too worried about sharing the garden with us.</div>
</div>
</div>
每张图⽚被⼀个img标签引⽤,它的标题包含在P元素中,它们均被包含在⼀个类名为“image”的div元素中。同⼀⾏的div被⼀个类名为“row”的div元素包含,整个影像图库被⼀个类名为“grid”的div元素包含。
实现这个布局的CSS代码⼗分简单:
复制代码
代码如下:
.grid {
display: table;
border-spacing: 4px;
}
.row {
display: table-row;
}
.image {
display: table-cell;
width: 240px;
background-color: #000;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论