CSS の line-clamp で複数行テキストを省略表示する
カード UI やニュース一覧で、長いテキストを 2〜3 行だけ表示して末尾を「…」で省略する処理はよく使われます。1 行の省略なら text-overflow: ellipsis で対応できますが、複数行の省略には別のアプローチが必要です。CSS の line-clamp を使えば、JavaScript なしで複数行の省略表示を実現できます。
1 行省略のおさらい
複数行の省略に入る前に、1 行だけの省略を確認しておきましょう。
.single-line {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}この 3 つのプロパティはセットで使います。white-space: nowrap でテキストの折り返しを禁止し、overflow: hidden ではみ出した部分を非表示にし、text-overflow: ellipsis で末尾に「…」を表示するという仕組みです。ただしこの方法は 1 行限定であり、2 行以上の省略には対応できません。
-webkit-line-clamp による複数行省略
複数行の省略には、-webkit-line-clamp を中心とした一連のプロパティを使います。
.multi-line {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}この 4 つのプロパティで、テキストが 3 行を超えた場合に末尾を「…」で省略する表示になります。
<div class="demo-wrap">
<div class="demo-card">
<p class="clamp-text">CSSのline-clampを使うと、複数行のテキストを指定した行数で切り詰めて末尾に省略記号を表示できます。カードUIやニュース一覧など、限られたスペースに長いテキストを収めたい場面で非常に便利です。JavaScriptを使わずにCSSだけで実現できるため、実装もシンプルになります。</p>
</div>
<div class="demo-card">
<p class="no-clamp">CSSのline-clampを使うと、複数行のテキストを指定した行数で切り詰めて末尾に省略記号を表示できます。カードUIやニュース一覧など、限られたスペースに長いテキストを収めたい場面で非常に便利です。JavaScriptを使わずにCSSだけで実現できるため、実装もシンプルになります。</p>
</div>
</div>.demo-wrap {
display: flex;
gap: 12px;
}
.demo-card {
flex: 1;
padding: 12px;
border: 1px solid #e5e7eb;
border-radius: 8px;
}
.clamp-text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
font-size: 13px;
line-height: 1.7;
color: #374151;
margin: 0;
}
.clamp-text::before {
content: "3行で省略";
display: block;
font-size: 11px;
color: #6366f1;
margin-bottom: 4px;
font-weight: bold;
}
.no-clamp {
font-size: 13px;
line-height: 1.7;
color: #374151;
margin: 0;
}
.no-clamp::before {
content: "省略なし";
display: block;
font-size: 11px;
color: #9ca3af;
margin-bottom: 4px;
font-weight: bold;
}左のカードは 3 行で省略され末尾に「…」が表示されています。右は同じテキストをそのまま表示した場合です。
各プロパティの役割
4 つのプロパティにはそれぞれ明確な役割があります。
要素を WebKit 独自のフレックスボックスとして扱います。通常の display: flex とは異なる旧仕様のレイアウトモデルで、-webkit-line-clamp が機能するために必要です。
ボックス内の子要素を縦方向に配置します。これにより行の概念が生まれ、行数による切り詰めが可能になります。
表示する最大行数を指定します。N 行を超えるテキストは非表示になり、末尾に省略記号が付きます。
N 行を超えた部分を実際に非表示にします。これがないと、行数制限の指定にかかわらずテキストが全行表示されてしまいます。
-webkit プレフィックスが付いている理由
プロパティ名に -webkit- が付いていることに違和感を覚えるかもしれません。これはもともと WebKit エンジン独自の実装として導入された経緯があるためです。しかし現在では Chrome、Firefox、Safari、Edge のすべてのモダンブラウザがこの記法をサポートしており、事実上の標準となっています。
CSS の仕様策定を行う W3C は、この機能を正式に標準化するため line-clamp プロパティを提案しています。
CSS Overflow Module Level 4 で定義が進められているが、2024 年時点でまだ草案段階。
将来的には -webkit- プレフィックスなしの line-clamp が使えるようになる見込みですが、現時点では -webkit-line-clamp を使うのが確実です。
line-clamp と height の違い
テキストの表示行数を制限する方法として、max-height と overflow: hidden を組み合わせる手法もあります。
行数ベースで制限する。末尾に「…」が自動で付く。行の途中でテキストが切れることがない。
高さベースで制限する。省略記号は自動で付かない。line-height との計算が合わないと行の途中でテキストが切れてしまう。
max-height で制限する場合は、line-height × 表示行数 を正確に計算して指定する必要があります。フォントサイズや行間を変更するたびに max-height も修正しなければならず、保守性が下がります。さらに省略記号を自分で付ける必要もあるため、line-clamp のほうが圧倒的に手軽です。
Flexbox や Grid の子要素で使うときの注意
line-clamp は Flexbox や Grid の子要素に適用するとき、意図どおりに動かないケースがあります。Flex アイテムはデフォルトで min-width: auto が適用されるため、テキストがコンテナからはみ出してしまうことがあるのです。
.flex-container {
display: flex;
gap: 16px;
}
.flex-item {
min-width: 0;
}
.flex-item .text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}min-width: 0 を Flex アイテムに指定することで、子要素がコンテナの幅を尊重するようになり、line-clamp が正しく機能します。Grid レイアウトでも同様に min-width: 0 が有効です。
Flex アイテムの min-width がデフォルトで auto
テキストが縮まらずコンテナからはみ出す
min-width: 0 を指定して解決
カード UI での実践例
実際のプロジェクトでよく見かけるカード UI に line-clamp を適用してみましょう。タイトルは 1 行、説明文は 2 行で省略するパターンです。
.card-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16px;
font-weight: bold;
}
.card-desc {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
font-size: 14px;
color: #6b7280;
}タイトルには従来の 1 行省略、説明文には line-clamp による 2 行省略を使い分けています。こうすることで、カードの高さが一定に保たれ、一覧画面のレイアウトが崩れません。
<div class="card-grid">
<div class="pcard">
<div class="pcard-title">CSSのline-clampで複数行テキストを省略表示する方法</div>
<div class="pcard-desc">line-clampを使うと複数行のテキストを指定した行数で切り詰めて末尾に省略記号を表示できます。カードUIやニュース一覧で便利です。</div>
</div>
<div class="pcard">
<div class="pcard-title">短いタイトル</div>
<div class="pcard-desc">短い説明文です。</div>
</div>
<div class="pcard">
<div class="pcard-title">FlexboxやGridの子要素で使うときはmin-widthに注意</div>
<div class="pcard-desc">Flexアイテムはデフォルトでmin-width: autoが適用されるため、テキストがコンテナからはみ出してしまうことがあります。min-width: 0を指定することで解決できます。</div>
</div>
</div>.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.pcard {
padding: 12px;
border: 1px solid #e5e7eb;
border-radius: 8px;
min-width: 0;
}
.pcard-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 14px;
font-weight: bold;
color: #111827;
margin-bottom: 6px;
}
.pcard-desc {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
font-size: 12px;
color: #6b7280;
line-height: 1.6;
margin: 0;
}3 枚のカードが同じ高さで並び、テキスト量に関係なくレイアウトが統一されています。Grid の子要素に min-width: 0 を指定しているのもポイントです。
line-clamp は記法こそベンダープレフィックス付きで少し変わっていますが、すべてのモダンブラウザで安定して動作します。カード UI やリスト表示など、テキストの長さが不定な場面では積極的に活用してみてください。