20

How do I make vertical tables in HTML? By vertical, I mean the rows will be vertical with table headers on the left.

enter image description here

I also need it the way so I can access these rows (in this case vertical) as in a normal table, with <tr>. This is because I get the data dynamically for one row (like for row A) and insert it in the table. I am using angularJS to avoid DOM manipulation, so I am not looking for complex DOM manipulation with Javascript.

dda
  • 6,030
  • 2
  • 25
  • 34
vishesh
  • 2,007
  • 6
  • 32
  • 67

7 Answers7

76

If you want <tr> to display columns, not rows, try this simple CSS

tr { display: block; float: left; }
th, td { display: block; }

This should display what you want as far as you work with single-line cells (table behavior is dropped).

/* single-row column design */
tr { display: block; float: left; }
th, td { display: block; border: 1px solid black; }

/* border-collapse */
tr>*:not(:first-child) { border-top: 0; }
tr:not(:first-child)>* { border-left:0; }
<table>
<tr>
    <th>name</th>
    <th>number</th>
</tr>
<tr>
    <td>James Bond</td>
    <td>007</td>
</tr>
<tr>
    <td>Lucipher</td>
    <td>666</td>
</tr>
</table>
Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
  • 1
    @Sean that's sad. IE was not v11 in the time I gave this answer. And it seems it won't be here for long, Microsoft will probably move to Spartan. To fix the behavior, you could try to set `table, tbody { display: block; }` – Jan Turoň Feb 06 '15 at 23:11
  • Just tested it in IE11 and it works fine. If there is any trouble, post your link. – Jan Turoň Jun 04 '15 at 17:11
  • 1
    Keep in mind that this solution will ruin the border collapse functionality. – totymedli Oct 23 '16 at 22:48
  • @totymedli that's worth to notice. The solution could be to remove top and left borders from all cells but the first in row and col: `th:not(:first-child), td:not(:first-child) { border-top: 0 none; } tr:not(:first-child) th, tr:not(:first-child) td { border-left: 0 none; }` – Jan Turoň Oct 24 '16 at 06:46
  • 2
    How to make the table body horizontally scrollable? – naXa stands with Ukraine Apr 16 '17 at 22:22
  • @naXa similarly, I guess you could set `display: block; width: something; overflow: auto` to table element, but you should ask separate question to help find it for those who search answer for it. – Jan Turoň Apr 17 '17 at 07:09
  • @JanTuroň Of course - [here it is](http://stackoverflow.com/q/43442893/1429387). But I'm afraid this would be a question with no answer. – naXa stands with Ukraine Apr 17 '17 at 07:13
  • @naXa - looks like you got your answer in no time ;-) – Jan Turoň Apr 17 '17 at 08:15
3

David Bushell has provided a solution and implementation here: http://dbushell.com/demos/tables/rt_05-01-12.html

The trick is to use display: inline-block; on the table rows and white-space: nowrap; on the table body.

Pratyush
  • 5,108
  • 6
  • 41
  • 63
1

AFAIK, there is no magic solution to switch this around. As for a rotation(90deg), that would most likely turn the whole table to the side, similar to how a sheet of paper would look if you turned in 90 degrees, and that's not what you want (I think?).

If this is possible (and realistic), I would suggest changing it in the HTML itself.


As indicated in the comments, there is no suggestion here, so here's a basic javascript alternative [even if this is not what you were looking for] using jQuery. Without knowing your experience, I've taken the time to comment everything to be sure you get what the code is doing.

