`
小吴的电脑
  • 浏览: 5413 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
最近访客 更多访客>>
社区版块
存档分类
最新评论

基于display:table的CSS布局

阅读更多
转自:http://ued.alipay.com/2008/10/%E5%9F%BA%E4%BA%8Edisplaytable%E7%9A%84css%E5%B8%83%E5%B1%80/

应原书编辑要求,先在文章顶部给出链接:《Everything You Know About CSS Is Wrong》
http://www.sitepoint.com/books/csswrong1/
这本书是10月发行的新书,为了避免版权纠纷,如要转载本文请保留以上链接,并遵循该CC2.5协议。

从digital-web的首页上看到一个标题党《Everything You Know About CSS Is Wrong》,被雷过之后仔细看了下原文,发现了一种新的CSS布局思路(其实就是详细介绍了display:table属性)。在IE6仍是王道的时代谈这种技术为时过早,全当是练习英文翻译贴出来给大家分享下,欢迎大家指点不足之处。

—————————以下是中文翻译——————————–

当IE8发布时,它将支持很多新的CSS display属性值,包括与表格相关的属性值:table、table-row和table-cell,它也是最后一款支持这些属性值的主流浏览器。它标志着复杂CSS布局技术的结束,同时也给了HTML表格布局致命一击。最终,使用CSS布局来制作出类似于table布局的栅格将会变得十分迅速和简单。
网页元素应用上那些与表格相关的display属性值后,能够模仿出与表格相同的特性。我将会在该文中给大家演示这种方法给CSS布局带来的巨大影响。

使用CSS表格

CSS表格能够解决所有那些我们在使用绝对定位和浮动定位进行多列布局时所遇到的问题。例如,“display:table;”的CSS声明能够让一个HTML元素和它的子节点像table元素一样。使用基于表格的CSS布局,使我们能够轻松定义一个单元格的边界、背景等样式,而不会产生因为使用了table那样的制表标签所导致的语义化问题。
在深入了解这种方法之前,让我们先来写份HTML文档实例:

1
2
3
4
5
6
7
<div id="wrapper">
<div id="main">
<div id="nav">? navigation column content…</div>
<div id="extras">? news headlines column content…</div>
<div id="content">? main article content…</div>
</div>
</div>
这份HTML源代码满足了内容呈现方面的要求。先是导航栏,然后是附加栏,最后是内容栏。
我们同样需要将以下CSS样式应用上去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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样例,而它们将表现出相同的视觉效果。



首先,以下是能够生成三列布局样例的其中一份:

1
2
3
4
5
6
7
<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样式也非常简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.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元素试试:

1
2
3
4
5
<div class="row">
<div class="cell">CELL A</div>
<div class="cell">CELL B</div>
<div class="cell">CELL C</div>
</div>
即使上面的代码遗漏了声明表格的那一行,浏览器仍将创建一个匿名的表格行。我们还可以移除更多的代码:

1
2
3
<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;”的元素而结束这一行。以下是相关的代码样例:

1
2
3
4
<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中的所有元素。
请看以下代码:

1
2
3
<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表格很快就能搞定。



以下是我们这个影像图库的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<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代码十分简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.grid {
display: table;
border-spacing: 4px;
}
.row {
display: table-row;
}
.image {
display: table-cell;
width: 240px;
background-color: #000;
border: 8px solid #000;
vertical-align: top;
text-align: center;
}
.image p {
color: #fff;
font-size: 85%;
text-align: left;
padding-top: 8px;
}
以上CSS代码简明易懂,可能你还注意到了我们是怎样通过border-spacing属性来控制单元格图像之间的距离的。制作一张栅格布局变得再简单不过了,同时我们还可以避免那些使用float元素实现等高布局所带来的麻烦。

将理论运用于实战

本文展示了CSS display属性中表格相关属性值的基础用法,开发者不断努力通过CSS来实现可靠的基础栅格布局,而这种方法最终会使其变得更简单。我们已经对CSS表格布局做了一个简明易懂的介绍,研究了display属性中各种表格相关的属性值,找出了匿名表格元素的本质,另外还发现了一些其它有用的CSS表格属性。
接下来的一步就看你了,你已经了解到使用CSS表格制作栅格布局的潜力,带着好奇心去自己尝试下吧!运用从本文学到的知识,你可以开始实践你自己的CSS表格布局并发明一些新的技术。

使用总结:

注:我使用display:table标签显示集合中数据,可此标签无height属性,可设置class class为table,增加如下代码即可。

.table {
display: table-cell;
width: 100px;
height: 100px;
}

或使用table,设置tr高度也可实现,但此方法是设置整个tr所占高度,并非是table 高度,table高度还是会随着数据的多少而变化。上一种方法table高度不会变化,数据少的时候,列名所在行+数据行撑起整个table。
分享到:
评论

相关推荐

    基于display:table的CSS布局让HTML元素和像table一样

    最终,使用CSS布局来制作出类似于table布局的栅格将会变得十分迅速和简单。 网页元素应用上那些与表格相关的display属性值后,能够模仿出与表格相同的特性。我将会在该文中给大家演示这种方法给CSS布局带来的巨大...

    CSS display属性的table表格布局

    项目改造中遇到DIV+CSS实现的table,新需求需要在表格使用单元格合并,网上调查返现CSS display:table实现的table表格,没有单元格的属性和样式,经过一番思考,曲折现实了单元格的合并,即采用正行嵌套一个单独的...

    display:table-cell实现兼容性的两栏自适应布局实现代码

    大美女一枚 来自上海 签名:想找个保鲜盒把你给我的那些感动都装起来。当你让我伤心的时候就拿出来回味一下。 微博:坐在办公室,只听轰隆隆几声巨响,晴天也能打雷吗?...} .content{display:table-cell; *displ

    CSS属性display:inline-block用法深入理解

    本文向大家描述一下CSS属性display:inline-block的用法,在使用CSS实现表现的时候,会经常接触到display:inline-block这一属性;可以将对象呈递为内联对象,但是对象的内容作为块对象呈递,旁边的内联对象会被呈递在...

    CSS布局实例:上中下三行,中间自适应

     对于非ie内核浏览器,通过设定display:table、display:table-row和display:table-cell来模拟表格的表现形式。 最外层#box { display:table; },高度100%,其子层#header/#main/#footer为{ display:table-row; },...

    css布局实例:网页布局的方法

    许多网页设计师都喜欢,将两个或者... 其实有个简单的方法,使用display:table, display:table-row and display:table-cell 就可以实现,而且高度小的容器会自适应那些高度相对较高的,但是IE不支持这个属性,我们先不

    深入解析CSS的display:inline-block属性的使用

    display:inline-block感觉与display:table-cell有些相似,例如对内部元素的包裹性。但是,由于display:inline-block最大的不同就是其没有父元素的匿名包裹特性,这使得display:inline-block属性的使用非常自由,可与...

    div+css table布局实现代码

    是根据我对文章的理解意译的,你就别挑哪里翻译的不对了,我的目的只是传达这个CSS技巧 许多网页设计师都喜欢,将两个或者多个容器等高的并排放置,并在里面展示每个容器的内容,就象经典表格布局中的单元格控制几个...

    CSS中的table-cell属性使用实例教程

    先让我们来研究下table,那些年曾经使用的table布局为何如此辉煌荡漾呢?她的特点有哪些呢?抛弃table的兼容性、seo、加载等与本文无关的内容不谈,只看属性,那么就两个特点:1.同行等高。2.宽度自动调节。那么...

    DIV+CSS之弹性盒模型布局

    这是我自己项目总结的一些布局方法,基于DIV+CSS实现的一种弹性盒模型布局,主要利用display:table-cell;这一属性来实现,兼容良好,可扩展性也比较强。适用于做前端重构、架构的童鞋。

    css之display属性之inline-block布局实现详解

    CSS display 属性 注释:如果规定了 !DOCTYPE,则 Internet Explorer 8 (以及更高版本)支持属性值 "inline-table"、"run-in"、"table"、"table-caption"、"table-cell"、"table-column"、"table-column-group"、...

    CSS多列布局实现方法大全

    摘要: 多列布局在网站应用中也是经常见到的,今天就分享4中多列布局。 display:table 复制代码代码如下:&lt;style&gt; .table { width: auto; min-width: 1000px; margin: 0 auto; padding: 0; display:table; } ....

    CSS布局带来的巨大影响:CSS display属性值

    我将会在该文中给大家演示这种方法给CSS布局带来的巨大影响。 应原书编辑要求,先在文章顶部给出链接:《Everything You Know About CSS Is Wrong》http://www.sitepoint.com/books/csswrong1/ 这本书是10月发行的...

    CSS让高度不确定图片垂直居中的几种技巧

    方法一 将外部容器的显示模式设置成display:table,这个设置的意思不用多说了吧… img标签外部再嵌套一个span标签,并设置span的显示模式为display:table-cell,这样span内部的内容就相当于表格,可以很方便的使用...

    CSS布局之如何实现居中布局

    1. 父级容器设置成表格,子级设为行内元素。 适合子级内容为文本展示。... display: table-cell; /* 转变成表格 */ text-align: center; /* 水平 */ vertical-align: middle; /* 垂直 */ } #child {

    css入门笔记

    ex:img,table 注意:大部分行内元素不能修改 span,a,i,u,b,s 3.溢出处理 当内容多,元素区域小的时候,会产生溢出的效果,默认都是纵向溢出 属性:overflow,overflow-x,overflow-y 取值: 1.visible 可见的...

    gridzilla:一个{显示

    更具体地说,一个基于{display: table}的网格系统旨在减轻基于float的网格的痛苦。 如果您需要较旧的浏览器支持,那么您可能需要浮动。 如果您正在设计一个现代网站,那么请享受 CSS 表提供的更自然的流程。 想知道...

Global site tag (gtag.js) - Google Analytics