三点リーダー(text-overflow: ellipsis)の適用を判定する方法と注意点
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- テキストがはみ出すことを防ぐ
- 文が終わりではないことを示す
ために三点リーダーを適用することがあるかと思います。
しかし、ただ適用しただけでは三点リーダーによって省略された記述の情報が抜け落ちてしまいます。
この問題を解決するために、三点リーダーが適用される場合のみ
- hover時にTooltipを表示する
- focus時に全文表示させる(レイアウトシフトに注意)
などを行うことで、ユーザに抜け落ちた情報を届けることができます。
この記事では、この機能を実現するためのoverflowの判定方法と注意点を説明していきます。
overflowの判定方法
判定するには HTMLElement.offsetWidth
と Element.scrollWidth
の値を比較する必要があります。
element.offsetWidth < element.scrollWidth
三点リーダーが適用されていれば、この条件式が true
になります。
overflowの判定での注意点
しかし、実装する上で注意することが2つあります。
左右のborderの幅
条件式の左辺で用いた HTMLElement.offsetWidth
が要素に対する何の値であるかを示した図です。
MDN Web Docs (offsetWidthの例)
HTMLElement.offsetWidth
は border を含むプロパティであることが読み取れます。
そのため、左右のborder幅を適用している場合は、その幅だけ offsetWidth から引いてあげる必要があります。
element.offsetWidth - (BORDER_LEFT_WIDTH + BORDER_RIGHT_WIDTH) < element.scrollWidth
三点リーダーが適用されているのに判定がfalseになる
こちらは多少厄介な問題です。
三点リーダーが表示されない(幅に対してテキストの方が短い)場合、offsetWidth
と scrollWidth
の値は同じになります。
しかし、以下のGIFの3つ目のテキストのように 三点リーダーが適用されているのに判定がfalseになる 場合があります。
なぜこのような現象が起きるかというと、scrollWidth
は値を丸めて整数にしているためです。
このときのそれぞれの値はどうなっているかですが width: 100px
とすると
- offsetWidth: 100px
- scrollWidth: 100px(本当は 100.25px といった値)
のようになっています。
この結果、三点リーダーが適用されているのに判定がfalseになる のです。
今回使用したコードは以下に置いておきます。
この記事を書いてて、(たぶんレンダリングエンジンが担ってる)三点リーダーを適用するしないの判定処理についても深ぼりたいなと思いました。
Element.getBoundingClientRect
を使用すれば小数点を含む offsetWidth
が取得できるのですが、丸める前の scrollWidth
は取得できなそうなので取得できる方法があればコメントで教えていただけたらと思います。
Discussion