// Change the selector to suit your needs
$('table').each(function(){
    var table       = $(this), // Reference each table in the page
        header      = $('thead', table), // Reference the table head
        headings    = []; // Set an array for each column

    // If the table doesn't have a header, use it's footer for column titles
    if(!header.length)
        header = $('tfoot', table);
    // If there's no header nor footer, skip to the next table
    if(!header.length)
        continue;

    // Loop each heading to get the header value
    $('th', header).each(function(){
        var heading = $(this).html(); // Each heading value content, including any HTML; use .text() to use the text only
        headings.push(heading); // Add heading value to array
    });

    // Make sure the content is wrapped in a tbody element for proper syntax
    if(!$('tbody', table).length)
        table.wrapInner('<tbody></tbody>');

    // Set counter to reference the heading in the headings array
    var x = 0;

    // Loop through each row in the table
    $('tbody tr').each(function(){
        var row     = $(this),
            label   = headings[x];

        // Add the heading to the row, as a <th> for visual cues (default: bold)
        row.prepend('<th>'+label+'</th>')

        // Move to the next value in the headings value
        x++;
    });
});
davewoodhall
  • 998
  • 3
  • 18
  • 43
  • This doesn't answer the question. Only a suggestion is made, that is clearly not what the question asks for. – totymedli Oct 23 '16 at 22:34
  • @totymedli I've added a javascript snippet to address your comment; however, I am still not aware of a CSS option to rotate the table. – davewoodhall Oct 24 '16 at 02:14
0

You can use <th> as the first cell in the row. Here's a fiddle: http://jsfiddle.net/w5nWG/


@vishesh so you want to transpose your table after DOM ready? try this http://gist.github.com/pgaertig/2376975

$(function() {
    var t = $('#thetable tbody').eq(0);
    var r = t.find('tr');
    var cols= r.length;
    var rows= r.eq(0).find('td').length;
    var cell, next, tem, i = 0;
    var tb= $('<tbody></tbody>');

    while(i<rows){
        cell= 0;
        tem= $('<tr></tr>');
        while(cell<cols){
            next= r.eq(cell++).find('td').eq(0);
            tem.append(next);
        }
        tb.append(tem);
        ++i;
    }
    $('#thetable').append(tb);
    $('#thetable').show();
}
Kijewski
  • 25,517
  • 12
  • 101
  • 143
sebastian
  • 1,528
  • 8
  • 26
  • 38
  • @vishesh so you want to transpose your table after DOM ready? try this https://gist.github.com/pgaertig/2376975 – sebastian Jun 04 '13 at 13:05
0
 <table>
     <tr><td>1</td></tr>
     <tr><td>2</td></tr>
     <tr><td>3</td></tr>
 </table>



 table { border-collapse: collapse; }
 table tr { display: block; float: left; }
 table tr tr{ display: block; float: left; }
 table th, table td { display: block; border: none; }
Nithiyakumar K
  • 22
  • 3
  • 12
-1

try this

<table>
  <thead>
    <tr>
      <th>id</th>
      <th>column1</th>
      <th>column2</th>
      <th>column3</th>
      <th>column4</th>
      <th>column5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
    </tr>
  </tbody>
</table>

css:

table, td, th {
  border: 1px solid red;   
}

thead {
  float: left;   
}


thead th {
  display: block;   
  background: yellow;
}

tbody {
  float: right;   
}
learner
  • 1,952
  • 7
  • 33
  • 62
-3

Maybe this link won't help : rotate a table 90 degrees neither would this one : http://www.w3.org/TR/html401/struct/tables.html

Otherwise, you can try this, has another user suggested (rejected and downvoted) :

table {
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}

This sounds silly, but hey, it's not worse than just not knowing the 'verry basic' HTML 4 table model.

Community
  • 1
  • 1
Milche Patern
  • 19,632
  • 6
  • 35
  • 52
  • 3
    This is a horrible solution. It rotates everything even text. The question asks for a transpose not for a rotation. – totymedli Oct 23 '16 at 22:45
  • Your downvote for misplaced sarcasm is accepted. But i wont delete this. – Milche Patern Oct 25 '16 at 18:36
  • I know this is old, but I bet @MilchePatern, that you would get some upvotes and few lol's even if you were to put this in a "run this code" code block so visitors can actually see how monty python your answer is. Most CAN'T see it at first glance – Eric Hepperle - CodeSlayer2010 Nov 16 '22 at 13:56