将表格行分成多行(响应式布局)

Posted

技术标签:

【中文标题】将表格行分成多行(响应式布局)【英文标题】:Break a table row into multiple line (responsive layout) 【发布时间】:2014-10-13 20:00:43 【问题描述】:

我有一个列出项目的网页。默认模板为此使用了一个表格,我觉得这非常合适。然而,在此表中,有一列包含的文本比其他列多得多:

虽然在大屏幕上可以使用,但在小屏幕上阅读却很烦人:

为了更好地利用可用空间,我只能想到一个使用 div 的假表布局。我做了一个原型,使用引导网格布局,在大屏幕上看起来像一个表格行,但在小屏幕和超小屏幕上有不同的布局:

虽然通过使用全宽提高了文本的可读性,但我不能再使用我为表格提供的实用程序,并且它以微妙的方式破坏了用户体验。例如,我使用了一个很好的脚本,可以在客户端进行排序。但这仅适用于真实的桌子。 (另外,真表和假表之间存在细微的不一致和视觉差异)

有什么方法可以将表格行重新格式化为类似于上一张图片中的多行容器?

仅供参考:我在服务器上使用 jquery 2.1.1、Bootstrap 3.2.0.1 作为 GUI 框架和 asp.net MVC。

Bootply 在这里:http://www.bootply.com/pRehwTai4G

编辑:如果不够清楚:我想保留<tr><td> 标签,但它们的样式类似于div。我不想用 div 替换表格。

【问题讨论】:

如果你发布一个有问题的 bootply,我有一些想法;但我不能肯定地说。 这个怎么样:bootply.com/kA1JWPSFSz -- 你需要调整 CSS,但是这个插件很不错 【参考方案1】:

感谢 Pete,我使用了您的解决方案并稍作修改。 (使用类 'br' 打破一行并继续使用 TD。)

<style>
table, th, td 
border: 1px solid black;
border-collapse: collapse;

.calculator br display:none;width:0; 
.calculator tr td.br display:none 

@media all and (max-width:768px) 
.calculator tr display: table;width:100%; 
.calculator td width:50%;           
.calculator th width:50%;
.calculator tr td.br display:table-row; 
.calculator tr th.br display:table-row;             

</style>


<table class="calculator" style="width:100%">
  <tr>
<th>Firstname a</th><th>Lastname</th>
<th class="br">Age</th>
  </tr>
  <tr>
    <td>Jilldfs fds</td><td>Smith</td><td class="br"></td><td>50</td><td>50</td>
  </tr>
  <tr>
    <td>Eve</td><td>Jackson</td><td class="br"></td><td>94</td><td>94</td>
  </tr>
</table>

【讨论】:

【参考方案2】:

只需几行 css 就可以做到这一点...

    @media all and (max-width:768px) 
        .calculator tr     display: table;  width:100%;                   
        .calculator td     display: table-row;            
    

.calculator 是用于表格的类:

<table class="calculator">

我使用它来快速更改我用于计算器输入的表格,以便在移动设备/桌面设备之间查看时更智能的外观设计:live example here 尽管最好通过移动设备和桌面设备并排查看差异(并非全部我的移动脚本是交付给桌面浏览器的,所以如果你纯粹通过桌面浏览器查看并最小化,整体设计可能看起来很奇怪,但单元格会变成行等来说明)。

此外,您可以在单元格中添加跨度/标签等并制作此内容

display:table-cell;

如果您愿意,可以将表格设置为块,这种方法更加轻量级并且不再需要使用 javascript

【讨论】:

最佳答案在这里! 在尝试(但失败)使用 bootstrap 和 flexbox 解决响应式表格的问题后,这是拯救我的解决方案 还注意到,当您使用引导程序时,设置 display: table-row 会使 缩小到内容大小。如果你想要一个全宽 td(如一行)显示:block 为我工作 引导效果将归因于 css 设置,如果需要,您可以通过向表应用额外的类并以这种方式定位来覆盖。 绝妙的解决方案! 【参考方案3】:

