进步博客

纯CSS实现响应式表格

先看DEMO

自从转岗至腾讯云后,项目中接触到大量的数据表格。多列数据表格在空间有限的手机屏幕下,难以完美呈现,需要做响应式处理。本文介绍一种使用纯CSS实现响应式表格的方法。

通常表格中的一行代表一条项目,每列代表项目的一个属性方面(即字段)。在屏幕空间充足的情况下,我们可以将表格的每列都完全显式在屏幕上,但在手机下,每列内容会拥挤不堪,甚至出现横向滚动条,用户快速了解每条项目基本情况的效率会大打折扣。

一种优化方法是:使用media queries监测屏幕viewport小于568px时,让单元格(td)独占一行,每行(tr)相互隔离,如同每条项目为一独立的表格,如下图:

现在每条项目便于阅读了,但表头(th)与对应的单元格(td)隔离开了,单元格的具体意义难以理解。那么,隐藏掉表格的thead,单元格内容右对齐,在每个单元格前面插入对应的表头(th)即可解决这个问题,如下图:

伪元素(:before)结合att()表达式(获取伪元素所依附元素的HTML属性值)可完成此任务。当然,我们首先要对每个单元格(td)元素改造:

样式如下:

table {
    border: 1px solid #ccc;
    width: 100%;
    margin: 0;
    padding: 0;
    border-collapse: collapse;
    border-spacing: 0;
}

table tr {
    border: 1px solid #ddd;
    padding: 5px;
}

table th,
table td {
    padding: 10px;
    text-align: center;
}

table th {
    text-transform: uppercase;
    font-size: 14px;
    letter-spacing: 1px;
}

/* <= 568px */
@media screen and (max-width: 35.5em) {
    table {
        border: 0;
    }
    table thead {
        display: none;
    }
    table tr {
        margin-bottom: 10px;
        display: block;
        border-bottom: 2px solid #ddd;
    }
    table td {
        display: block;
        text-align: right;
        font-size: 13px;
        border-bottom: 1px dotted #ccc;
    }
    table td:last-child {
        border-bottom: 0;
    }
    table td:before {
        content: attr(data-label);
        float: left;
        text-transform: uppercase;
        font-weight: bold;
    }
}

大功告成了吗?某些屏幕阅读器(如OSX 和iOS下voiceOver)可朗读伪类插入的内容,这 是否造成了过度提示,会不会影响屏幕阅读器用户的访问效率。而某些屏幕阅读器与浏览器的组合又不会朗读,如何优化呢?

参考资料:
Responsive Tables in Pure CSS