之前做页面都没有画表格的经历, 最近工作中有接触到, 刚好补了一下这方面的知识
结构
一个较完整的表格结构如下
|
|
caption
是表格的标题
thead
里放的是表格的头, 一个头对应一个th
tbody
里放的是表格的数据, 一条数据对应一个td
th
与td
都应该在tr
内, 一个tr
就是一行
样式
- 边框
需要同时设置th/td的边框, 同时还要设置table的边框折叠
|
|
table的html属性也有border
|
|
border
属性同时设置了td/th的边框宽度, 但缺点是不能设置边框颜色及边框线条样式, 所以还是使用css来设置边框更好
border-spacing
属性可以设置单元格的边框之间的间距, 但需要border-collapse
属性为separate
时才生效. 一般较少使用
- 文字
文字水平居中使用 text-align: center;
文字垂直居中使用 vertical-align: middle;
Chrome下默认是垂直居中的
如果限制了单元格的宽度, 此时需要文字换行, 可以使用 word-break: break-all;
如果感觉文字太靠近边框, 可以对td/th设置内衬 padding: 2px 5px;
如果改变标题的位置, 需要对table设置 caption-side: top;
或 caption-side: bottom;
Chrome下的默认值是top
- 跨行与跨列
跨行需要用到属性rowspan
, 跨列需要用到属性colspan
, 下面是简单的示例
See the Pen table-with-cross-row-col by levy (@levy9527) on CodePen.
- 布局算法
|
|
二者有以下区别:
- automatic时, 每一列的宽度是自动计算的, 由该列中最宽的内容决定; fixed时, 每一列的宽度可以用width单独设置
- 前者需要需要接受所有内容后, 才能确定表格布局, 耗时较多; 后者在接受到第一行表格内容时, 即可确定表格布局, 耗时较少
实践
- 多列表格
表格有很多列时, 则宽度会很大, 如果table的父元素是body, 则水平滚动表格时body也会一起动, 尤其是手机端, 体验非常不好
解决方案是, 给table添加套一个父元素, 则可以只滚动表格, 不滚动页面的其他内容
|
|
|
|
- 固定列
表格的前几列在水平滚动时固定, 我的思路是这样的:
- 把原本一个表格拆分成两个, 一个是拥有固定列的(以下称为固定表格fixedTable), 一个是正常的表格, 可以横向滚动(下面称为滚动表格scrollTable)
- 固定列其实可以看成表格固定于视窗, 则前一个表格的
position
应设置为fixed
- 因为固定表格不在文档流中, 则正常表格应设置
position
为relative
, 使它可以产生偏移, 使得两个表格拼接看起来像是一个表格
具体看代码
See the Pen YpmWBg by levy (@levy9527) on CodePen.
如果固定列是动态的, 则需要元素生成后取得固定表格的宽度, 再设置滚动表格的偏移, 示例代码如下:
|
|
如果单元格的内容也是动态的, 且单元格限制了宽度, 则文字过多时, 会产生换行, 则滚动表格的表头的高度也会变化, 需要调整固定表格的表头高度
|
|
实践表明, 这种方案并不完善, 因为以下两种情况:
- 表格行过多
表格有很多行时, 表格的高度超过视窗, 则需要垂直滚动才能看到下面的内容. 但因固定表格position
为fixed
, 无论怎么滚动, 固定表格下面的行都是看不见的, 因此还需要监听body的滚动事件, 动态修改固定表格的垂直偏移
|
|
- 移动端横屏显示
移动端还有横屏显示的需求, 则监听到手机横屏时, 需要重新调整固定表格的偏移. 至于事件, 最简单的是onresize
|
|
因为每一次滚动都设置一下元素的偏移, 则每一次都会触发reflow, 极其影响性能, 滚动时可明显看出固定表格在上下”漂移”
另外, 在写了css的基础上, 还要写这么多的js代码来应对几种情况, 因此我觉得此方案并非最佳方案, 尤其不推荐在移动端使用