如果您从表中删除thead 标记并将th 绑定到tbody 中,那么您可以使用以下带有css 代码的jquery 来获取响应式表:

HTML

<table class="table table-striped">
    <tbody>
        <tr>
            <th class="col-sm-1">Col 1
            </th>
            <th class="col-sm-2">Col 2
            </th>
            <th class="col-sm-6">Col 3
            </th>
            <th class="col-sm-1">Col 4
            </th>
            <th class="col-sm-1">Col 5
            </th>
            <th class="col-sm-1">Col 6
            </th>
        </tr>
        <tr>
            <td>ILK-AK Garching
            </td>
            <td>Einen guten Titel zu finden ist eigentlich eine Diskussion …
            </td>
            <td>Eine wunderbare Heiterkeit hat meine ganze Seele eingenommen, gleich den süßen Frühlingsmorgen, die ich mit ganzem Herzen genieße. Ich bin allein und…
            </td>
            <td>Niedrig
            </td>
            <td>
                <time datetime="2014-07-18T12:03:38.9570000">18.07.2014 12:03</time>
            </td>
            <td>
                <time datetime="2014-08-20T14:15:39.3830000">20.08.2014 14:15</time>
            </td>
        </tr>
        <tr>
            <td>ILK-AK Garching
            </td>
            <td>Zeta-Kafka ist, gleich einem Manifest, pompös und glorreich
            </td>
            <td>Jemand musste Josef K. verleumdet haben, denn ohne dass er etwas Böses getan hätte, wurde er eines Morgens verhaftet. »Wie ein Hund!« sagte er, es wa…
            </td>
            <td>Niedrig
            </td>
            <td>
                <time rel="timeago" datetime="2014-08-20T13:41:22.3500000">20.08.2014 13:41</time>
            </td>
            <td>
                <time rel="timeago" datetime="2014-08-20T14:16:39.8170000">20.08.2014 14:16</time>
            </td>
        </tr>
        <tr>
            <td>ILK-AK Garching
            </td>
            <td>Tests von mechanischen Apparaten sind grundsätzlich erwünsc…
            </td>
            <td>Er hörte leise Schritte hinter sich. Das bedeutete nichts Gutes. Wer würde ihm schon folgen, spät in der Nacht und dazu noch in dieser engen Gasse mi…
            </td>
            <td>Mittel
            </td>
            <td>
                <time datetime="2014-08-20T13:41:51.0870000">20.08.2014 13:41</time>
            </td>
            <td>
                <time datetime="2014-08-20T14:18:21.2200000">20.08.2014 14:18</time>
            </td>
        </tr>
    </tbody>
</table>

CSS

/* seo friendly tables */
 .div-table 
    display: table;
    /* Defines a Table */
    font-size: 14px;
    border-bottom: 1px solid #dddddd;
    color: #8d8d8d;
    margin: 0;
    width: 100%;

.table-container 
    display: table;
    width: 100%;

.table-head 
    display: table-header-group;
    /* Defines a table header group */
    font-weight: 600 !important;
    text-align: center;
    border: solid 1px #ddd;
    color: #333;
    background: rgb(242, 242, 242);
    font-size: inherit;
    vertical-align: middle;

.table-head .column 
    /* Column inside the table-head */
    background: #f2f2f2;
    color: #7d7d7d;
    border: solid 1px #ddd;

.table-row 
    display: table-row;
    /* Defines a table row */
    padding: 3px 6px;
    color: #333;
    border-collapse: collapse;
    text-align: center;
    vertical-align: middle;

.table-row .column:nth-child(1) 
    /* First column in a row */
    border-left: 1px solid #eeeeee;

.table-row:last-child .column 
    /* column in a last row */
    border-bottom: none;

.table-row:hover 
    background: #f9f9f9;

.column 
    display: table-cell;
    /* Defines a table cell */
    padding: 8px 3px;
    color: #333;
    border-bottom: 1px solid #eeeeee;
    border-right: 1px solid #eeeeee;
    vertical-align:middle;

