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

47

我有一个列出物品的网页。默认模板使用表格,我觉得非常合适。但是,在这个表格中,有一列包含比其他列更多的文本:

enter image description here

虽然在大屏幕上这样做是可行的,但在小屏幕上阅读非常烦人:

enter image description here

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

enter image description here

虽然通过使用全宽度来提高文本的可读性,但我不能再使用表格的工具,这会以微妙的方式破坏用户体验。例如,我使用一个很好的脚本,在客户端启用排序。但这只适用于真正的表格。(此外,真正的表格和伪表格之间存在小的不一致和视觉差异)
有没有办法将表格行重新格式化为类似于最后图像中的多行容器?
FYI: 我正在使用jquery 2.1.1、Bootstrap 3.2.0.1作为GUI框架,以及服务器上的asp.net MVC。
Bootply在这里:http://www.bootply.com/pRehwTai4G 编辑:如果没有表达清楚:我想保留<tr><td>标签,但将它们样式设定为类似于divs。我不想用divs替换表格。

如果您在Bootply上发布了问题,我有一些想法;但没有一个可以确定地说。 - Jordan.J.D
1
这个怎么样:http://www.bootply.com/kA1JWPSFSz -- 你需要调整CSS,但这个插件很棒。 - Christina
4个回答

52

您可以只使用几行 CSS 来完成此操作...

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

.计算器是用于表格的类:

<table class="calculator">

我使用这个工具快速修改我用于计算器输入的表格,使其在移动端/桌面端查看时具有更智能的外观设计:此处有实际示例,尽管最好通过并排查看移动设备和桌面设备之间的差异(并非所有移动脚本都会传送到桌面浏览器,因此如果您仅通过桌面浏览器最小化查看,则整体设计可能看起来很奇怪,但单元格将变成行等以进行说明)。

另外,您可以在单元格中添加span / label等,并使其变得更加美观。

display:table-cell;

如果你愿意,可以将表格设为块级元素,这种方法更加轻量级,而且不需要使用JavaScript。


2
最佳答案在这里! - Lev
在尝试使用Bootstrap和Flexbox解决响应式表格问题失败后,这个解决方案拯救了我。 - S Raghav
1
还注意到当您使用bootstrap时,设置display: table-row会使<td>缩小到内容大小。如果您想要一个全宽度的td(就像一行),display: block对我有用。 - S Raghav
引导效应将由CSS设置引起,如果需要,您可以通过向表格应用附加类并以此方式进行定位来覆盖它。 - Pete - iCalculator
绝妙的解决方案! - Mohammad Mahroz

13
如果您从表格中删除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());
    });
});

这里可以找到全屏演示 Jsfiddle.net编辑链接

然而,如果您希望使用当前的HTML标记,则需要稍微更改脚本。


2
这个问题的解决方案很好。 - HPWD

13
你可以看一下响应式数据表。如果不适合你的需求,你可以使用JavaScript重新创建表格视图为divs。如果你可以获得表格数据的JSON格式,这将是最简单的方法,它将被转换为表格或divs-具体取决于分辨率。如果无法以JSON格式获取数据,您始终可以使用jQuery的html()或text()从表格单元格获取数据并重新绘制成divs。

只是一个现代时代的注释:我认为这个答案随着时间的推移变得越来越好。如果你想在窄屏幕上使用不同的布局,我建议最好分别进行,并在客户端之间进行选择。即使只有很少的JS也可以实现这一点。 最受欢迎的答案对于缺乏JS非常好,但重新定义tr感觉有点hacky,如果你想将表格行转换为更好的面板,以每行1-n个数据片段(如问题中的最后一个图像),则会与浏览器发生冲突。 - DasKrümelmonster

0

谢谢 Pete,我使用了你的解决方案并做了一些小修改。(使用一个 class 'br' 来打断一行并继续进行 TDs。)

<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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接