【JavaScript】要素が一定数以上ある場合に省略表示する方法

リストやカードが多すぎるとき、最初は数件だけ見せて「もっと見る」で残りを展開する省略表示は、ページをすっきり見せる定番のUIです。

ポイントはボタンのクリックで展開・折りたたみを切り替えることです。単に隠すだけでは「もっと見る」が機能しません。この記事では、実際に動くトグルとして実装する方法を解説します。

この記事の結論:初期表示件数を決めて残りを display: none にし、ボタンのクリックで「もっと見る↔閉じる」を切り替えます。残り件数の表示や、<button>aria-expanded でのアクセシビリティ対応も加えると親切です。
スポンサーリンク

完成イメージ(動くデモ)

↓ ボタンで展開・折りたたみができます:

  • アイテム1
  • アイテム2
  • アイテム3
  • アイテム4
  • アイテム5
  • アイテム6
  • アイテム7
  • アイテム8

基本のHTML

省略したいリストと、「もっと見る」ボタンを用意します。ボタンは <div> ではなく <button> を使い、キーボードでも操作できるようにします。

HTML
<ul id="list">
  <li>アイテム1</li>
  <li>アイテム2</li>
  <!-- ...省略... -->
  <li>アイテム8</li>
</ul>
<button id="toggle" type="button" aria-expanded="false">もっと見る</button>

JavaScriptで「もっと見る/閉じる」を実装

表示件数 VISIBLE を決め、それ以降を display: none に。ボタンのクリックで expanded を反転させ、表示し直します。クリックイベントを必ず付けるのが肝心です(これが無いと「もっと見る」は動きません)。

JavaScript:展開・折りたたみトグル
const list = document.getElementById("list");
const button = document.getElementById("toggle");
const VISIBLE = 5;       // 最初に見せる件数
let expanded = false;

function update() {
  const items = list.children;
  for (let i = 0; i < items.length; i++) {
    items[i].style.display = expanded || i < VISIBLE ? "" : "none";
  }
  const rest = items.length - VISIBLE;
  button.textContent = expanded ? "閉じる" : `もっと見る(残り${rest}件)`;
  button.setAttribute("aria-expanded", String(expanded)); // 状態を支援技術へ
  button.style.display = items.length > VISIBLE ? "" : "none"; // 少なければボタン不要
}

button.addEventListener("click", () => {
  expanded = !expanded;
  update();
});

update(); // 初期表示

aria-expanded を開閉に合わせて更新すると、スクリーンリーダーにも状態が伝わります。要素の表示/非表示の切り替え自体は要素の表示/非表示を切り替える方法、クラスでの制御はclassListの使い方も参考になります。

高さで省略する方法(max-height+グラデーション)

件数ではなく高さで切りたい場合は、max-heightoverflow: hidden を使います。下部にグラデーションをかけると「続きがある」と伝わります。

CSS:高さで省略+グラデーション
.clamp-box {
  max-height: 120px;
  overflow: hidden;
  position: relative;
}
/* 下部にフェードをかけて続きを示す */
.clamp-box::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 40px;
  background: linear-gradient(rgba(255,255,255,0), #fff);
}
.clamp-box.is-open { max-height: none; }     /* 展開時 */
.clamp-box.is-open::after { display: none; }

あとは「もっと見る」ボタンで is-open クラスを classList.toggle() するだけです。

テキストの省略(… / 複数行)

要素の数ではなく1つのテキストが長い場合の省略は、CSSだけでできます。1行なら text-overflow: ellipsis、複数行なら line-clamp を使います。

CSS:テキストの省略
/* 1行で省略(…) */
.ellipsis {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 3行で省略 */
.line-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

text-overflow: ellipsis が効かないときの原因はtext-overflow: ellipsisが効かない原因と解決方法で解説しています。jQueryでの「もっと見る」実装は「もっと見る」で折りたたむ完全ガイドも参考になります。

よくある質問(FAQ)

Q要素の数が一定以上のとき省略表示するには?
A初期表示件数を決め、それ以降を display: none で隠します。「もっと見る」ボタンのクリックイベントで隠した要素を表示し、もう一度押すと閉じるトグル形式が一般的です。
Q「もっと見る」を押しても何も起きません。なぜ?
Aボタンにクリックイベント(addEventListener("click", ...))が付いていないのが原因です。ボタン要素を作るだけでは動かないため、クリック時に表示・非表示を切り替える処理を必ず追加します。
Qテキストが長い場合に省略(…)で表示するには?
ACSSの text-overflow: ellipsisoverflow: hiddenwhite-space: nowrap を組み合わせます。複数行での省略には -webkit-line-clamp を使います。
Q"もっと見る"で段階的に表示する実装のポイントは?
A初期表示数と追加表示数を定数で管理し、クリックのたびに表示数を増やして対象要素の display を変更します。全件表示したらボタンを非表示にする処理も忘れずに追加してください。

まとめ

要素の省略表示は、初期件数だけ表示して残りを display: none にし、ボタンのクリックで展開・折りたたみを切り替えるのが基本です。ボタンにクリックイベントを付けないと機能しない点に注意してください。

残り件数の表示や aria-expanded での状態通知を加えると、より親切なUIになります。高さで切るなら max-height +グラデーション、長いテキスト1つの省略なら ellipsis / line-clamp、と用途で使い分けましょう。