ニュース一覧や記事リストで「最初は数件だけ表示して、残りは「もっと見る」ボタンで展開する」というUIはページをすっきりさせるとともに、ユーザーが必要に応じてコンテンツを取得できる優れたUXパターンです。
この記事ではCSSのnth-child・jQueryのslideToggle・段階的に追加表示する方法まで、用途に合わせた複数の実装パターンを解説します。
この記事でわかること
- CSS nth-child で初期表示件数を制限する
- 「もっと見る」「閉じる」ボタンのテキスト連動
- アイテム数が少ない場合にボタンを非表示にする
- 「もっと見る」を押すたびに数件ずつ追加表示する(段階的表示)
- 完全展開後にボタンを非表示にする
基本実装: CSS + jQuery で折りたたみ
最もシンプルなパターンです。CSSで4件目以降を非表示にし、ボタンクリックで slideToggle() を使って開閉します。
HTML
<ul class="news-list"> <li><span class="news-date">2025年12月01日</span>新機能をリリースしました。</li> <li><span class="news-date">2025年11月15日</span>メンテナンスのお知らせ</li> <li><span class="news-date">2025年10月30日</span>サービス料金を改定しました。</li> <li><span class="news-date">2025年10月01日</span>秋のキャンペーンを開始しました。</li> <li><span class="news-date">2025年09月12日</span>UI/UXをリニューアルしました。</li> <li><span class="news-date">2025年08月25日</span>アプリの最新版を公開しました。</li> </ul> <button class="more-btn">もっと見る</button>
CSS(初期表示を3件に制限)
.news-list > li:nth-child(n+4) {
display: none;
}
JavaScript
$(function () {
// アイテムが3件以下ならボタンを非表示
var limit = 3;
if ($('.news-list > li').length <= limit) {
$('.more-btn').hide();
}
$('.more-btn').on('click', function () {
var isOpen = $(this).hasClass('is-open');
// 4件目以降をslideで開閉
$('.news-list > li:nth-child(n+' + (limit + 1) + ')').slideToggle(300);
// ボタンのテキストと状態を切り替える
$(this)
.text(isOpen ? 'もっと見る' : '閉じる')
.toggleClass('is-open');
});
});
nth-child の番号は 1始まり
:nth-child(n+4) は「4番目以降の要素」を意味します。最初の3件(1・2・3番目)を表示し、4番目以降を隠します。表示件数を5件にしたい場合は :nth-child(n+6) に変更してください。初期表示件数をJavaScriptで制御する(推奨)
CSSではなくJavaScriptで初期表示件数を制御する方法です。WordPressなどで件数を動的に変更したい場合や、スマホとPCで件数を変えたい場合に便利です。
<ul id="news-list"> <li>ニュース1</li> <li>ニュース2</li> <li>ニュース3</li> <li>ニュース4</li> <li>ニュース5</li> <li>ニュース6</li> </ul> <button id="more-btn">もっと見る</button>
$(function () {
var LIMIT = 3; // 初期表示件数
var $items = $('#news-list > li');
var $btn = $('#more-btn');
// 初期状態: LIMIT件目以降を非表示
$items.slice(LIMIT).hide();
// 件数がLIMIT以下ならボタン不要
if ($items.length <= LIMIT) {
$btn.hide();
return;
}
$btn.on('click', function () {
var isOpen = $(this).hasClass('is-open');
if (isOpen) {
// 閉じる: LIMITより後を非表示 + スクロールを先頭へ
$items.slice(LIMIT).slideUp(300);
$(this).text('もっと見る').removeClass('is-open');
} else {
// 開く: 全件表示
$items.slice(LIMIT).slideDown(300);
$(this).text('閉じる').addClass('is-open');
}
});
});
「もっと見る」を押すたびに数件ずつ追加表示する
SNSのタイムラインのように、クリックするたびに数件ずつ追加で表示するパターンです。全件表示後はボタンを非表示にします。
$(function () {
var INITIAL = 3; // 最初に表示する件数
var ADD = 3; // 「もっと見る」で追加する件数
var shown = INITIAL;
var $items = $('#news-list > li');
var $btn = $('#more-btn');
// 初期状態: INITIAL件のみ表示
$items.hide().slice(0, shown).show();
// 全件以下なら最初からボタンを非表示
if ($items.length <= INITIAL) {
$btn.hide();
return;
}
$btn.on('click', function () {
// 次の ADD 件を表示
$items.slice(shown, shown + ADD).slideDown(300);
shown += ADD;
// 全件表示したらボタンを非表示
if (shown >= $items.length) {
$(this).fadeOut(200);
}
});
});
段階的表示 vs 全件開閉 の使い分け
- 段階的表示(追加ロード): ニュース・記事一覧など、戻る必要がない一方向のリスト
- 全件開閉(アコーディオン): FAQ・チームメンバー一覧など、折りたたむことがある場合
CSS トランジションを使ったスムーズなアニメーション
slideToggle() の代わりにCSSトランジションを使うと、より滑らかなアニメーションが実現できます。ただし height: auto はトランジションが効かないため、max-height を使うテクニックを使います。
.news-list > li:nth-child(n+4) {
display: block; /* display:none ではなく */
max-height: 0; /* max-height でアニメーション */
overflow: hidden;
transition: max-height 0.3s ease, opacity 0.3s ease;
opacity: 0;
}
.news-list.is-open > li:nth-child(n+4) {
max-height: 200px; /* 十分に大きな値 */
opacity: 1;
}
$(function () {
$('.more-btn').on('click', function () {
$('.news-list').toggleClass('is-open');
var isOpen = $('.news-list').hasClass('is-open');
$(this).text(isOpen ? '閉じる' : 'もっと見る');
});
});
「もっと見る」とページネーションの比較
| 方式 | メリット | デメリット | 向いているケース |
|---|---|---|---|
| もっと見る(全開閉) | シンプル・折りたたみ可能 | 全件DOMが必要 | ニュース・FAQ・チームページ |
| 段階的追加表示 | 軽い初期ロード・自然なUX | 戻れない(閉じられない) | SNSタイムライン・記事一覧 |
| Ajax追加ロード | 大量データに対応・初期ロード軽い | 実装が複雑・サーバー連携必要 | ECサイト・ブログ一覧 |
| ページネーション | URLで状態共有可能・SEO有利 | ページ遷移が発生 | ブログ・検索結果 |
まとめ
jQueryで「もっと見る」UIを実装する方法を用途によって選びましょう。
- シンプル開閉: CSS
:nth-child(n+4)+slideToggle() - JS管理推奨:
$items.slice(LIMIT).hide()で件数を変数管理 - 段階的表示:
slice(shown, shown + ADD).slideDown()で追加表示 - 全件表示後:
fadeOut()でボタンを非表示 - CSSアニメ:
max-height+ transition でスムーズな開閉
関連記事: アコーディオン完全ガイド / アコーディオン実装方法の完全比較 / ボタンクリックで要素の表示・非表示を切り替える
よくある質問(FAQ)
Q「閉じる」後に先頭へスクロールしたいです。
A閉じるアクション後に
$("html, body").animate({ scrollTop: $("#news-list").offset().top - 20 }, 300) でリストの先頭にスクロールできます。ユーザーが「閉じた後どこを見ていたかわからなくなる」問題を防げます。Qスマホは3件、PCは5件のように件数を変えたいです。
A
var LIMIT = $(window).width() < 768 ? 3 : 5; のように ウィンドウ幅で初期値を変えてください。リサイズ時の対応が必要な場合は$(window).on("resize") でも再計算するとより確実です。QWordPressでカスタムフィールドの件数に応じて動的に制御したいです。
APHPでアイテム数を
data-count 属性などでHTML側に出力し、JavaScriptで parseInt($(el).data("count")) で取得する方法が安全です。または最初からアイテム数を数えて $items.length で判定しても同じことができます。Q開閉状態をページ遷移後も保持したいです(前ページで開いていたら次もopen)。
A
sessionStorage.setItem("newsOpen", "1") で状態を保存し、ページロード時に sessionStorage.getItem("newsOpen") で読み込んで自動展開する方法が使えます。QAjaxで動的にリストを追加した場合はどうすれば良いですか?
AAjaxでアイテムを追加した後、
$items = $("#news-list > li") で変数を取り直し、shown 変数が更新された件数に合わせてボタンの表示・非表示を再判定してください。段階的表示の場合は新しいアイテムだけ非表示にして追加し、ボタンの状態を再チェックします。