CSSでtableの行と列を入れ替える


1.やりたいこと

通常のテーブルを使用したレイアウト(1行目がヘッダ、2行目以降が各レコード)をhtmlの構造はそのままに縦横を入れ替えたい。
flexを使用した例(「CSSのみでtableの行列入れ替え - Qiita」など)もあるがこの場合、空白カラムがあるとレイアウトが崩れてしまうので他の方法で実現をしてみる。

動作確認をした環境は以下の通り。Macを持っていないのでMac版safariではどうなるか不明です。

  1. Windos10 × Chrome 81.0.4044.92,IE11 (11.719.18362.0)
  2. iOS 13.4 (iPad mini 4) × safari

▼入れ替え前のイメージ

▼入れ替え後のイメージ

2.縦横入れ替え前

まずは通常のテーブルを使用した状態。
ここからHTML/CSSを修正し、入れ替えていきます。(面積の値は数字、記号の挙動を確認したいため適当です)

HTML

<table>
    <thead>
        <tr><th>県名</th><th>県庁所在地</th><th>面積</th></tr>
    </thead>
    <tbody>
        <tr><td>埼玉</td><td>さいたま</td><td>-</td></tr>
        <tr><td>千葉</td><td>千葉</td><td>-</td></tr>
        <tr><td>神奈川</td><td>横浜</td><td>1</td></tr>
    </tbody>
</table>

CSS

table {
    border : 1px solid;
}
th {
    border : 1px solid;
    background-color : #FF9900;
}
td {
    border : 1px solid;
}

プレビュー

3.テーブルの行列を入れ替える

tableに[-ms-writing-mode: tb-lr;writing-mode: vertical-lr;]を設定します。

CSS

table {
    border : 1px solid;
    -ms-writing-mode : tb-lr;
    writing-mode : vertical-lr;
}
th {
    border : 1px solid;
    background-color : #FF9900;
}
td {
    border : 1px solid;
}

プレビュー

テーブルの行列が入れ替り、文字も縦書きになりました。

4.文字を横書きにする(NG)

th,td要素の中を横書きにしたいので[-ms-writing-mode: lr-tb;writing-mode: horizontal-tb;]を設定すると…

CSS

table {
    border : 1px solid;
    -ms-writing-mode : tb-lr;
    writing-mode : vertical-lr;
}
th {
    border : 1px solid;
    background-color : #FF9900;
    -ms-writing-mode : lr-tb;
    writing-mode : horizontal-tb;
}
td {
    border : 1px solid;
    -ms-writing-mode : lr-tb;
    writing-mode : horizontal-tb;
}

プレビュー

chrome,safariは変化なし…。IEは横書きになったが要素の幅がおかしい。インライン要素のような状態になっています。「3.テーブルの行列を入れ替える」に対してセルの高さを指定して必ず1文字ごとに改行されるようにする手もあるが、半角文字や記号があるとうまく機能しなくなるので他の方法を考えます。

4.文字を横書きにする

th,td要素が[display:table-cell]の状態を保てばよさそう。そこで少々強引ではあるがth,td要素に設定した文字列をspanタグで囲みます。そして、span要素が横書きになるようCSSに「-ms-writing-mode : lr-tb;writing-mode : horizontal-tb;」を設定します。
crhome,IEはこれでOKですがsafariはセルの高さが無くなりテーブルがつぶれてしまいました。そのため少し強引ですがth,td要素に「line-height : 1;height : 1em;」、span要素に「white-space : nowrap;」を設定します。
このあたりは作りたいテーブルに応じて(内容が静的or動的etc)調整してください。

HTML

<table>
    <thead>
        <tr><th><span>県名</th></span><th><span>県庁所在地</th></span><th><span><span>面積</th></span></tr>
    </thead>
    <tbody>
        <tr><td><span>埼玉</td></span><td><span>さいたま</td></span><td><span></td></span></tr>
        <tr><td><span>千葉</td></span><td><span>千葉</td></span><td><span></td></span></tr>
        <tr><td><span>神奈川</td></span><td><span>横浜</td></span><td><span>1</td></span></tr>
    </tbody>
</table>

CSS

table {
    border : 1px solid;
    -ms-writing-mode : tb-lr;
    writing-mode : vertical-lr;
}
th {
    border : 1px solid;
    background-color : #FF9900;
    line-height : 1;
    height : 1em;
}
td {
    border : 1px solid;
    line-height : 1;
    height : 1em;
}
td>span,th>span{
    -ms-writing-mode : lr-tb;
    writing-mode : horizontal-tb;
    white-space : nowrap;
}

プレビュー

幅が少々不ぞろいですが一旦完成。
後は必要に応じて幅やマージン、パディングを調整といったところでしょうか