简体   繁体   English

拆分 HTML 表格以适应视口宽度

[英]Split HTML table to fit viewport width

I have a HTML table with a lot of columns.我有一个包含很多列的 HTML 表。 I want to split the table to fit the viewport width like so:我想拆分表格以适应视口宽度,如下所示:

The basic table基本表

      | Column 1 | Column 2 | Column 3 | Column 4
------+----------+----------+----------+---------
Row 1 | (1,1)    | (1,2)    | (1,3)    | (1,4)
Row 2 | (2,1)    | (2,2)    | (2,3)    | (2,4)

What I want to have我想要的

      | Column 1 | Column 2
------+----------+---------
Row 1 | (1,1)    | (1,2)
Row 2 | (2,1)    | (2,2)

      | Column 3 | Column 4
------+----------+---------
Row 1 | (1,3)    | (1,4)
Row 2 | (2,3)    | (2,4)

The cells containing 'Row X' and 'Column X' are headers, which I want to maintain on the wrapped table.包含 'Row X' 和 'Column X' 的单元格是标题,我想保留在包装表上。

Is this possible using HTML/CSS/Javascript, such that the table splits responsively?这是否可以使用 HTML/CSS/Javascript,以便表格响应拆分?

Edit 1 My HTML:编辑 1我的 HTML:

 <table> <thead> <tr> <th></th> <th>Column 1</th> <th>Column 2</th> <th>Column 3</th> <th>Column 4</th> </tr> </thead> <tbody> <tr> <th>Row 1</th> <td>(1,1)</td> <td>(1,2)</td> <td>(1,3)</td> <td>(1,4)</td> </tr> <tr> <th>Row 2</th> <td>(2,1)</td> <td>(2,2)</td> <td>(2,3)</td> <td>(2,4)</td> </tr> </tbody>

Here's a JS solution to get you started.这是一个让您入门的 JS 解决方案。 This one can be optimized in several ways and you can adopt it to your own project requirements.这可以通过多种方式进行优化,您可以根据自己的项目要求采用它。 All in all, I enjoyed quick-hacking this little sample.总而言之,我喜欢快速破解这个小样本。

