chocolat

tips_javascript

テキスト省略時の text-overflow: ellipsis の適用を判定する方法(複数行)

September 15, 2022

css で長い文章を省略するときに text-overflow: ellipsis を使用して省略部分に「…」(三点リーダー)などを表示することができます。

省略されているときのみツールチップで全文が表示されるようにしたいといった場合に、JavaScript で text-overflow: ellipsis が適用されているかどうかを判定する必要があります。

1行の場合は HTML text-overflow ellipsis detection の回答にある方法で実現できますが、テキストが複数行になる場合は少し変更が必要です。

作成済みのデモはこちらです。ソースコードの全体はこちらでご確認ください。
デモ(CodePen)

実現したいこと

  • テキストが指定より長い場合は省略して、末尾に省略記号「…」が表示される
  • テキストが省略されている場合のみツールチップが表示される

html を用意する

中にテキストを持つカードが並ぶレイアウトです。
テキストは2行以下と3行(省略あり・なし)の3種類を用意しました。

<div class="card-list">
  <div class="block">
    <p class="text">この文章はダミーです。文字の大きさ、量、字間、行間</p>
  </div>

  <div class="block">
    <p class="text">この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、</p>
  </div>

  <div class="block">
    <p class="text">この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文</p>
  </div>
</div>

css でテキストが指定より長い場合は省略する

1行のみで省略する場合は以下の指定で省略できます。

white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

複数行の場合は以下のように指定します( -webkit-line-clamp の数字が行数になります)。

overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;

JavaScript で text-overflow: ellipsis が適用されているか判定する

text-overflow: ellipsis が適用されるのは、要素の中身が指定よりも大きい場合です。
要素の中身(テキスト全体)が、要素を表示する領域(cssで指定した3行分の高さ)よりも大きい場合は true を返すようにします。

要素の中身の高さを Element.scrollHeight 、要素を表示する領域の高さを Element.offsetHeight でそれぞれ取得して比較します。

テキスト要素を受け取り、 text-overflow: ellipsis が適用されているかを判定して truefalse を返す関数を作成します。

const isEllipsisActive = (el) => {
  return (el.offsetHeight < el.scrollHeight);
}

この関数をテキスト要素(サンプルの .text )をひとつずつ渡して実行します。

const elements = document.querySelectorAll('.text');

elements.forEach((el) => isEllipsisActive(el));

text-overflow: ellipsis が適用されている場合はツールチップを表示する

ツールチップは HTMLElement.title を使用します。 html 要素に title="このテキストがツールチップとして表示されます。" のように指定します。

通常、テキストは、マウスがノード上にあるときに「ツールチップ」ポップアップに表示されます。
HTMLElement.title - Web API | MDNより引用

先ほどの関数で true が返る場合のみ、html に title 要素を追加します。

elements.forEach((el) => {
  if(isEllipsisActive(el)) {
    // テキスト全文を取得
    const text = el.textContent;
    // テキスト全文を title と共に追加
    el.setAttribute('title', text);
  }
});

デモ

デモでは text-overflow: ellipsis の判定の関数の結果を Console に書き出すようにしているので、Console を開いて正しく判定されているか確認してみてください。

CodePen で「テキスト省略時の text-overflow: ellipsis の適用を判定する方法(複数行)」のデモを見る

参照