テキスト省略をCSSで行たい理由
親要素の横幅に収まるように、テキストを三点リーダーで省略したい場合、
CSSで行うのが簡単でシンプルです。
サーバーサイドで文字数を元に切り捨てた場合、HTML上に全文が載らないため、
title属性やその他UIで全文を表示させる時に不便です。
また、レスポンシブの場合は尚更CSSで行えると実装が楽です。
注意
IE11対応とありますが、三点リーダーはIE11では表示されません。(行数で切り捨て表示するのみ)
単一行はCSSのみで実装
単一行の場合は、下記CSSを適用することで、親要素の横幅を超えた分を「...」で省略できます。
こちらはIE11を気にせず使用できます。
p {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
複数行はJavaScriptでCSSを適用する
複数行の場合は上記で対応できないため、-webkit-line-clamp
プロパティを使用します。
-webkit-line-clamp
で指定した値の行数以降(下記だと4行目から)が非表示になり、指定行の最後の文字が「...」になります。
p {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
しかし、line-clamp
自体-webkit-付きでIE11が未対応のため、JavaScriptで-webkit-line-clamp
の対応を判定し、
対応していない場合はheight
を固定にして、overflow-y: hidden;
ではみ出した分を非表示にしたいと思います。
また、JavaScriptでCSSを適用するため、カスタムdata属性で行数を指定できる実装にしておけば、
CSSで行数違いの-webkit-line-clamp: n;
を複数記述する手間もありません。
HTML
幅の基準になる親要素を用意し、その子要素としてテキストを省略する要素を置きます。
data-truncation
属性の値に省略する行数を設定します。
<div class="parent" style="width:300px;">
<p data-truncation="3">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
JavaScript
HTML要素単体(element)と、行数(lineNumber)を引数に持つaddTruncationCSS
関数を作成します。
element.style
オブジェクトにWebkitLineClamp
が存在するかを判定します。
真の場合は、element.style
オブジェクトにline-clamp用のスタイルを適用します。
偽(IE11)の場合は、line-height
と指定された行数の乗算で固定する高さを決めて、height
に指定します。
あとは、querySelectorAll
で要素を取得して、各要素ごとにaddTruncationCSS
関数を実行します。
const addTruncationCSS = (element, lineNumber) => {
if('WebkitLineClamp' in element.style) {
element.style.display = '-webkit-box';
element.style.WebkitLineClamp = lineNumber;
element.style.WebkitBoxOrient = 'vertical';
element.style.overflow = 'hidden';
} else {
// IE11などline-clamp非対応の処理
const limitHeight = parseFloat(getComputedStyle(element).lineHeight) * Number(lineNumber);
element.style.overflowY = 'hidden';
element.style.height = String(limitHeight) + 'px';
}
}
const truncationElements = document.querySelectorAll('[data-truncation]');
if(truncationElements) {
for (const elemet of truncationElements) {
const lineNumber = elemet.dataset.truncation;
addTruncationCSS(elemet, lineNumber);
}
}
以上です。レンダリング時のガタつきが気になる場合は、省略する要素にdisplay: none;
やhidden
属性を付与して、適宜JavaScriptを調整すれば解消できるかと思います。
サンプル
line-clamp
について
ブラウザ対応
ドキュメント
複数行テキスト省略の実装についてより詳しく
Line Clampin' (Truncating Multiple Line Text) | CSS-Tricks
https://css-tricks.com/line-clampin/