使用CSS table来布局

现在已经很少有人会使用table来设计网页的布局,但是table真的过时了吗?不然!例如,在很常见的一个2列的布局中,左边我们想放一个导航菜单,右边放置正文内容,然后顶上放置一个header,页面最下方放置一个footer,这应该是一个很常见的页面布局方式。

这个时候,我们希望中间的siderbar跟正文内容都有相同的高度,顶着上面的header与下面的footer,该怎么办呢?

带着这个疑问,我将介绍css中的display属性table,table-cell,table-row,table-row-group,table-header-group,table-footer-group,table-caption,table-column,table-column-group。我想大家肯定对display:block,display:inline相当熟悉了,但是在这儿我还是想啰嗦一下对display熟悉的理解。

display属性会定义标签的盒子模型,每一个标签都有自己的默认盒子模型,例如div得默认盒子模型为block,span的默认盒子模型为inline,li的默认盒子模型为list-item。每一种盒子模型都有一些默认特征,例如block模型会默认独占父元素的宽度,当然,我们也可以设置它的宽度。但是inline模型则跟它相比有很大区别,inline元素会根据其内容自动调整宽高,因为就算我们显式设置其宽高也没用,正因为如此,inline元素一般不会独占父元素的宽度。

那么回到主题,当display属性为table,或table-*时,对应的元素会有什么样的特征呢?我们都知道table标签,它可以设置背景,边框,可以定义里面每行的高度,可以定义每列的宽度。可以直观理解当一个标签的display属性设置为table后,它就具有table标签的一些默认特征。那我们会问:这样的话跟直接使用table标签有什么区别呢?这就涉及到一个样式与数据分离的原则了,在HTML中我们应该尽量不要包含样式的信息,它只是用来定义网页的基本结构,元素之间的逻辑位置关系,以及所包含的信息,所以后来都推荐使用XHTML,也许有这方面的考虑吧。而CSS样式则用来告诉浏览器应该怎样展示HTML。如果直接用table,table定义的是一个语义结构,它除了会把数据用表格显示,并且指示这个地方就是一个表格,可能会在可访问性上造成歧义。

另外如果想调整布局也比较困难。另外,难道说我们就要彻底摒弃table标签吗?当然也不是!例如我们要呈现一些数据表,那还是用table非常合适的。

下面是一个用display=table布局的范例:


<nav>
	<section class="command-list">
	<section class="command-item"><span>Home</span></section>
	<section class="command-item"><span>Archive</span></section>
	<section class="command-item"><span>Download</span></section>
	<section class="command-item"><span>Leisure</span></section>
	</section>
</nav>
.command-list {
   display: table;
   border-spacing: 10px;
   table-layout: fixed;
}
.command-item {
   display: table-cell;
   border-radius: 10px;
   background-color: #a9ed8c;
   text-align: center;
   width: 200px;
   line-height: 2em;
   vertical-align: middle;
}

我们知道table, head, tr, td, footer都有严格的层次关系,那么使用display属性时会不会有这方面的限制呢?没有。原因是浏览器会自动创建匿名元素。例如在上面的例子中我们直接让子元素的display属性值为table-cell,这个时候,浏览器在呈现时会自动把这些拥有table-cell属性值的子元素依次添加到一个匿名的元素中,该元素的display属性值为table-row。

如果有如下的示例代码,那浏览器会怎么显示呢?
<div class="cell">cell1</div>
<div class="cell">cell2</div>
<div class="cell">cell3</div>
<div>cell4</div>
这个时候,会创建两个有父子关系的匿名元素,子元素有table-row属性值,父元素有table属性值.注意,cell4因为没有table-cell属性值,所以它不会被包含在匿名的table-row元素中。
另外,还有些相关的CSS属性:
table-layout 定义table layout算法
  • auto - 列宽由cell中不可断开(unbreakable)的内容的最大宽度觉得; 缺点是比较慢,因为它要读取table中所有的内容才能确定列宽

  • fixed - 水平宽度只由table的宽度和列宽决定,而不是cell中的内容; 性能比较好, 浏览器只要碰到第一行就能决定table怎么显示了
  • inherit - 属性值继承至父元素

border-collapse:定义table的边框是否折叠成一个边框
  • collapse - 边框尽量折叠,border-spacing和empty-cells属性值被忽略
  • separate - 边框分开,border-spacing和empty-cells属性值不被忽略
  • inherit - 属性值继承至父元素
在本人最开头提的那个问题怎么解决呢?如下是利用css table的解决办法:


            <section class="content-container-sample">
               <section class="left-sidebar">
                   <ul>
                       <li>Message In Site</li>
                       <li>Forum</li>
                       <li>Blog</li>
                       <li>Ask Question</li>
                   </ul>
               </section>
               <section class="right-content">
                  <blockquote >
                     <p>Perhaps you’re feeling slightly uncomfortable about the example we’ve just seen—after all, haven’t web standards advocates like myself been insisting for years that you shouldn’t be using tables for layout?</p>
                  </blockquote>
                   <q>
                           Perhaps you’re feeling slightly uncomfortable about the example we’ve just seen—after all, haven’t web standards advocates like myself been insisting for years that you shouldn’t be using tables for layout?
                  </q>
               </section>
            </section>
.content-container-sample {
   display: table;
   border-collapse: collapse;
   width: 80%;
   margin:0 auto;
}
.left-sidebar {
   display: table-cell;
   width: 25%;
   background-color: #e0e0e0;
}
.left-sidebar > ul {
	list-style-type:none;	
}
.left-sidebar > ul > li {
	margin-bottom:15px;
}
.right-content {
   display: table-cell;
   width: 75%;
   height: 500px;
   background: -moz-linear-gradient(45deg, #ab9898, #f3abab);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值