最新情報

NEWS

自動出力ナビゲーションをアコーディオン化する

目次

アコーディオン化とは

アコーディオン化とは、親子関係のあるページ一覧をリンクリスト化した際に、最初は子ページメニューを隠しておいてメニューのどこかに用意されたトリガーをクリックすると子ページメニューが開くという仕組みです。

自動出力ナビゲーション

WordPressではテンプレートタグ(wp_list_pages)を使って固定ページの一覧を自動出力することができます。
その自動出力されるメニューはただの階層のあるリストですが、これを上のようなアコーディオンメニュー化する方法をご紹介します。

こちらの記事で紹介した通り、ハンバーガーメニューとフッターナビゲーションの両方で共通で下記のソースで自動出力しています。

<nav class="sitemap-nav">
	<ul class="nav-parent">
		<?php
			$args = array(
				'child_of'     => 0,
				'depth'        => 0,
				'post_status'  => 'publish',
				'sort_column'  => 'menu_order',
				'sort_order'   => 'ASC',
				'title_li'     => '',
				'walker' => new UK_PAGE_MENU_WALKER(),
			);
			wp_list_pages( $args );
		?>
	</ul>
</nav>

walkerによる出力ソースのカスタマイズ

‘walker’ => new UK_PAGE_MENU_WALKER() がキモで、アコーディオンを開閉するボタンを追加します。
walkerクラスは functions.php に下記を記述して定義します。

class UK_PAGE_MENU_WALKER extends Walker_Page {
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<input type=\"checkbox\">\n<ul class=\"nav-child\">\n";
    }
}

walker追加前はこのソースだったのが

<li class="page_item page_item_has_children"><a href="...">親ページサンプル</a>
<ul class="children">
	<li class="page_item"><a href="...">子ページサンプル</a></li>
	<li class="page_item"><a href="...">子ページサンプル</a></li>
</ul>
</li>

walkerを追加することによってこうなります。便利ですねぇ walker。

<li class="page_item page_item_has_children"><a href="...">親ページサンプル</a>
<input type="checkbox">
<ul class="nav-child">
	<li class="page_item"><a href="...">子ページサンプル</a></li>
	<li class="page_item"><a href="...">子ページサンプル</a></li>
</ul>
</li>

CSSに詳しいひとは「あー」ってなりますよね。これでもうほぼ解決したようなものです。

CSSによるアコーディオン機能の実装

私が考える最もシンプルなアコーディオンメニューのCSS(SCSS)がこれです。

.sitemap-nav {
	ul {
		line-height: 21px;
		li {
			>a {
				color: #000;
				text-decoration: none;
				display: block;
				border-bottom: 1px solid #888;
				padding: 1em 0;
			}
			&.page_item_has_children {
				position: relative;
				>a {
					padding-right: 30px;
				}
				>input {
					cursor: pointer;
					position: absolute;
					top: 1em;
					right: 0;
					border: none;
					outline: none;
					appearance: none;
					display: inline-block;
					width: 21px;
					height: 21px;
					margin: 0;
					&::before, &::after {
						content: '';
						position: absolute;
						width: 11px;
						height: 1px;
						top: 10px;
						left: 5px;
						background-color: #000;
					}
					&::after {
						transform: rotate(90deg);
					}
					&:checked {
						&::after {
							display: none;
						}
						+ ul.nav-child {
							display: block;
						}
					}
				}
				ul.nav-child {
					margin-left: 20px;
					display: none;
				}
			}
		}
	}
}

まず子リスト(ul.nav-child)を初期状態で隠しておきます(display: none;)。
これを開閉するトリガーとして子リストの直前に配置したチェックボックスをチェックすると(input:checked)、その直後の子リストを表示する(+ ul.nav-child { display: block; })という簡単な仕組みです。

実際には、このソースをハンバーガーメニューとフッターメニューで共通化して出力し、出力する場所によってレイアウトやデザインをCSSで調整しています。

よろしくどうぞ。