24

How can I make the table header appear on the left side of the table as a column instead on the top as a row? I have this markup:

<table>
  <thead>
    <tr>
      <th>a</th>
      <th>b</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
    </tr>
  </tbody>
</table>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Richard Knop
  • 81,041
  • 149
  • 392
  • 552

6 Answers6

54

Just use <th> as the first element in the row. Then add the scope attribute, which has no visual impact, but you could use it e.g. in CSS.

<table>
  <tbody>
    <tr>
      <th scope="row">A</th>
      <td>b</td>
    </tr>
    <tr>
      <th scope="row">C</th>
      <td>d</td>
    </tr>
  </tbody>
</table>

See also http://www.w3.org/TR/WCAG20-TECHS/H63

Joel
  • 4,503
  • 1
  • 27
  • 41
jakov
  • 641
  • 5
  • 3
30

How's this?

Example

Example

CSS

thead {
  float: left;   
}

thead th {
  display: block;   
}

tbody {
  float: right;   
}

jsFiddle.

Update

Well, the 1, 2 should also be as column, obviously.

jsFiddle.

It also looks like IE baulks at this. You may have to trade semantic-ness for cross browser compatibility.

Update

Example

If you have multiple rows that you want to become columns.

jsFiddle.

Luke Schoen
  • 4,129
  • 2
  • 27
  • 25
alex
  • 479,566
  • 201
  • 878
  • 984
  • Well, the 1, 2 should also be as column, obviously. – Richard Knop Apr 27 '11 at 07:21
  • @Richard It mustn't of been that obvious then :P. See update. – alex Apr 27 '11 at 07:26
  • Guess where it doesn't work in... IE7. Haven't tested any other versions – Gary Green Apr 27 '11 at 07:27
  • @Gary I had a suspicion it may not. You may have to trade semantics for cross browser compatibility. – alex Apr 27 '11 at 07:28
  • Made a minor modification to allow more "rows": http://jsfiddle.net/kwfetzxf/ Also, both seem to work in IE11, Chrome and FF – LoPoBo Jan 23 '15 at 13:03
  • Is that possible in some way to have this table to 100% width ? I wasn't able to do it because of the float I think. – baraber Dec 01 '17 at 15:42
  • if you want to display multiple columns of data then you also need to add `tbody tr { display: inline-block; }` as shown here http://jsfiddle.net/ltfschoen/jtn6bmyz/5/. otherwise if you add more 's in the then the data clears to the next row – Luke Schoen Apr 05 '23 at 06:52
2

I needed something a little different, but the answers by @alex and @marion got me started in the right direction. The problem was that when you needed many items in the table, the "columns" started stacking funny on smaller screens.

Thanks to Serge for his answer here that led me in this solution. This solution allows for scrolling horizontally and doesn't stack funny regardless of the size of the screen/window. I tested it in Chrome, Firefox, Opera, Edge, and IE11. Here's the fiddle with the correct alignment for the new "rows" and "columns": https://jsfiddle.net/berrym/6r3zvaef/21/

And just in case it disappears from JSFiddle:

<style>
table{
  display:block;
  white-space:nowrap;
  width:100%;
}
td, th {
  border-bottom: 1px solid red;
  border-collapse: collapse;
}
thead {
  float: left;
  background: yellow;
  width: 10%;
}
thead tr {
  width:100%;
  float:left;
}
thead th {
  display: block;
}
tbody {
  float: left;
  width: 90%;
}
tbody tr {
  display: inline-block;
}
tbody td {
  float:left;
  width:100%;
}
</style>
<table>
  <thead>
    <tr>
      <th>A</th>
      <th>B</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
  </tbody>
</table>
Michael
  • 2,016
  • 5
  • 35
  • 51
  • YOU ARE AMAZING. THANK YOU. I have been scouring everywhere for this answer -- no one else was taking the stacking on smaller screens into account. – Sensoray Mar 03 '20 at 00:25
2

You can see the result here. You mean like this?

<table border="1">
    <thead>
        <tr>
            <th></th>
            <th colspan="2">Letters</th>
        </tr>
        <tr>
            <th></th>
            <th>a</th>
            <th>b</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td rowspan="3">Numbers</td>
            <td>1</td>
            <td>4</td>
        </tr>
        <tr>
            <td>2</td>
            <td>5</td>
        </tr>
        <tr>
            <td>3</td>
            <td>6</td>
        </tr>
    </tbody>
</table>

You usually use rowspan and colspan for cells spanning multiple columns/rows.

Dennis G
  • 21,405
  • 19
  • 96
  • 133
0

This worked perfectly for me : (inspired from the first answer)

Example here

html :

 <table>
  <thead>
    <tr>
      <th>A</th>
      <th>B</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a1</td>
      <td>b1</td>
    </tr>
    <tr>
      <td>a2</td>
      <td>b2</td>
    </tr>
    <tr>
      <td>a3</td>
      <td>b3</td>
    </tr>
  </tbody>
</table>

css :

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

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

tbody {
  float: left;   
}
tbody tr {
  display: block;
  float: left;
}
tbody td {
  display: block;
}
  • You win the gold star! Thanks for sharing your answer! – Michael Dec 20 '17 at 17:23
  • The problem is, that this causes all of the columns to be pushed down below the table when resizing -- do you have a way to counteract that? otherwise this will only work for minimal amounts of data. – Sensoray Mar 02 '20 at 23:32
0

If you use bootstrap, you can achieve this easily with the table-reflow style: http://v4-alpha.getbootstrap.com/content/tables/#reflow

Frank Fang
  • 151
  • 2
  • 7
  • 1
    `.table-reflow` was actually dropped from Bootstrap 4, so this is no longer an option. See [this commit](https://github.com/twbs/bootstrap/commit/bd72b9593bbff9a001ba818dbf8782b5ed3f08d0) – Scribblemacher Jan 26 '17 at 16:05