th、tdにFlexboxを使うとwidth指定がきかない
この記事は最終更新から4年以上が経過しています。情報が古くなっている可能性があります。
tableタグにFlexboxを適用したところ、Edgeではセル幅がちゃんと確保できず、内容に応じて狭くなってしまう事態が発生。
table-layout:fixedでは対応できなかったので、この事象の原因と対処法をまとめました!
事象
外部システムから発行したHTMLコードを改変せずそのまま使わなきゃいけない箇所があり、以下のHTMLコードを
- はじめの4つの見出し&コンテンツ→横幅50%で横並び
- 後ろ2つの見出し&コンテンツ→横幅100%で縦並び
このように並ばせようとしました。
やりたいレイアウト
適用コード
<table><tbody>
<tr><th>th1</th><td>td1</td></tr>
<tr><th>th2</th><td>td2</td></tr>
<tr><th>th3</th><td>td3</td></tr>
<tr><th>th4</th><td>td4</td></tr>
<tr><th>th5</th><td>td5</td></tr>
<tr><th>th6</th><td>td6</td></tr>
</tbody></table>
tbody { display:flex; flex-wrap:wrap; width: 100%; }
tr { width: 100%; }
tr:nth-child(1),tr:nth-child(2),tr:nth-child(3),tr:nth-child(4) { width: 50%; }
th { width:30%; }
td { width:30%; }
上記を各ブラウザで表示確認したところ、
- (Mac)safari、firefox→問題なし
- (Win)Chrome→問題なし
- (Win)Edge/IE→崩れが発生!
どうやらEdge/IEだけth、tdで指定したwidthがちゃんと効いていない模様。
trのwidth幅は指定通り確保されていましたが、th、tdだけ内容量によって横幅が変わってしまいました。
調べてみると「tableタグでwidth幅が確保できない時はtable-layout:fixedで解決する」という事例が多くありましたが、こちらを試してみても解消せず。
原因
テストコードで各ブラウザの表示を検証してみました。
テストコード
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>テスト</title>
</head>
<body>
<style>
.wrap1,
.wrap2 {display: flex;width: 500px;}
.wrap1 .a,
.wrap1 .b {display: block;}
.wrap2 .a,
.wrap2 .b {display: table-cell;}
.a {width: 30%;background: #ccc;}
.b {width: 70%;background: #aaa;}
</style>
<h1>テスト</h1>
<h2>普通にブロック指定</h2>
<div class="wrap1">
<div class="a">a1a1a1a1a1a1a1a1</div>
<div class="b">b1b1b1b1b1b1b1b1</div>
</div>
<h2>子要素をtable-cell指定</h2>
<div class="wrap2">
<div class="a">a2a2a2a2a2a2a2a2</div>
<div class="b">b2b2b2b2b2b2b2b2</div>
</div>
</body></html>
子要素divを2つ持つ、親要素divのセットを2セット用意。
この事象がtableタグならではかどうかの切り分けをするため、後者のdivの子要素には「display: table-cell;」を指定してみました。
結果
(Mac)safari、chrome、firefox、(Win)chrome→問題なし
(Win)Edge→横幅とれず!
つまり、flex-itemがtable-cellの場合、Edge/IEではwidth指定がきかなくなるということのようです。
解決
この崩れが起きた場合は、display: table-cellになっている子要素をdisplay:blockにすることで解消することができました。
基本的に横並びにしたい!という時にフレックスボックスとテーブルレイアウトを同時に使うことはないと思います。
なので、特にtableタグをflexでこねくり回したいという時にはご注意ください。