grid和ol元素响应表格设计方案

弹性表格布局不是新主题,并且已经提出了许多解决方案。 “响应表数据综述”由Chris Coyier于2012年首次发布,事情总结得很整齐(包括2018年的更新)。原文连接:https://css-tricks.com/responsive-data-table-roundup/
还有以下一篇文章
Really Responsive Tables using CSS3 Flexbox”。

前文提要:

这里还有一个可选项就是网格响应布局。这不是网格的基础教程,是一个实际的演示案例,对网格布局不熟悉的可以参考国内沅一峰的相关网格文章,本文最后有传送门...谢谢。

HTML表格

HTML中的传统的table是一种布局格式,用于通过行和列矩阵显示项目集合。 项按行布局,在相同列中具有相同的数据属性,行通常按一个或多个可排序属性排序。使用table时,数据的布局生硬地编码为行和列(例如和)。通常这种布局方式在桌面浏览器中可以正常地陈列数据,但实际上,当你需要在手机浏览器上容纳相同行数的数据表时,往往和发生各行单元格的宽度和列标题单元格宽度不一致的情况,尤其当你的表格是表头固定,表体可以上下滚动的flex表格布局。在手机端浏览器更是如此

grid和ol元素响应表格设计方案_第1张图片
各行单元格的宽度和列标题单元格宽度不一致的情况

造成这种原因主要是来自单元格的字符串长度不确定性而导致的。你可能会做的是固定每个flex单元格的宽度或者对超出单元格宽度的字符串进行类似overflow:hidden的样式设置,或者字体换行等。但那些是非常不好的设置体现。

改善问题

先见一组预览图,在本文中,我使用CSS网格布局模块和CSS属性在没有Javascript的情况下根据屏幕的宽度来模拟一个表格,并且在小屏幕下的行记录切换为卡片模式。主要是规避手机端的宽度过小的问题,充分利用好手机屏幕的高度,容乃足够的信息。如下图效果。


grid和ol元素响应表格设计方案_第2张图片
Kapture-2019-08-04-at-22.02.06.gif

重新定义的表

让我们首先重新定义表格数据应该如何用HTML表示。这里为什么不用回table元素的flex方案呢?我不想废话,如果你要实现flex的布局方案并且有些数据列是多个单元格复合的话,使用table的flex方案写出的html模版会比单纯的ol和div的网格方案会异常的复杂的多。

如前所述,由于表数据本质上是一个有序的项集合,因此使用有序列表似ol元素是顺其自然。 此外,由于表通常用于补充文本描述,因此

用于表示单元格的属性,因为HTML5没有为此定义适当的标记。 这里的关键是将语义相似的属性表示为
的层次结构。 在定义数据表的grid布局方式时将使用此结构。

  1. #
    用户名
    部门
    职务
    联系方式
    照片
    1. 1
      Jack
      品质
      主任
      137-1341-0192
      .......

如上数据类tbody里的所有

元素内的实际数据都是实际数据。

使用ol有序列表+grid布局方案的优点

  1. 网格模拟的表格的样式轮廓很简洁,对列宽度的定制相对比较灵活,得益于网格的grid-template-columns的属性。
  2. 只需在不同的media screen语句中,在相邻的两个li元素之间的,可以实现非常复杂的多列复合报表结构。样式控制相对简单。即便无javascript的参与都能实现。


    grid和ol元素响应表格设计方案_第3张图片
    多列复合的响应布局,主要用一个同一个css 的class样式的div子列包裹在同样class样式的父div中

然后是核心的多列复合的网格css样式代码(关于多列复合的响应布局可能需要另外独立写一文)

    .cell-container{
        display: grid;
        grid-template-columns: repeat(auto-fit,minmax(var(--column-width-min),1fr));
    }
grid和ol元素响应表格设计方案_第4张图片
这是一种多列复合响应布局的示例
  1. 多浏览器支持,目前ie11之后和基于webkit内核的主流浏览器都支持。

缺点:

模拟单元格 div需要过多相同的自定义属性,有些冗余的感觉。

表头固定,表体上下滚动的通用样式

这样的样式还不算简洁的,当然可以进一步简写,当然鉴于这遍是教程。这里写的css略有冗余。

ol.table-container{
    list-style: none;
    padding:0;
    margin: 0;
    width:450px;
}

ol.table-container * {
    box-sizing: border-box;
}

.table-container >.row{
    display: grid;
    grid-template-columns: 3em 5em 4em 4em 9em 3em;
    border-top:1px solid #ccc;
    border-right: 1px solid #ccc;
}

.contact{
    grid-column: span 2;
}

.table-header{
    background-color: blanchedalmond;
    border-bottom: 1px solid #ccc;
}
.table-header >.cell{
/*     border-top:1px solid #ccc; */
    border-left:1px solid #ccc;
    text-align: center;
}


.table-body{
    height: 200px;
    overflow-y:auto;
    border-bottom:1px solid #ccc;
}
.table-body > ol > li >.cell{
    text-align: center;
    border-left: 1px solid #ccc;
}

.table-header >.cell:last-child,
.table-body > .table-container >.row >.cell:last-child{
    display: none;
}


@media screen and (max-width:460px){
    
    ol.table-container{
        width: 95%;
        height: 450px;
        overflow-y: auto;
    }
    
    .table-header.row{
        display: none;
    }
    
    .table-body{
        height: 100%;
        overflow:hidden;
    }
    
    
    .table-body >.table-container > .row {
        display: grid;
        grid-template-columns: 1fr;
        background-color: blanchedalmond;
        border:1px solid #ccc;
        margin-bottom: 15px;
        border-radius: 15px;
        padding:15px;
        box-shadow: 10px 10px 10px -5px #ccc;
        transition: all .5s ease-in;
        line-height: 1.2em;
    }
    
    .row{
        width:95%;
        min-width: 326px;
    }
    
    .table-header >.cell:last-child,
        .table-body > .table-container >.row >.cell:last-child{
        display: inline-flex;
    }
    
    
    .contact{
        grid-column: span 1;
    }
    
    .table-body > .table-container > .row > .cell:before{
        content: attr(data-title);
        text-align: left;
    }

    .table-body > .table-container > .row >.cell{
        display: grid;
        grid-template-columns:4em 9em .8fr;
        padding-left:8px;
        grid-gap: 5px;
        justify-items: left;
        border:1px s÷olid #ccc;
    }
    
    .table-body >.table-container > .row > .avatar{
        grid-row:1 / 6;
        grid-column: 2 / 3;
        align-items: center;
    }
    
    .table-body > .table-container >.row:hover{
        background-color: #ffe066;
        box-shadow: 10px 10px 10px -2px #999;
    }   
}

这里的基本思想是将项目的所有属性显示为普通表,显示宽度允许。 这种布局可以看到尽可能多的项目(行)。table-body里的ol的class样式是二次嵌套使用,虽然略有冗余,但整体来说非常简洁。

卡片样式主要通过隐藏表头,和重置二层嵌套的ol有序表的网格结构实现。

网格参考文章:
http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html

你可能感兴趣的:(grid和ol元素响应表格设计方案)