Open xinglie opened 5 years ago
本项目仅供参考,需要浏览器css支持display:flex,position:sticky等特性
css
display:flex
position:sticky
table
从功能上来讲,行列的数据更适合使用table,所以当您的需求中没有固定表头,固定列时,请直接使用table,模拟table更多的是解决固定表头,固定列等事情。
当数据量多时,我们期望表头或表尾固定,只滚动中间区域,但是<tbody>不能做为滚动容器。如果我们强制改变<tbody>的display使它可以滚动,然后<thead>中的列和<tbody>中的列就对不齐了。
<tbody>
display
<thead>
然后我们可能就要上javascript然后各种同步列的宽度了,然后你会发现解决1个问题会引入3个问题,到最后列可能还会有些许的偏差并没有对齐。
javascript
1
3
这个网上的案例有一些,感兴趣的话可以搜搜看
我们知道css3中position新增了sticky,如果浏览器支持,直接在<thead>上使用position:sticky就完成了表头固定,多好?
css3
position
sticky
chrome曾经支持过<thead>上设置position:sticky,但是后来不知为何又去掉了,然后目前没有浏览器支持<thead>上设置position:sticky,这都什么鬼?具体可以看下caniuse。https://caniuse.com/#search=sticky
chrome
caniuse
网上常见的做法是使用4个表格来完成相应的功能,以ant.design为代表,可以看下它的效果和实现:https://ant.design/components/table-cn/
4
ant.design
这种做法实现起来麻烦,计算的量也不少,在表头固定、首列固定、尾列固定、表尾固定这些需求同时存在的情况下,列对齐需要计算,然后同步。行高需要计算,然后同步,据说ant.design是以中间行为最大高度,然后去同步首列中的行和尾列的行。
做到最后依然可能对不齐,我在ant.design中的表格组件上经常能见到对不齐的bug
bug
做完各种计算后,如果要实现鼠标移上行变色,你会发现css中的hover伪类没法使用,因为表格是分离的,这时候就又需要绑定javascript事件进行模拟实现,这个简直了...
hover
div
该方法仍然需要计算,但计算量少了很多,只需要列宽计算
因为行没有被拆分,所以行高不需要计算对齐,同时可以使用css中的hover伪类实现鼠标移入变色
demo地址 https://xinglie.github.io/magix-table/index.html 项目地址 https://github.com/xinglie/magix-table
由单元格内容自动撑开,最好不要在单元格上写高度,可以在单元格内再套一个div之类的来处理高度。因为整行的单元格并没有分离,所以行高不需要计算,同时可以使用css的hover伪类来处理鼠标移上的背景色。
列宽需要javascript计算,其实也谈不上计算,因为计算宽度的过程可以省去,比如你给每一列都写好了宽度,或使用百分比则不需要计算。
列宽的处理上更重要的是把表格head中的列宽同步给body中的列,列宽没办法自动处理,这一步还是需要javascript来进行同步。
head
body
同时考虑到类似table实际运用,宽度可能是百分比,可能是定值,也可能混用,也可能省略等,以方便为目的,对head中的列宽进行计算后再同步给body中的列
列合并不是问题,因为所有的单元格都在一行上,无非是计算的时候,把合并列的单元格的宽度自成它合并几列的宽度即可
行合并是个大问题,目前并未找到合适的方案,示例中的head中的行合并其实是视觉上的效果,并不是真正意义上的合并。也仅head中的单元格做了视觉上的合并,body中的并没有做,因为该“行合并”方案本质上有很大缺陷,就没再深入去处理。
未来可能使用css中的display:grid来模拟表格,这个方案在合并单元格上有着天然的优势,也许可以用它做出更好的表格
display:grid
当然,还是希望position:sticky能尽早的用在table上,目前虽然像chrome支持在th上使用position:sticky,但是也仅是th上,而且还有bug,期望浏览器赶快完善起来吧。
th
本项目仅供参考,需要浏览器
css
支持display:flex
,position:sticky
等特性为什么模拟
table
table
有哪些问题body不能滚动
当数据量多时,我们期望表头或表尾固定,只滚动中间区域,但是
<tbody>
不能做为滚动容器。如果我们强制改变<tbody>
的display
使它可以滚动,然后<thead>
中的列和<tbody>
中的列就对不齐了。然后我们可能就要上
javascript
然后各种同步列的宽度了,然后你会发现解决1
个问题会引入3
个问题,到最后列可能还会有些许的偏差并没有对齐。这个网上的案例有一些,感兴趣的话可以搜搜看
sticky
我们知道
css3
中position
新增了sticky
,如果浏览器支持,直接在<thead>
上使用position:sticky
就完成了表头固定,多好?chrome
曾经支持过<thead>
上设置position:sticky
,但是后来不知为何又去掉了,然后目前没有浏览器支持<thead>
上设置position:sticky
,这都什么鬼?具体可以看下caniuse
。https://caniuse.com/#search=stickytable
做固定表头,固定列功能网上常见的做法是使用
4
个表格来完成相应的功能,以ant.design
为代表,可以看下它的效果和实现:https://ant.design/components/table-cn/这种做法实现起来麻烦,计算的量也不少,在表头固定、首列固定、尾列固定、表尾固定这些需求同时存在的情况下,列对齐需要计算,然后同步。行高需要计算,然后同步,据说
ant.design
是以中间行为最大高度,然后去同步首列中的行和尾列的行。做到最后依然可能对不齐,我在
ant.design
中的表格组件上经常能见到对不齐的bug
做完各种计算后,如果要实现鼠标移上行变色,你会发现
css
中的hover
伪类没法使用,因为表格是分离的,这时候就又需要绑定javascript
事件进行模拟实现,这个简直了...div
模拟表格该方法仍然需要计算,但计算量少了很多,只需要列宽计算
因为行没有被拆分,所以行高不需要计算对齐,同时可以使用
css
中的hover
伪类实现鼠标移入变色demo地址 https://xinglie.github.io/magix-table/index.html 项目地址 https://github.com/xinglie/magix-table
行高
由单元格内容自动撑开,最好不要在单元格上写高度,可以在单元格内再套一个
div
之类的来处理高度。因为整行的单元格并没有分离,所以行高不需要计算,同时可以使用css
的hover
伪类来处理鼠标移上的背景色。列宽
列宽需要
javascript
计算,其实也谈不上计算,因为计算宽度的过程可以省去,比如你给每一列都写好了宽度,或使用百分比则不需要计算。列宽的处理上更重要的是把表格
head
中的列宽同步给body
中的列,列宽没办法自动处理,这一步还是需要javascript
来进行同步。同时考虑到类似
table
实际运用,宽度可能是百分比,可能是定值,也可能混用,也可能省略等,以方便为目的,对head
中的列宽进行计算后再同步给body
中的列单元格合并
列合并不是问题,因为所有的单元格都在一行上,无非是计算的时候,把合并列的单元格的宽度自成它合并几列的宽度即可
行合并是个大问题,目前并未找到合适的方案,示例中的
head
中的行合并其实是视觉上的效果,并不是真正意义上的合并。也仅head
中的单元格做了视觉上的合并,body
中的并没有做,因为该“行合并”方案本质上有很大缺陷,就没再深入去处理。后续
未来可能使用
css
中的display:grid
来模拟表格,这个方案在合并单元格上有着天然的优势,也许可以用它做出更好的表格当然,还是希望
position:sticky
能尽早的用在table
上,目前虽然像chrome
支持在th
上使用position:sticky
,但是也仅是th
上,而且还有bug
,期望浏览器赶快完善起来吧。