table で text-overflow: ellipsis; したい
◆ div と span で囲んで position + flexbox
◆ table-layout: fixed
◆ table-layout: fixed
table の td の中にながーいテキストがあるときに 最後を … にしたいです
text-overflow: ellipsis; でいいはずなのですが td の中だとだめです
これだと table の幅が 600px を超えて全く省略されません
div に囲むと 600px に収めようと頑張って 「短いテキスト」 のほうが縦に一文字ずつになりました
でも まだ 600px をオーバーしています
「長ああああい」 の方は全く省略されずに横に並んでます
これだとうまく table が 600px になって「長あああああい」 のところは … で省略されます
ですが position:absolute にしているので table の自動で中央揃えになる機能が効きません
td>div>span と長くなりましたが これだとちゃんと中央揃えに来てくれます
しかしまだ一部問題があって IE11 では動きません
IE を捨ててるならこれでいいのですけど 古いブラウザも対応が必要になった場合には使えないです
原因は position:aboslute の div の height が IE では td と同じにならないからです
JavaScript で強制的に td の height を div にも height 指定するか flexbox 以外の方法を使うことになります
なので別の方法も考えてみます
そもそもの問題は td が指定した長さから 勝手にかわることです
これを固定するために table-layout: fixed; を使います
こっちはシンプルですが 長あああああああいテキストが … になります
ただ こっちも少し問題点があります
table に対して width 決めておけば td の width は適当でもいい感じにやってくれるので ここでは両方 300px にしてます
正確な幅を書くなら もう少し小さくしないと padding やセル間の隙間があって合計が 600px を超えてしまいます
固定してしまうと td が 300px になるので 600px に収まるように調整はされず 600px よりちょっと大きな table サイズになります
610px くらい
table-layout: fixed; を使うなら td の幅計算もしっかりしないといけないです
列幅が行の追加で変化してくれない問題もあります
後から行を追加したときに その行のことは考えずに 最初に決まった列幅がずっと固定です
最初は空 table で JavaScript で行を追加する場合は列の位置が全部左端にいておかしな表示になっていまします
また table が % 指定になっていて 他の列に値が入った後の残りのスペース全部を使いたい時に その td に width: 100% としておけば table の width になるように自動で残りスペースを計算してくれますが table-layout: fixed; だと他の列に width が設定されてないと 0px 扱いで計算されて列の表示が被ることもでてきます
自動調整機能がなくなるのですから div のみで作るような状態ですね
なので table-layout: fixed; にすれば解決 とも言えない微妙なところです
実際に動くサンプルページ
text-overflow: ellipsis; でいいはずなのですが td の中だとだめです
普通に書くと
table{
width: 600px;
border: 1px solid #66e;
}
tr{
height: 60px;
}
.t1 td{
width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
width: 600px;
border: 1px solid #66e;
}
tr{
height: 60px;
}
.t1 td{
width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<table class="t1">
<tr>
<td>短いテキスト</td>
<td>長ああああああああああああああああああああああああああああああああいテキスト</td>
</tr>
</table>
<tr>
<td>短いテキスト</td>
<td>長ああああああああああああああああああああああああああああああああいテキスト</td>
</tr>
</table>
これだと table の幅が 600px を超えて全く省略されません
div に囲んでみる
.t2 td{
width: 300px;
}
.t2 td div{
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
width: 300px;
}
.t2 td div{
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<table class="t2">
<tr>
<td>短いテキスト</td>
<td>
<div>
長ああああああああああああああああああああああああああああああああいテキスト
</div>
</td>
</tr>
</table>
<tr>
<td>短いテキスト</td>
<td>
<div>
長ああああああああああああああああああああああああああああああああいテキスト
</div>
</td>
</tr>
</table>
div に囲むと 600px に収めようと頑張って 「短いテキスト」 のほうが縦に一文字ずつになりました
でも まだ 600px をオーバーしています
「長ああああい」 の方は全く省略されずに横に並んでます
position つけてみる
td の幅を 300px と書いても 内側の要素で変わってしまうので 中の要素のサイズで計算されないように position を使います.t3 td{
width: 300px;
position: relative;
}
.t3 td div{
position: absolute;
top: 0;
left: 0;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
width: 300px;
position: relative;
}
.t3 td div{
position: absolute;
top: 0;
left: 0;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<table class="t3">
<tr>
<td>短いテキスト</td>
<td>
<div>
長ああああああああああああああああああああああああああああああああいテキスト
</div>
</td>
</tr>
</table>
<tr>
<td>短いテキスト</td>
<td>
<div>
長ああああああああああああああああああああああああああああああああいテキスト
</div>
</td>
</tr>
</table>
これだとうまく table が 600px になって「長あああああい」 のところは … で省略されます
ですが position:absolute にしているので table の自動で中央揃えになる機能が効きません
flexbox も使う
センタリングは仕方ないので自分でやります.t4 td{
width: 300px;
position: relative;
}
.t4 td div{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
}
.t4 td div span{
margin: auto;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
width: 300px;
position: relative;
}
.t4 td div{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
}
.t4 td div span{
margin: auto;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<table class="t4">
<tr>
<td>短いテキスト</td>
<td>
<div><span>
長ああああああああああああああああああああああああああああああああいテキスト
</span></div>
</td>
</tr>
</table>
<tr>
<td>短いテキスト</td>
<td>
<div><span>
長ああああああああああああああああああああああああああああああああいテキスト
</span></div>
</td>
</tr>
</table>
td>div>span と長くなりましたが これだとちゃんと中央揃えに来てくれます
しかしまだ一部問題があって IE11 では動きません
IE を捨ててるならこれでいいのですけど 古いブラウザも対応が必要になった場合には使えないです
原因は position:aboslute の div の height が IE では td と同じにならないからです
JavaScript で強制的に td の height を div にも height 指定するか flexbox 以外の方法を使うことになります
table-layout:fixed
IE はなかったコトにして Chrome や Firefox では動きましたが ちょっとコードが長くなってますなので別の方法も考えてみます
そもそもの問題は td が指定した長さから 勝手にかわることです
これを固定するために table-layout: fixed; を使います
.t5{
table-layout: fixed;
}
.t5 td{
width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
table-layout: fixed;
}
.t5 td{
width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<table class="t5">
<tr>
<td>短いテキスト</td>
<td>
長ああああああああああああああああああああああああああああああああいテキスト
</td>
</tr>
</table>
<tr>
<td>短いテキスト</td>
<td>
長ああああああああああああああああああああああああああああああああいテキスト
</td>
</tr>
</table>
こっちはシンプルですが 長あああああああいテキストが … になります
ただ こっちも少し問題点があります
table に対して width 決めておけば td の width は適当でもいい感じにやってくれるので ここでは両方 300px にしてます
正確な幅を書くなら もう少し小さくしないと padding やセル間の隙間があって合計が 600px を超えてしまいます
固定してしまうと td が 300px になるので 600px に収まるように調整はされず 600px よりちょっと大きな table サイズになります
610px くらい
table-layout: fixed; を使うなら td の幅計算もしっかりしないといけないです
列幅が行の追加で変化してくれない問題もあります
後から行を追加したときに その行のことは考えずに 最初に決まった列幅がずっと固定です
最初は空 table で JavaScript で行を追加する場合は列の位置が全部左端にいておかしな表示になっていまします
また table が % 指定になっていて 他の列に値が入った後の残りのスペース全部を使いたい時に その td に width: 100% としておけば table の width になるように自動で残りスペースを計算してくれますが table-layout: fixed; だと他の列に width が設定されてないと 0px 扱いで計算されて列の表示が被ることもでてきます
自動調整機能がなくなるのですから div のみで作るような状態ですね
なので table-layout: fixed; にすれば解決 とも言えない微妙なところです
サンプル
上のコードを Chrome で実行した場合の画像がこちらです実際に動くサンプルページ