由于開発されたモバイルアプリには国際化が含まれているため、マイナーな言語では表示が切れたりスタイルが崩れたりする問題が発生することがあります。この場合、スタイルのレベルで問題を解決する必要があります。たとえば、1 行を超える場合には省略記号を表示するなど、これは非常に簡単に解決でき、互換性も非常に良いです。
max-width: 3rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
しかし、2 行以上のテキストを省略記号で切り捨てる場合は、やや複雑になります。いくつかの CSS プロパティを使用して、複数行の切り捨て問題を解決することができます。
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
上記のコードは Chrome ブラウザでは実際の要件を満たすことができますが、アプリ内で実行し、対応する Web ビューを開くと、実際の要件を満たすことができないことがわかります。互換性の問題がかなりありますので、この方法では要件を完全に解決することはできません。このドキュメントを参考に、さまざまな解決策が提供されています。
多行テキストの省略表示 (...) の完全なガイド - WEB フロントエンド開発
実際のシナリオでは、JavaScript
を使用して要件を解決することができますが、CSS だけで完璧に要件を解決することができるかどうかについて、私は記事を見つけました。記事では、テキストの切り捨てをどのように CSS で解決するかについて説明しており、いくつかの方法が紹介されていますが、私は最後の方法が私の要件を完璧に解決していると思います。以下は記事で言及されている方法です:
float 特性を使用した複数行テキストの切り捨て#
最初にやりたいことは、複数行のタイトルテキストの切り捨て効果ですが、明らかにタイトルの長さを制御することはできませんので、上記の方法は使用できません。問題の本質に戻って考えてみると、テキストがオーバーフローした場合に省略記号を表示し、オーバーフローしない場合には省略記号を表示しないようにしたいと考えています。(2 つの形式、2 つの効果)
CSS がもうすでに無力で、JS で実現するしかないと思っていたとき、非常に巧妙な方法を見つけました。そして、上記で述べたすべての基準を満たすことができます。以下では、float 特性を使用して複数行テキストの切り捨て効果を実現する方法について説明します。
基本原理:
3 つのボックスがあり、ピンクのボックスは左に浮動し、浅い青のボックスと黄色のボックスは右に浮動します。
- 浅い青のボックスの高さがピンクのボックスよりも低い場合、黄色のボックスは浅い青のボックスの右下に位置します。
- 浅い青のボックスのテキストが多すぎて、ピンクのボックスの高さを超える場合、黄色のボックスは右下に停止せず、ピンクのボックスの下に移動します。
これで、2 つの状態の 2 つの表示形式が区別されました。したがって、黄色のボックスを相対位置に設定し、オーバーフローしたコンテンツの黄色のボックスをテキストコンテンツの右下に移動し、オーバーフローしない場合は外部に移動することができます。overflow: hidden
を使用するだけで非表示にすることができます。
基本的な原理はこれです。浅い青い領域をタイトルとし、黄色の領域を省略記号の効果と考えることができます。ピンクのボックスがスペースを占めているので、タイトルが全体的に後ろに移動することはありません。これは、浅い青いボックスのmargin-left
にピンクのボックスの幅と同じ負の値を設定することで実現できます。
それでは、前述の DOM 構造を簡略化し、次のように変更します:
<div class="wrap">
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos labore sit vel itaque delectus atque quos magnam assumenda quod architecto perspiciatis animi.</div>
</div>
先ほどのピンクのボックスと黄色のボックスは、疑似要素を使用して代替することができます。
.wrap {
height: 40px;
line-height: 20px;
overflow: hidden;
}
.wrap .text {
float: right;
margin-left: -5px;
width: 100%;
word-break: break-all;
}
.wrap::before {
float: left;
width: 5px;
content: '';
height: 40px;
}
.wrap::after {
float: right;
content: "...";
height: 20px;
line-height: 20px;
/* 三つの省略号の幅 */
width: 3em;
/* ボックスがスペースを占めないようにする */
margin-left: -3em;
/* 省略号の位置を移動する */
position: relative;
left: 100%;
top: -20px;
padding-right: 5px;
}
実装効果:デモのリンク
これは私が見た中で最も巧妙な方法です。CSS 2.1 の機能のみをサポートすれば十分です。その利点は次のとおりです:
- 互換性が高く、主要なブラウザに対して良好なサポートがあります。
- レスポンシブな切り捨てで、異なる幅に対応します。
- テキストが範囲外にある場合にのみ省略記号を表示し、それ以外の場合は省略記号を表示しません。
欠点としては、省略記号をシミュレートしているため、表示位置が完全に合わない場合があることです。したがって、次のことを考慮することができます:
- グラデーション効果を追加し、テキストにフィットさせることができます。上記のデモ効果と同様です。
word-break: break-all;
を追加して、単語を改行時に分割できるようにすることで、テキストと省略記号のフィット効果をより向上させることができます。
しかし、実際の使用中に、.wrap::after
のtop: -20px
はwrap
に対して上方向にオフセットされていることがわかりました。記事の例とは異なり、例では下方向にオフセットされています。最終的に、この問題を解決するために、wrap
にbox-sizing: content-box;
を追加しました。おそらく、自分のプロジェクトのレイアウトが影響しているのかもしれませんが、なぜこのようになるのかはまだわかりません。