/* Responsive table */
 @media all and (max-width:768px) 
    .div-table, .table-row, .column, .column:before 
        display: block;
        /* Converts a table, table row, table column and table column:before into a block element */
    
    .div-table, .table-row .column:last-child 
        border-bottom: none;
    
    .table-head 
        position: absolute;
        /* Hides table head but not using display none */
        top: -1000em;
        left: -1000em;
    
    .table-row 
        border: 1px solid #eeeeee;
        margin: 20px 0;
    
    .table-row .column 
        border-right:none;
        text-align: left;
    
    .table-row .column:nth-child(1) 
        /* first column of the row */
        border-left: none;
        border-right: none;
    
    .table-row .column:last-child 
        /* last column of the row */
        border-right: none;
    
    .table-row:last-child .column, .column 
        /* Column in the last row and column */
        border-bottom: 1px solid #eeeeee;
    
    .table-row:hover 
        background: #fff;
    
    .column:before 
        /* prints the value of data-label attribute before the column data */
        font-weight: bold;
        padding-right: 20px;
        font-size: 12px;
        content:"" attr(data-label)"";
        /* call the attribute value of data-label and adds a string // */
    
    .column:hover 
        background: #f9f9f9;
    

jQuery 代码

$(document).ready(function () 
    var gridClass = $('.table');
    // counts total number of td in a head so that we can can use it for label extraction
    var head_col_count = $(gridClass).find('tbody th').size();

    // loop which replaces td
    for (i = 0; i <= head_col_count; i++) 
        // head column label extraction
        var head_col_label = $(gridClass).find('tbody th:nth-child(' + i + ')').text();
        // replaces td with <div class="column" data-label="label">
        $(gridClass).find('tr td:nth-child(' + i + ')').replaceWith(function () 
            return $('<div class="column" data-label="' + head_col_label + '">').append($(this).contents());
        );
    
    // replaces table with <div class="table">
    $(gridClass).replaceWith(function () 
        return $('<div class="div-table">').append($(this).contents());
    );

    // replaces thead with <div class="table-head">
    $('.div-table tbody tr:first-child').replaceWith(function () 
        return $('<div class="table-head">').append($(this).contents());
    );
    // replaces tbody with <div class="table-container">
    $('.div-table tbody').replaceWith(function () 
        return $('<div class="table-container">').append($(this).contents());
    );
    // replaces tr with <div class="table-row">
    $('.div-table tr').replaceWith(function () 
        return $('<div class="table-row">').append($(this).contents());
    );
    // replaces th with <div class="column">
    $('.div-table th').replaceWith(function () 
        return $('<div class="column">').append($(this).contents());
    );
);

可以在here 找到全屏演示。 Jsfiddle.net 编辑link。

但是,如果您希望使用当前的 html 标记,则必须稍微更改脚本。

【讨论】:

这个 OP 的好解决方案。【参考方案4】:

您可以查看Responsive data tables。如果这不符合您的需要,您可以使用 JavaScript 将表格视图重新创建为 div。如果您可以将表数据作为 JSON 获取,这将是最简单的,它将被转换为表或 div - 取决于分辨率。如果你不能将它作为 JSON,你总是可以使用 jQuery 的 html() 或 text() 从表格单元格中获取数据并重新绘制到 div 中。

【讨论】:

只是来自更现代的一个注释:我认为这个答案随着时间的推移而老化得很好。如果您想在窄屏幕上使用不同的布局,我会说最好分别进行它们并在客户端之间进行选择。这甚至适用于非常小的 JS。由于缺少 JS,最受好评的答案是非常好的 f,但是重新定义 tr 感觉有点笨拙,如果您想将表格行变成更好的面板以每行有 1-n 个数据块,您将与浏览器抗争(如问题中的最后一张图片)

以上是关于将表格行分成多行(响应式布局)的主要内容,如果未能解决你的问题,请参考以下文章

JGUI源码:实现响应式布局(13)

超 Nice 的表格响应式布局小技巧

响应式表格布局

响应式表格不适用于 laravel 布局

为小型显示器显示彼此下方的表格列(响应式布局)

有啥方法可以让 <tr> 浮动以实现响应式表格布局?