表格 table
出现的很久了,曾经作为风靡一时的布局神器,但随着css层叠样式的各种优势,表格布局基本都已经淡出人们的视线。目前表格基本上的作用就只有用作表格了。但是由于我们对表格了解甚少,在表格上其实是有不少坑的,下面就让我们一起来填填坑。
填坑进行时
单元格宽度无效
这个是非常常见的问题了,简单重现如下:
代码:
<style>
#test1 td {
border:1px solid #333;
}
</style>
<table id="test1">
<tr>
<td width="50px">1</td>
<td width="50px">2223232323232323</td>
<td width="50px"></td>
<td width="50px"></td>
</tr>
<tr>
<td style="width:50px;">1</td>
<td style="width:50px;">2223232323232323</td>
<td style="width:50px;"></td>
<td style="width:50px;"></td>
</tr>
</table>
效果:
显而易见,无论是 w3c 已经不赞成使用的 html 标签上的 width
属性,还是以css形式指定的 width
,所指定的宽度在内容超出时都没有任何效果。
或许你会想到 overflow
这个属性,不过你可是试试,加上它也并没有什么效果。如何解决请看下文的 表格超宽 问题。
表格超宽
除了上面讲到的宽度无效之外,还有一个很常见的问题就是表格的宽度不受限制。
依旧代码说话:
<style>
#test2 {
width:400px;
}
#test2 td,
#test2 th {
border:1px solid #333;
}
</style>
<table id="test2">
<thead>
<tr>
<th style="width:50px;">序号</th>
<th style="width:50px;">名称</th>
<th style="width:300px">详情</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width:50px;">1</td>
<td style="width:50px;">测试</td>
<td style="width:300px;"><img src="http://dummyimage.com/600x300" alt=""></td>
</tr>
</tbody>
</table>
效果如下:
如上代码所示,我们本是想表格宽度为400px,序号和名称各占50px,剩下的详情列宽度为300px。
而实际的效果可能非常令你失望,序号和名称列会被挤得非常窄,详情列的宽度也不是预想的300px,而是表格中当前列最宽的内容的宽度。
前两列被挤窄的也就罢了,你会发现表格的宽度也不是你所指定的 400px。(400px只是此处举例,通常的使用常为表格占容器宽度的100%,出现这种超宽的情况会使得表格超出容器。)
如果你遇到过这些,你肯定觉得表格很坑。
百度一搜这种问题很多,而且大多的答案都不能解决问题。多数答案基本是表格或是单元格宽度由内容决定,让你不要给表格设置宽度,而是给表格单元格内的内容设置宽度。
如单元格宽度无效时,可进行如下改造(本例类似):
代码:
<style>
#test1 td {
border: 1px solid #333;
}
.td-inner {
width:50px;
}
</style>
<table id="test1">
<tr>
<td>
<div class="td-inner">1</div>
</td>
<td>
<div class="td-inner">2223232323232323</div>
</td>
<td>
<div class="td-inner"></div>
</td>
<td>
<div class="td-inner"></div>
</td>
</tr>
</table>
效果
从效果上看,确实达到了预期效果。可是这实际上是治标不治本的伪解决方案,其本质上根本没有解决表格单元和自身宽度无效的问题。
这个问题无解了吗?其实想想都不可能,表格曾经作为一种布局方案,如果存在这么大的坑,如何用来布局?
解决这个问题实际上只要知道一个表格的属性即可,它就是—— table-layout
。
table-layout
的属性值如下表:
值 | 描述 |
---|---|
auto | 默认。列宽度由单元格内容设定。 |
fixed | 列宽由表格宽度和列宽度设定。 |
inherit | 规定应该从父元素继承 table-layout 属性的值。 |
可以看出其默认形式就是自动布局,即由单元格中内容决定。想要我们在单元格或表格上的宽度上生效,只用给表格加上 table-layout:fixed;
即可。
一行代码解决根本问题,而且可以避免无谓的嵌套多层html。
<style>
#test3 {
width:400px;
table-layout: fixed;
}
#test3 td,
#test3 th {
border:1px solid #333;
}
</style>
<table id="test3">
<thead>
<tr>
<th style="width:50px;">序号</th>
<th style="width:50px;">名称</th>
<th style="width:300px">详情</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width:50px;">1</td>
<td style="width:50px;">测试</td>
<td style="width:300px;"><img src="http://dummyimage.com/600x300" alt=""></td>
</tr>
</tbody>
</table>
关于 table-layout
的详细介绍如下:
table相关的巧用
垂直居中
对需要垂直居中的元素加上 display:table-cell;
再配以 vertical-align: middle;
即可使得当前元素像表格中的单元格一样垂直居中。如下所示:
<style>
.test3 {
width:300px;
height: 300px;
border:1px solid #333;
display: table;
}
.test3 > .vertical-middle {
display: table-cell;
text-align: center;
vertical-align: middle;
}
</style>
<div class="test3">
<div class="vertical-middle">
我能垂直居中
</div>
</div>
<div class="test3">
<div class="vertical-middle">
我能垂直居中
我能垂直居中
我能垂直居中
我能垂直居中
我能垂直居中
我能垂直居中
我能垂直居中
我能垂直居中
我能垂直居中
我能垂直居中
我能垂直居中
</div>
</div>
父容器的上设置的宽高度只是为了示意,为其他值依然能够做到垂直居中。
可以看到目标元素上存在 display: table-cell;
其父元素也只有 display: table;
他们之间并没有表格行(即display:table-row;
)的存在,这实际上是因为表格存在 匿名表格元素创建规则 ,即
CSS2.1表格模型中的元素,可能不会全部包含在除HTML之外的文档语言中。这时,那些“丢失”的元素会被模拟出来,从而使得表格模型能够正常工作。所有的表格元素将会自动在自身周围生成所需的匿名table对象,使其符合table/inline-table、table-row、table- cell的三层嵌套关系。
此方式垂直居中优势:
- 支持不定宽高的元素
不足:
- 实际就是把当前元素变成了一个td,不能和绝对定位、浮动同时使用,
margin
无效。
行等高布局
进行水平列表渲染的时候,可能的一种情况就是不同的列表条目有不同的高度。这时候如果使用浮动,则会存在问题,如:
<style>
#test4 {
width:300px;
}
#test4:after {
clear: both;
content: " ";
display: table;
}
#test4>.t4-item {
float: left;
}
</style>
<div id="test4">
<div class="t4-item"><img src="http://dummyimage.com/100x80" alt=""></div>
<div class="t4-item"><img src="http://dummyimage.com/100x110" alt=""></div>
<div class="t4-item"><img src="http://dummyimage.com/100x60" alt=""></div>
<div class="t4-item"><img src="http://dummyimage.com/100x90" alt=""></div>
<div class="t4-item"><img src="http://dummyimage.com/100x30" alt=""></div>
<div class="t4-item"><img src="http://dummyimage.com/100x70" alt=""></div>
</div>
效果如下:
预想的情况应该是前三个一行,后面三个另起一行,直接使用浮动则会出现上面情况,第四个占据一行,后面两个又新起了一行。
仅使用浮动也可以实现等高布局,可以为每个浮动的元素设置一个最小高度,设置值为列表中最高的元素的高度。不过如果高度均无法确定,则仅用浮动无法实现等高布局。
而表格有一个特性就是每行的高度相同,因此等高的可以使用表格相关属性实现。如:
<style>
#test5 >.row{
display: table-row;
}
#test5 .t5-item {
display: table-cell;
vertical-align: top;
}
</style>
<div id="test5">
<div class="row">
<div class="t5-item"><img src="http://dummyimage.com/100x80" alt=""></div>
<div class="t5-item"><img src="http://dummyimage.com/100x110" alt=""></div>
<div class="t5-item"><img src="http://dummyimage.com/100x60" alt=""></div>
</div>
<div class="row">
<div class="t5-item"><img src="http://dummyimage.com/100x90" alt=""></div>
<div class="t5-item"><img src="http://dummyimage.com/100x30" alt=""></div>
<div class="t5-item"><img src="http://dummyimage.com/100x70" alt=""></div>
</div>
</div>
效果:
虽然可以实现效果。但是也有局限性,必须新增一个辅助元素 .row
。
等宽布局
假设有一个水平列表,元素个个数不定,但是无论多少个,要使得列表元素评分容器控件。这时候使用 display:table-cell
。 就非常方便了。
<style>
.test6 {
display: table;
width:500px;
table-layout: fixed;
}
.test6>.t6_item {
display: table-cell;
background: #ccc;
color:#000;
text-align: center;
}
</style>
<div class="test6">
<div class="t6_item">等宽</div>
<div class="t6_item">等宽</div>
</div>
<div class="test6">
<div class="t6_item">等宽</div>
<div class="t6_item">等宽</div>
<div class="t6_item">等宽</div>
</div>
<div class="test6">
<div class="t6_item">等宽</div>
<div class="t6_item">等宽</div>
<div class="t6_item">等宽</div>
<div class="t6_item">等宽</div>
<div class="t6_item">等宽</div>
<div class="t6_item">等宽</div>
</div>
即无论列表有2个、3个6个还是任意个都能使得每个列表平均占据父容器宽度。
这实际是利用了表格中不给单元格指定宽度时,单元格宽度平均分配的特性。
两列布局
这种两列布局如何实现呢? 比较常用的是就是左侧绝对定位,右侧直接用margin-left
推动左侧占据的宽度即可。而实际上使用display: table-cell;
来实现代码量更少。
代码:
<style>
.test7 {
width: 600px;
}
.test7:after {
content: " ";
display: table;
clear: both;
}
.test7>.left {
float: left;
padding: 10px;
}
.test7>.right {
display: table-cell;
width: 2000em;
}
.r-content {
word-break: break-all;
}
</style>
<div class="test7">
<img src="http://dummyimage.com/100x100" alt="" class="left">
<div class="right">
<div class="r-content">sdfsjdfgjdsgfjsdgfjdsgjfgdsjfgdsjfgjdsgfjdsgfjdsgfhdsghfgdshfgdshfgdshfghdghsdgfhdsgfhsdgfhdsgfhdsgfhsdgfhdsgfhdsgfhdsgfhs
7月30日,朱日和训练基地,中共中央总书记、国家主席、中央军委主席习近平检阅部队并发表重要讲话。 这是新中国成立后我军首次以庆祝建军节为主题的盛大阅兵,受阅官兵列阵沙场,以战斗姿态接受检阅。这场场面燃爆的沙场点兵,传递五个重大信号:
第一,沙场点兵,展示的是中国军队的实战能力 在成吉思汗扬鞭跃马的古战场,一支现代化军队的沙场点兵如何更有气势?主要看战力! 虽然这次阅兵主题是庆祝建军节,但沙场特色非常浓厚:铁流滚滚,风尘仆仆。这次阅兵打破广场阅兵惯例,所有曲目都是播放录音,不安排军乐团、合唱队,也不搞群众性观摩。标兵不穿礼服而是穿迷彩服,就位方式也不是以往的踢正步,而是采用跑步形式,更添实战味。女兵以战斗员身份出现,多个方队集结机动也完全是实战化。值得注意的是,领导人也着野战军服。
</div>
</div>
</div>
效果
如果你觉得什么东西坑比较多,那是因为你不了解它,学起来吧!
Last modified on 2017-07-31