Here's the code pen: http://codepen.io/anon/pen/RPLvyN .这是代码笔: http : //codepen.io/anon/pen/RPLvyN (Resize the screen horizontally to see the effect). (水平调整屏幕大小以查看效果)。

 function FlexTable(el, container) { if(!(this instanceof FlexTable)) { return new FlexTable(el, container); } this.$el = $(el); this.$container = $(container); this.tables = [{ $el: this.$el, columns: [] }]; this.getInfo(); this.extractData(); this.extractLabels(); this.handleResizing(); this.restructure(); } FlexTable.prototype.getInfo = function() { this.columns = []; this.$el.find("thead th").each(function(key, el) { this.columns.push($(el).outerWidth()); }.bind(this)); this.tables[0].columns = this.columns.slice(1); }; FlexTable.prototype.extractData = function() { this.data = []; this.rows = -1; $("tbody td").each(function(index, element) { if(index % (this.columns.length - 1) === 0) { this.data[++this.rows] = []; } this.data[this.rows].push($(element).text().trim()); }.bind(this)); }; FlexTable.prototype.extractLabels = function() { this.columnLabels = []; this.rowLabels = []; this.$el.find("thead > tr > :nth-of-type(n + 2)").each(function(index, element) { this.columnLabels.push($(element).text().trim()); }.bind(this)).end().find("tbody > tr > :first-child") .each(function(index, element) { this.rowLabels.push($(element).text().trim()); }.bind(this)); }; FlexTable.prototype.handleResizing = function() { this.$container.resize(function() { this.restructure(); }.bind(this)); }; FlexTable.prototype.availableSpace = function(flatten) { return flatten ? +Infinity : this.$container.outerWidth(); }; FlexTable.prototype.possibleTables = function() { var space = this.availableSpace(); var total = 0; var column = 0; var numTables = 0; var tables = []; while(true) { total = this.columns[0]; tables[numTables] = { $el: null, columns: [] }; do { total += this.columns[++column]; tables[numTables].columns.push(column - 1); } while((total + this.columns[column + 1]) < space); numTables++; if(column === this.columns.length - 1) { break; } } return tables; }; FlexTable.prototype.sameTablesAsBefore = function(tables) { if(this.tables.length !== tables.length) { return false; } for(var i = 0, len = tables.length; i < len; i++) { if(tables[i].columns.length !== this.tables[i].columns.length) { return false; } } return true; }; FlexTable.prototype.clearExistingTables = function() { this.tables.forEach(function(table) { table.$el.remove(); }); }; FlexTable.prototype.tableTemplate = function() { var $table = $("<table></table>"); var $tbody = $("<tbody></tbody>"); $table.append("<thead><tr><th></th></tr></thead>"); this.data.forEach(function(element, index) { this.cellTemplate(true) .text(this.rowLabels[index]) .appendTo($("<tr></tr>").appendTo($tbody)); }.bind(this)); return $table.append($tbody); }; FlexTable.prototype.cellTemplate = function(th) { return $(th ? "<th></th>" : "<td></td>"); }; FlexTable.prototype.buildTable = function(table, column) { var $table = this.tableTemplate(); for(var i = 0, len = table.columns.length; i < len; i++, column++) { this.cellTemplate(true) .text(this.columnLabels[column]) .appendTo($table.find("thead tr")); for(var j = 0, lenj = this.data.length; j < lenj; j++) { this.cellTemplate() .text(this.data[j][table.columns[i]]) .appendTo($table.find("tbody tr").eq(j)); } } return $table; }; FlexTable.prototype.restructure = function() { var tables = this.possibleTables(); if(this.sameTablesAsBefore(tables)) { return; } this.clearExistingTables(); for(var i = 0, column = 0, len = tables.length; i < len; column += tables[i++].columns.length) { var $table = this.buildTable(tables[i], column); tables[i].$el = $table; $(".tables").append($table); } this.tables = tables; }; $(function() { FlexTable(".tables table:first", window); });
 * { margin: 0; padding: 0; } body { padding: 10px 20px; } table { border-collapse: collapse; } table + table { margin-top: 15px; } table th, table td { white-space: nowrap; border: 1px solid #ccc; padding: 5px 10px; text-align: left; } table tr th:first-of-type { border: 0; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> HTML: <div class="tables"> <table> <thead> <tr> <th></th> <th>Name</th> <th>Position</th> <th>Office</th> <th>Age</th> <th>Start date</th> <th>Salary</th> </tr> </thead> <tbody> <tr> <th></th> <td>Tiger Nixon</td> <td>System Architect</td> <td>Edinburgh</td> <td>61</td> <td>2011/04/25</td> <td>$320,800</td> </tr> <tr> <th></th> <td>Garrett Winters</td> <td>Accountant</td> <td>Tokyo</td> <td>63</td> <td>2011/07/25</td> <td>$170,750</td> </tr> <tr> <th></th> <td>Ashton Cox</td> <td>Junior Technical Author</td> <td>San Francisco</td> <td>66</td> <td>2009/01/12</td> <td>$86,000</td> </tr> <tr> <th></th> <td>Cedric Kelly</td> <td>Senior Javascript Developer</td> <td>Edinburgh</td> <td>22</td> <td>2012/03/29</td> <td>$433,060</td> </tr> <tr> <th></th> <td>Airi Satou</td> <td>Accountant</td> <td>Tokyo</td> <td>33</td> <td>2008/11/28</td> <td>$162,700</td> </tr> <tr> <th></th> <td>Brielle Williamson</td> <td>Integration Specialist</td> <td>New York</td> <td>61</td> <td>2012/12/02</td> <td>$372,000</td> </tr> <tr> <th></th> <td>Herrod Chandler</td> <td>Sales Assistant</td> <td>San Francisco</td> <td>59</td> <td>2012/08/06</td> <td>$137,500</td> </tr> <tr> <th></th> <td>Rhona Davidson</td> <td>Integration Specialist</td> <td>Tokyo</td> <td>55</td> <td>2010/10/14</td> <td>$327,900</td> </tr> <tr> <th></th> <td>Colleen Hurst</td> <td>Javascript Developer</td> <td>San Francisco</td> <td>39</td> <td>2009/09/15</td> <td>$205,500</td> </tr> <tr> <th></th> <td>Sonya Frost</td> <td>Software Engineer</td> <td>Edinburgh</td> <td>23</td> <td>2008/12/13</td> <td>$103,600</td> </tr> <tr> <th></th> <td>Jena Gaines</td> <td>Office Manager</td> <td>London</td> <td>30</td> <td>2008/12/19</td> <td>$90,560</td> </tr> <tr> <th></th> <td>Quinn Flynn</td> <td>Support Lead</td> <td>Edinburgh</td> <td>22</td> <td>2013/03/03</td> <td>$342,000</td> </tr> <tr> <th></th> <td>Charde Marshall</td> <td>Regional Director</td> <td>San Francisco</td> <td>36</td> <td>2008/10/16</td> <td>$470,600</td> </tr> <tr> <th></th> <td>Haley Kennedy</td> <td>Senior Marketing Designer</td> <td>London</td> <td>43</td> <td>2012/12/18</td> <td>$313,500</td> </tr> <tr> <th></th> <td>Tatyana Fitzpatrick</td> <td>Regional Director</td> <td>London</td> <td>19</td> <td>2010/03/17</td> <td>$385,750</td> </tr> <tr> <th></th> <td>Michael Silva</td> <td>Marketing Designer</td> <td>London</td> <td>66</td> <td>2012/11/27</td> <td>$198,500</td> </tr> <tr> <th></th> <td>Paul Byrd</td> <td>Chief Financial Officer (CFO)</td> <td>New York</td> <td>64</td> <td>2010/06/09</td> <td>$725,000</td> </tr> <tr> <th></th> <td>Gloria Little</td> <td>Systems Administrator</td> <td>New York</td> <td>59</td> <td>2009/04/10</td> <td>$237,500</td> </tr> <tr> <th></th> <td>Bradley Greer</td> <td>Software Engineer</td> <td>London</td> <td>41</td> <td>2012/10/13</td> <td>$132,000</td> </tr> <tr> <th></th> <td>Dai Rios</td> <td>Personnel Lead</td> <td>Edinburgh</td> <td>35</td> <td>2012/09/26</td> <td>$217,500</td> </tr> <tr> <th></th> <td>Jenette Caldwell</td> <td>Development Lead</td> <td>New York</td> <td>30</td> <td>2011/09/03</td> <td>$345,000</td> </tr> <tr> <th></th> <td>Yuri Berry</td> <td>Chief Marketing Officer (CMO)</td> <td>New York</td> <td>40</td> <td>2009/06/25</td> <td>$675,000</td> </tr> <tr> <th></th> <td>Caesar Vance</td> <td>Pre-Sales Support</td> <td>New York</td> <td>21</td> <td>2011/12/12</td> <td>$106,450</td> </tr> <tr> <th></th> <td>Doris Wilder</td> <td>Sales Assistant</td> <td>Sidney</td> <td>23</td> <td>2010/09/20</td> <td>$85,600</td> </tr> <tr> <th></th> <td>Angelica Ramos</td> <td>Chief Executive Officer (CEO)</td> <td>London</td> <td>47</td> <td>2009/10/09</td> <td>$1,200,000</td> </tr> <tr> <th></th> <td>Gavin Joyce</td> <td>Developer</td> <td>Edinburgh</td> <td>42</td> <td>2010/12/22</td> <td>$92,575</td> </tr> <tr> <th></th> <td>Jennifer Chang</td> <td>Regional Director</td> <td>Singapore</td> <td>28</td> <td>2010/11/14</td> <td>$357,650</td> </tr> <tr> <th></th> <td>Brenden Wagner</td> <td>Software Engineer</td> <td>San Francisco</td> <td>28</td> <td>2011/06/07</td> <td>$206,850</td> </tr> <tr> <th></th> <td>Fiona Green</td> <td>Chief Operating Officer (COO)</td> <td>San Francisco</td> <td>48</td> <td>2010/03/11</td> <td>$850,000</td> </tr> <tr> <th></th> <td>Shou Itou</td> <td>Regional Marketing</td> <td>Tokyo</td> <td>20</td> <td>2011/08/14</td> <td>$163,000</td> </tr> <tr> <th></th> <td>Michelle House</td> <td>Integration Specialist</td> <td>Sidney</td> <td>37</td> <td>2011/06/02</td> <td>$95,400</td> </tr> <tr> <th></th> <td>Suki Burks</td> <td>Developer</td> <td>London</td> <td>53</td> <td>2009/10/22</td> <td>$114,500</td> </tr> <tr> <th></th> <td>Prescott Bartlett</td> <td>Technical Author</td> <td>London</td> <td>27</td> <td>2011/05/07</td> <td>$145,000</td> </tr> <tr> <th></th> <td>Gavin Cortez</td> <td>Team Leader</td> <td>San Francisco</td> <td>22</td> <td>2008/10/26</td> <td>$235,500</td> </tr> <tr> <th></th> <td>Martena Mccray</td> <td>Post-Sales support</td> <td>Edinburgh</td> <td>46</td> <td>2011/03/09</td> <td>$324,050</td> </tr> <tr> <th></th> <td>Unity Butler</td> <td>Marketing Designer</td> <td>San Francisco</td> <td>47</td> <td>2009/12/09</td> <td>$85,675</td> </tr> <tr> <th></th> <td>Howard Hatfield</td> <td>Office Manager</td> <td>San Francisco</td> <td>51</td> <td>2008/12/16</td> <td>$164,500</td> </tr> <tr> <th></th> <td>Hope Fuentes</td> <td>Secretary</td> <td>San Francisco</td> <td>41</td> <td>2010/02/12</td> <td>$109,850</td> </tr> <tr> <th></th> <td>Vivian Harrell</td> <td>Financial Controller</td> <td>San Francisco</td> <td>62</td> <td>2009/02/14</td> <td>$452,500</td> </tr> <tr> <th></th> <td>Timothy Mooney</td> <td>Office Manager</td> <td>London</td> <td>37</td> <td>2008/12/11</td> <td>$136,200</td> </tr> <tr> <th></th> <td>Jackson Bradshaw</td> <td>Director</td> <td>New York</td> <td>65</td> <td>2008/09/26</td> <td>$645,750</td> </tr> <tr> <th></th> <td>Olivia Liang</td> <td>Support Engineer</td> <td>Singapore</td> <td>64</td> <td>2011/02/03</td> <td>$234,500</td> </tr> <tr> <th></th> <td>Bruno Nash</td> <td>Software Engineer</td> <td>London</td> <td>38</td> <td>2011/05/03</td> <td>$163,500</td> </tr> <tr> <th></th> <td>Sakura Yamamoto</td> <td>Support Engineer</td> <td>Tokyo</td> <td>37</td> <td>2009/08/19</td> <td>$139,575</td> </tr> <tr> <th></th> <td>Thor Walton</td> <td>Developer</td> <td>New York</td> <td>61</td> <td>2013/08/11</td> <td>$98,540</td> </tr> <tr> <th></th> <td>Finn Camacho</td> <td>Support Engineer</td> <td>San Francisco</td> <td>47</td> <td>2009/07/07</td> <td>$87,500</td> </tr> <tr> <th></th> <td>Serge Baldwin</td> <td>Data Coordinator</td> <td>Singapore</td> <td>64</td> <td>2012/04/09</td> <td>$138,575</td> </tr> <tr> <th></th> <td>Zenaida Frank</td> <td>Software Engineer</td> <td>New York</td> <td>63</td> <td>2010/01/04</td> <td>$125,250</td> </tr> <tr> <th></th> <td>Zorita Serrano</td> <td>Software Engineer</td> <td>San Francisco</td> <td>56</td> <td>2012/06/01</td> <td>$115,000</td> </tr> <tr> <th></th> <td>Jennifer Acosta</td> <td>Junior Javascript Developer</td> <td>Edinburgh</td> <td>43</td> <td>2013/02/01</td> <td>$75,650</td> </tr> <tr> <th></th> <td>Cara Stevens</td> <td>Sales Assistant</td> <td>New York</td> <td>46</td> <td>2011/12/06</td> <td>$145,600</td> </tr> <tr> <th></th> <td>Hermione Butler</td> <td>Regional Director</td> <td>London</td> <td>47</td> <td>2011/03/21</td> <td>$356,250</td> </tr> <tr> <th></th> <td>Lael Greer</td> <td>Systems Administrator</td> <td>London</td> <td>21</td> <td>2009/02/27</td> <td>$103,500</td> </tr> <tr> <th></th> <td>Jonas Alexander</td> <td>Developer</td> <td>San Francisco</td> <td>30</td> <td>2010/07/14</td> <td>$86,500</td> </tr> <tr> <th></th> <td>Shad Decker</td> <td>Regional Director</td> <td>Edinburgh</td> <td>51</td> <td>2008/11/13</td> <td>$183,000</td> </tr> <tr> <th></th> <td>Michael Bruce</td> <td>Javascript Developer</td> <td>Singapore</td> <td>29</td> <td>2011/06/27</td> <td>$183,000</td> </tr> <tr> <th></th> <td>Donna Snider</td> <td>Customer Support</td> <td>New York</td> <td>27</td> <td>2011/01/25</td> <td>$112,000</td> </tr> </tbody> </table> </div>

If you are using just one table, then I doubt that your specs be accomplished without using JavaScript to basically restructure the HTML.如果您只使用一张表,那么我怀疑您的规范是否可以在不使用 JavaScript 来基本重构 HTML 的情况下完成。 The latter, in my opinion would not be the best way to go.后者,在我看来不是最好的方法。 If you are willing to adjust the markup from the get go, then, yes, you can accomplish the functionality that you are seeking using only CSS.如果您愿意从一开始就调整标记,那么,是的,您可以仅使用 CSS 来实现您正在寻求的功能。

Here's just one example: http://jsfiddle.net/ktrz74sm/ .这里只是一个例子: http : //jsfiddle.net/ktrz74sm/ (Resize the screen to see the effect). (调整屏幕大小以查看效果)。

HTML: HTML:

<div id = "wrapper">
    <table>
        <tr>
            <td></td>
            <td>Column 1</td>
            <td>Column 2</td>
        </tr>
        <tr>
            <td>Row 1</td>
            <td>(1, 1)</td>
            <td>(1, 2)</td>
        </tr>
        <tr>
            <td>Row 2</td>
            <td>(2, 1)</td>
            <td>(2, 2)</td>
        </tr>
    </table>
    <table>
        <tr>
            <td></td>
            <td>Column 3</td>
            <td>Column 4</td>
        </tr>
        <tr>
            <td>Row 1</td>
            <td>(1, 3)</td>
            <td>(1, 4)</td>
        </tr>
        <tr>
            <td>Row 2</td>
            <td>(2, 3)</td>
            <td>(2, 4)</td>
        </tr>
    </table>
</div>

CSS: CSS:

table td {
    text-align: center;
}

@media screen and (min-width: 400px) {
    table {
        display: inline-table;    
    }

    table:nth-of-type(2) td:first-of-type {
        display: none;    
    }   
}

And, here's a solution that uses counters to eliminate naming rows and columns: http://jsfiddle.net/nm5bybf2/ .而且,这里有一个使用计数器来消除命名行和列的解决方案: http : //jsfiddle.net/nm5bybf2/

HTML: HTML:

<div id = "wrapper">
    <table>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>(1, 1)</td>
            <td>(1, 2)</td>
        </tr>
        <tr>
            <td></td>
            <td>(2, 1)</td>
            <td>(2, 2)</td>
        </tr>
    </table>
    <table>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>(1, 3)</td>
            <td>(1, 4)</td>
        </tr>
        <tr>
            <td></td>
            <td>(2, 3)</td>
            <td>(2, 4)</td>
        </tr>
    </table>
</div>

CSS: CSS:

body {
    counter-reset: column-counter;
}   

table td {
    text-align: center;
}

table {
    counter-reset: row-counter;
}

table tr:nth-of-type(n + 2) td:first-of-type:before {
    counter-increment: row-counter;
    content: "Row " counter(row-counter);
}

table tr:first-of-type td:nth-of-type(n + 2):before {
    counter-increment: column-counter;
    content: "Column " counter(column-counter);
}

@media screen and (min-width: 400px) {
    table {
        display: inline-table;
    }

    table:nth-of-type(2) td:first-of-type {
        display: none;    
    }
}

Basically you're trying to make a responsive table, without getting the columns that don't fit in the view space cut off by the edge of the the screen, correct?基本上,您正在尝试制作一个响应式表格,而不会让不适合被屏幕边缘切断的视图空间的列,对吗?

If so, why not just make two side-by-side tables?如果是这样,为什么不制作两张并排的桌子呢? Let me explain.让我解释。

I actually had to find a solution to this same problem just this past week for a client of the company I work for who wanted a 9 by 9 table on his site, which is no big deal, except it needed to be responsive.实际上,就在上周,我不得不为我工作的公司的一位客户找到解决同一问题的方法,该客户希望在他的网站上有一张 9 x 9 的桌子,这没什么大不了的,只是它需要响应。

So, here's what I came up with.所以,这就是我想出的。

I created two sideby side tables.我创建了两个并排的边桌。 The first containing only one column, with 9 rows.第一个只包含一列,有 9 行。 Then immediately to the right of it I created a second table, this one with 8 columns and 9 rows.然后在它的右边我创建了第二个表,这个表有 8 列和 9 行。 I set both tables to a fixed hight so they lined up properly.我将两张桌子都设置为固定高度,以便它们正确排列。 Next, use bootstrap's responsive table class and apply it to the large table that you want to scroll.接下来,使用 bootstrap 的响应式表格类并将其应用于您要滚动的大表格。 Use CSS media querys to change the widths of the tables using max-width (and set the media queries accordingly for your table at various page widths).使用 CSS 媒体查询使用 max-width 更改表格的宽度(并相应地为您的表格设置不同页面宽度的媒体查询)。 This allows the two tables to look like one table, but makes the left column(aka table) fixed.这允许两个表看起来像一个表,但使左列(又名表)固定。 This eliminates the need to repeat the first column over and over when displaying the rest of the columns.这消除了在显示其余列时一遍又一遍地重复第一列的需要。

Check out the table on the bottom of this page on a mobile device or narrow screen to see what I'm talking about and see if this setup would work for your use.在移动设备或窄屏上查看本页底部的表格,看看我在说什么,看看这个设置是否适合您使用。 Pure CSS powered mobile friendly table with lots of columns.纯 CSS 驱动的移动友好表格,有很多列。

http://www.cleanplanetdetailing.com/test-gtechniq-pricing.html http://www.cleanplanetdetailing.com/test-gtechniq-pricing.html

If that method does work for what you're trying to do, and you want more details on how to do it, post a comment and I'll be happy to make a write-up on it if you need one.如果该方法确实适用于您正在尝试做的事情,并且您想了解有关如何操作的更多详细信息,请发表评论,如果您需要,我很乐意对其进行撰写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM