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

作者: 铁甲万能狗 | 来源:发表于2019-08-04 23:14 被阅读0次

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

    但这里还有一个可选项就是网格响应布局。

    HTML表格

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

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

    改善问题

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


    Kapture-2019-08-04-at-22.02.06.gif

    重新定义的表(=项目集合)

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

    如前所述,由于表数据本质上是一个有序的项集合,因此使用有序列表似ol元素是顺其自然。 此外,由于表通常用于补充文本描述,因此<div>用于表示单元格的属性,因为HTML5没有为此定义适当的标记。 这里的关键是将语义相似的属性表示为<div>的层次结构。 在定义数据表的grid布局方式时将使用此结构。

    <ol class="table-container">
            <!--第一个li是模拟thead-->
            <li class="table-header row">
                <div class="cell sn">#</div>
                <div class="cell username">用户名</div>
                <div class="cell depart">部门</div>
                <div class="cell title">职务</div>
                <div class="cell contact">联系方式</div>
                <div class="cell avatar">照片</div>
            </li>
           <!--第二个li是模拟tbody,并且内部在嵌套一个与外层一样的
                ol有序列表结构,主要实现数据表的上下滚动效果-->
            <li class="table-body">
                <ol class="table-container">
                    <li class="row">
                        <div class="cell sn" data-title="#">1</div>
                        <div class="cell username" data-title="用户名">Jack</div>
                        <div class="cell depart" data-title="部门">品质</div>
                        <div class="cell title" data-title="职务">主任</div>
                        <div class="cell contact" data-title="联系方式">137-1341-0192</div>
                        <div class="cell avatar" data-title="">
                            <img src="/static/images/male.png">
                        </div>
                        .......
                    </li>
                 </ol>
            </li>
        </ol>
    

    如上数据类tbody里的所有<div>元素内的实际数据都是实际数据。

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

    1. 网格模拟的表格的样式轮廓很简洁,对列宽度的定制相对比较灵活,得益于网格的grid-template-columns的属性。

    2. 多层有序列表的相同嵌套,可以实现非常复杂的多列复合报表结构。样式控制相对简单。即便无javascript的参与都能实现。


      这是一种多列复合响应布局的示例
    3. 多浏览支持,目前ie11之后和基于webkit内核的主流浏览器都支持。

    缺点:

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

    css样式设定

    这样的样式还不算简洁的,当然可以进一步简写,当然鉴于这遍是教程。这里写的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元素响应表格设计方案

        本文链接:https://www.haomeiwen.com/subject/mqxtdctx.html