在讲模拟表格前,先来谈谈表格使用的优势和劣势,然后决定要不要去模拟表格。
表格的优势:
a.自动适配宽度:表格的优势主要体现在表格的自动适配方面,一般数据长度比较统一的情况下,不设置单元格宽度,单元格会根据其内容自动适配宽度。
b.不定高垂直居中:一般垂直居中设置元素高度和行高相等就能解决,但是在高度变化时,css无法动态设置行高,表格的 vertical-align : middle;能很好的解决这类需求。
表格的劣势
a.显示:如果单元格数据出现纯数字、超长纯字母超出单元格宽度,超出长度隐藏溢出部分显示“...”等,设置的宽度就失效了,该单元格就会压缩其他单元格,显示效果是不可控的。
b.加载速度:Table要比其它html标记占更多的字节,占用更多的服务器流量资源,延缓下载速度,也会阻挡浏览器渲染引擎的渲染顺序,影响加载速度。
c.布局可维护性查:使用表格布局的组件,结构变化时很难维护,基本要重新修改结构,通过css基本无法达到预期效果。
div模拟表格
问题一:超出的边框线宽度 单元格数* (左边框宽度 + 右边边框宽度)px
要做到自适应,势必需要单元格的宽度使用百分比,但是边框线使用百分比,显然是不可取的,预留边框宽度为固定像素,那么所有单元格宽度加起来为100%时必然宽度超过单元格边框和 。
解决方案:使用margin为负数来抵消边框宽度,设置单元格的总和为100%即可。
margin-left: -(border-left-width);margin-right: -(border-right-width);
问题二:单元格高度无法根据最大高度单元格适配
单元格高度小于最高单元格时,单元格的高度不会随着最大高度适配,当然这种问题对于需要溢出显示“...”来并不存在,对于多行显示就是必须解决的问题。
解决方案:使用盒模型来撑开元素,设置底部外边距为一个比较大的负数值,确保高度可以达到最大单元格高度,然后使用同样数值的正数内边距抵消外边距,单元格外父级元素溢出隐藏。
.table-tr{
overflow: hidden;
}
.table-th, .table-td {
padding-bottom: 999px;
margin-bottom: -999px;
}
然后就是边框线闭合,这个缺哪里就补哪里就好。
表头表身单元格对齐,表身出滚动条
表头表身分离势必是两块结构,表身多出个滚动条必然会导致表头表身在出现或不出现滚动条的一种情况下无法对齐,滚动条占当前元素宽度,使用盒模型无法解决滚动条宽度的问题;使用绝对定位可以解决滚动条宽度问题,但是绝对定位脱离文档流,无法检测什么时候出现滚动条。
解决方案一:Css3 calc()设置宽度,默认出滚动条
设置表头宽度: (17px为预留滚动条像素,你可以转化为rem)
width: calc(100% - 17px);
表身默认出现滚动条,这样不用做任何js处理就可以达到预期效果,但是滚动条莫名的出现在那里,用户体验不是很友好。
解决方案二:固定宽度
设置表头和表内容块的宽度(rem)相同,表身宽度为表头宽度加上17px,可以完美解决对齐问题,但是要想效果更好必须在不同屏幕下去修改html字体来调整
解决方案三:根据数据条数动态控制表内容块宽度(单元格单行数据显示)
这种方法有局限性,必须要求单元格的高度要统一,以便判断数据超过多少条时需要设置表内容块宽度。如果单元格高度确定的情况下,只需要设置表内容块宽度跟表头宽度相同即可
width: calc(100% - 17px);
下附方案代码 (注:一下方法无法垂直居中,最好的方式是单行显示,溢出显示“...”)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
html{
font-size: 100px;
}
*{
margin:0;
padding:0;
font-size: 0.14rem;
}
.div-table{
width: 80%;
margin: 0.5rem auto 0;
}
.table-tr{
overflow: hidden;
border: 1px solid #bfbfbf;
border-top:0;
}
.table-title{
width: calc(100% - 17px) ;
border-top: 1px solid #bfbfbf;
}
.table-body{
width: 100%;
max-height: 5rem;
min-height: 1.5rem;
overflow-x: hidden;
overflow-y: scroll;
}
.table-th, .table-td {
float: left;
width: 10%;
border-right: 1px solid #bfbfbf;
margin-right: -1px; /* 抵消右边框宽度 */
min-height: .3rem; /* 防止内容为空时缺失 */
line-height: .3rem;
padding-bottom: 999px;
margin-bottom: -999px;
}
.table-th span, .table-td span{
display: block;
padding: 0 0.05rem;
}
</style>
</head>
<body>
<div class="div-table">
<!-- 表头 -->
<div class="table-title">
<div class="table-tr">
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
<div class="table-th"><span>标题1</span></div>
</div>
</div>
<!-- 表身 -->
<div class="table-body">
<!-- 表内容块 -->
<div class="table-content">
<div class="table-tr">
<div class="table-td"><span>内容1</span></div>
<div class="table-td"><span>内容1</span></div>
<div class="table-td"><span>内容1</span></div>
<div class="table-td"><span>内容1</span></div>
<div class="table-td"><span>内容1</span></div>
<div class="table-td"><span>内容1</span></div>
<div class="table-td"><span>内容1</span></div>
<div class="table-td"><span>内容1</span></div>
<div class="table-td"><span>内容1</span></div>
<div class="table-th"><span>内容1</span></div>
</div>
</div>
</div>
</div>
</body>
</html>