モバイルサイトは画面の大きさも限られており、できるだけ多くの情報を表示するために、文章を一部だけ表示して、一覧表示したいことがあるでしょう。
文章の量によりレイアウトが乱れてしまうことを避けたい場合にも有効です。
文章を省略することや、省略されている文章があることを示す記号をエリプシス(ellipsis)といい、三点リーダーで表します。
Javascriptを利用する方法や、CSSのafter疑似要素を利用する方法などもありますが、CSS3だけで出来る方法を段階的にご紹介します。
なお、サンプルはiOS Safari(webkit)でしか動作確認していませんので、ご了承ください。
サンプルリストアイテム
以下のようなサムネイル画像とタイトル、説明文があるシンプルなリストアイテムを定義します。
このままだと、左のサムネイルの高さをはみだして説明文があふれています。
スタイルシート
/* * リセット */ * { margin : 0; padding : 0; } body, h2 { font: 12px/1.5 "ヒラギノ角ゴ Pro W3" } /* * リストアイテム */ .list-item { width: 320px; display: -webkit-box; } .list-item img { width: 120px; height: 100px; margin: 5px; } .list-item .desc { width: 175px; margin: 5px 10px 5px 5px; } .list-item .desc h2 { font-weight: bold; } .list-item .desc p { }
HTML
<div class="list-item"> <img src="//placehold.it/120x100&text=ellipsis" /> <div class="desc"> <h2>ellipsisとは省略のこと</h2> <p>文章の量でレイアウトがくずれないように、あらかじめきめられた文字数や行数で、文章を省略します。三点リーダーを表示することで、以降にまだ文章があることを示します。</p> </div> </div>
あふれた文字を隠す
もっとも簡単にあふれた文字を隠すのは、heightを固定して、overflow:hiddenを設定することです。しかし、行が欠けてしまっていて、あまり見栄えがよくありません。
スタイルシート
.style1 .desc { height: 100px; overflow: hidden; }
HTML
<div class="list-item style1"> <img src="//placehold.it/120x100&text=style1" /> <div class="desc"> <h2>overflowで省略</h2> <p>文章の量でレイアウトがくずれないように、あらかじめきめられた文字数や行数で、文章を省略します。三点リーダーを表示することで、以降にまだ文章があることを示します。</p> </div> </div>
あふれた文字を隠す(行が欠けないように)
高さを正確に指定してやると、行が欠けることはありません。サンプルのスタイルでは、行高は文字サイズである12pxの1.5倍ですから、18pxです。説明文に4行とるなら、72pxあればいいことになります。これできれいに省略することができました。
基本となる行高が変わると、修正する箇所が増えて保守性が下がります。こういうときは、CSSプリプロセッサを利用するとよいでしょう(参考記事:「Stylusを使って、iOS retina対応のCSSスプライトを作る」)。
スタイルシート
.style2 .desc p { height: 72px; overflow: hidden; }
HTML
<div class="list-item style2"> <img src="//placehold.it/120x100&text=style2" /> <div class="desc"> <h2>overflowで省略</h2> <p>文章の量でレイアウトがくずれないように、あらかじめきめられた文字数や行数で、文章を省略します。三点リーダーを表示することで、以降にまだ文章があることを示します。</p> </div> </div>
説明文に…を付加する
省略された説明文の最後に…を付加して、続きがあることを表します。説明文は最大4行ですから、4行目にline-clampを付加します。クランプとは締め具のことですが、紙にクリップをつけるようなことを想像すればよいでしょう。line-clampは特に文字を隠す属性ではなく、単に指定した行にクランプ文字(…)をつけるだけのようです。ですから、overflow:hiddenがなければ、単に指定行の行末に…が重なります。
スタイルシート
-weblit-line-clampを有効にするには、display:-webkit-box,-webkit-box-orient:verticalも同時に設定する必要があるようです。
.style3 .desc p { height: 72px; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; }
HTML
<div class="list-item style3"> <img src="//placehold.it/120x100&text=style3" /> <div class="desc"> <h2>overflowで省略</h2> <p>文章の量でレイアウトがくずれないように、あらかじめきめられた文字数や行数で、文章を省略します。三点リーダーを表示することで、以降にまだ文章があることを示します。</p> </div> </div>
タイトルに…を付加する
複数行を一行で省略したいだけなら、text-overflowを設定します。text-overflowは一行に省略したいとき、white-spaceと同時に指定します。
スタイルシート
.style4 .desc h2 { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .style4 .desc p { height: 72px; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; }
HTML
<div class="list-item style4"> <img src="//placehold.it/120x100&text=style4" /> <div class="desc"> <h2>text-overflowで長いタイトルを省略</h2> <p>文章の量でレイアウトがくずれないように、あらかじめきめられた文字数や行数で、文章を省略します。三点リーダーを表示することで、以降にまだ文章があることを示します。</p> </div> </div>
全体5行でタイトル行2行+説明文3行
もう少し、ややこしい省略をしたい場合の例をご紹介します。全体の行数をタイトルと説明文で二分するとき、タイトルが1行+説明文4行、タイトルが2行+説明文3行の合計5行までとしたい場合の例です。残念ながら、この省略ではCSSのみで…をつけることができませんでした。
かならず…がついてよいなら、after疑似要素でできそうです。またJavascriptで文章の高さから、行数を算出し、最終行にline-clampすればできそうです。
将来、line-clampやtext-overflowのオプション、または組み合わせで、複数行の行末にellipsisがつけられるようにならないかなと個人的には考えています。
スタイルシート
タイトルと説明文を囲むdivに対してheightを固定し、その中のh2,pには、max-heightで最大高を指定します。h2の高さは最大2行分(18*2=36px)とし、pの高さは最大4行分(18*4=72px)としておきます。
.style5 .desc { height: 90px; overflow: hidden; } .style5 .desc h2 { max-height: 36px; overflow: hidden; } .style5 .desc p { max-height: 72px; overflow: hidden; }
HTML
<div class="list-item style5"> <img src="//placehold.it/120x100&text=style5-1" /> <div class="desc"> <h2>全体5行のうち、タイトルが最大2行で、残りが説明文の行数とする場合</h2> <p>文章の量でレイアウトがくずれないように、あらかじめきめられた文字数や行数で、文章を省略します。三点リーダーを表示することで、以降にまだ文章があることを示します。</p> </div> </div>
全体5行でタイトル行1行+説明文4行
さきほどと同じスタイルで文章量を変更して、タイトル1行+説明文4行にします。
<div class="list-item style5"> <img src="//placehold.it/120x100&text=style5-2" /> <div class="desc"> <h2>全体5行、タイトルが1行</h2> <p>文章の量でレイアウトがくずれないように、あらかじめきめられた文字数や行数で、文章を省略します。三点リーダーを表示することで、以降にまだ文章があることを示します。</p> </div> </div>
長い単語の折り返し
最後に省略とは直接関係ないですが、長い単語の折り返し方法をご説明します。和文のなかに欧文単語があると、単語の途中で改行してほしいと思うことがあるでしょう。overflow-wrap(旧word-wrap)とword-breakを利用する方法をご紹介します。
何も指定しないと長い単語(TheQuickBrownFoxJumpsOverTheLazyDog)は、overflow:hiddenが効いているので、あふれてしまいます。
スタイルシート
.style6 .desc { height: 100px; overflow: hidden; }
HTML
<div class="list-item style6"> <img src="//placehold.it/120x100&text=style6" /> <div class="desc"> <h2>長い単語の折り返し</h2> <p>たとえば、TheQuickBrownFoxJumpsOverTheLazyDogという単語があると、このように表示されます。</p> </div> </div>
長い単語の折り返し(overflow-wrap)
overflow-wrap:break-wordの単語の折り返しの特徴は、一旦改行されたのち、単語の途中で改行されるところです。また、ある程度禁則ルールが適用されるので、禁則ルールをできるだけ残したいならoverflow-wrapを利用する方がよいでしょう。
「表示されます」の「ま」の後で改行されているのは、「す」の後で改行すると、行頭に行頭禁則文字である句読点「。」がくるので、「ま」の後で改行されています。ぶら下げや行揃えもしてもらえると、もっときれいなんでしょうけどね。
スタイルシート
.style7 .desc { height: 100px; overflow: hidden; overflow-wrap: break-word; }
HTML
<div class="list-item style6"> <img src="//placehold.it/120x100&text=style6" /> <div class="desc"> <h2>長い単語の折り返し</h2> <p>たとえば、TheQuickBrownFoxJumpsOverTheLazyDogという単語があると、このように表示されます。</p> </div> </div>
長い単語の折り返し(word-break)
word-break:break-allの単語の折り返しの特徴は、一旦の改行はなしにバッサリと改行してくれるところです。禁則とか気にせず、とにかく改行したいときは、こちらの方がよいでしょう。
スタイルシート
.style8 .desc { height: 100px; overflow: hidden; word-break: break-all; }
HTML
<div class="list-item style8"> <img src="//placehold.it/120x100&text=style6" /> <div class="desc"> <h2>長い単語の折り返し</h2> <p>たとえば、TheQuickBrownFoxJumpsOverTheLazyDogという単語があると、このように表示されます。</p> </div> </div>
最後に、これらのサンプルコードをgistに置いておきますので、ご利用ください。
単に表示を確認したいなら、こちらで。