本稿ではWordPressテーマGeneratePressカスタマイズとして、スマホメニューを横スクロールする方法を紹介します。
サイトのモバイルレイアウトにおけるメニューはハンバーガーメニューが一般的です。
では、どうして私は、
一言でいうと、

「UX」の観点からです
その思想についてあわせて語らせていただきます。
私の経験に基づく、UXの観点からのハンバーガーメニューの問題点
私の経験に基づくハンバーガーメニューの問題点は2つあります。
ハンバーガーメニューの問題点:
①三本線(≡)が何を意味するのかわからない人もいる。
②展開するまでサイト構造(カテゴリ)が隠れている。
三本線(≡)が何を意味するのかわからない人もいる
これは、私自身の経験に基づきます。
スマホを始めた頃は≡を見てもスルーしていたと思います。
「思います」というのは、当時は存在そのものに気付いていなかったからです。
ある日、≡があることに気づきました。
しかし何を意味するのかわからず、やっぱりスルーしました。
やがて自分がサイトを作るようになってはじめて、≡がモバイルにおけるグローバルナビであることに気づいた次第です。
もしかしたらこんな風にバカにされるのかもしれません。

情弱おつw
しかし少なくとも、私は知りませんでしたし、興味も持ちませんでした。
それなりにはITに強いと周囲に言われる側だったにかかわらずです。
だったらネットにそこまで慣れているわけじゃない人だと尚更わからないのではないか?
少なくとも自分がわからなかった以上は、それを基準にしてサイトを作るべきじゃないか?
……と考えたわけです。
展開するまでカテゴリ(サイト構造)が隠れている
ハンバーガーメニューは展開するまでカテゴリが隠れています。
狭いモバイルの画面に省スペースでメニューを設置できるのがハンバーガーメニューのメリット。
しかしこれは同時にデメリットでもあります。
やはりかつての私の話です。
検索であるサイトに行った場合、まず記事を読みます。
知りたい目的があってサイトに来ているわけですから当然です。
そして読んだら、目的を達したのですから大半は直帰します。

たとえその記事が面白かったとしてもです
カテゴリ(サイト構造)はハンバーガーメニューによって隠されていますから目に入りません。
あるいはコンパクトがゆえに、ハンバーガーメニューの存在に気づきません。
もしかしたら他に有益な情報があったかもしれないのに、みすみすフイにしてしまっています。

探してよ
とツッコミ入れられるでしょうけど。
このサイトのどこにどんな記事があるかわからない。
いくら読んだ記事が面白かったとしても、そこまでして探そうとは思えないです。
PCでなら最初からグローバルナビあるから別ですけど。
モバイルだと、ハンバーガーメニューを知っている現在ですら、私の直帰率は悪くなります。
だって、

めんどくさいし
これにつきます。
どっぷりはまるほどにすごく面白いならともかく、普通に面白いくらいだと他のサイトに行っちゃいます。
メニューを開くだけのはずなんですけど、なんででしょうね?
ニールセン・ノーマングループのレポート
ハンバーガーメニューをめぐる実験
……という話をGemini執事にしたところ、

ニールセン・ノーマングループがユーザーテストで検証していますよ

おおう!
ざっくり、レポートの内容を以下にまとめました。
本文にはもっと詳しく書かれています。
Webディレクターやマーケターなら絶対に一読する価値があります。
調査結果が示す3つのファクト
NNgが「常時表示メニュー(Visible)」「ハンバーガー等の隠しメニュー(Hidden)」「両者の併用(Combo)」の3パターンでユーザーの行動を追跡したところ、以下のような定量データが明らかになりました。
- メニューの利用率(クリック率)がほぼ半減する。
メニューをハンバーガーアイコンの中に隠してしまうと、ユーザーがその存在に気づいて利用する確率(発見可能性:Discoverability)が、常時表示されている場合に比べてモバイル・PCともに約50%低下します。
PC環境でのデータ: メニューが常時見えている場合の利用率が48%〜50%だったのに対し、隠した場合は27%へと激減しました。 - 目的のコンテンツにたどり着く時間が延びる。
メニューが隠されているサイトでは、ユーザーが特定のページ(情報)を探し出すまでにかかる時間(Time on Task)が余計に増加します。
PC環境: 平均で5〜7秒のロス モバイル環境: 平均で約2秒のロス - タスクの成功率(目的の情報へ到達できた割合)が下がる。
「このサイトに何があるか」が直感的に伝わらないため、サイト内を巡る(回遊する)意欲が削がれます。結果として、目的地にたどり着く「タスク成功率」は、隠しメニューにすることでスマホ・PCともに明確に低下することが確認されました。
なぜハンバーガーメニューは「効かない」のか?
NNgのレポートでは、数値が悪化する背景として人間の認知特性を挙げつつ、以下の2つの大きなハードルを指摘しています。
- 「見えないものは、存在しない」 (Out of sight, out of mind)
ユーザーは画面上で最初に見えた要素をベースに行動を判断します。三本線の中にどれだけ重要なリンクを格納していても、隠されている限り「そこには何もない」のと同じ扱いになってしまいます。 - 「2アクション」を強いるインタラクションコスト
常時表示メニューなら1タップで移動できるのに対し、ハンバーガーメニューは「①メニューを開く」→「②項目を選ぶ」という2ステップが必要です。このわずかな認知・操作の負荷(インタラクションコスト)が、ユーザーにとっては想像以上に高い壁となります。
回遊率を改善するための「脱・ハンバーガー」アプローチ
レポートでは、ただハンバーガーメニューを悪とするのではなく、人間の認知に最適化した代替設計(Beyond the Hamburger)を推奨しています。
- 対策A:主要ナビゲーションの常時表示(Visible)
最も重要な3〜5つのコアコンテンツは、隠さず画面上(スマホであれば下部のタブバーなど)にテキスト付きで常時表示させます。ユーザーが迷うことなく、1タップで瞬時に移動できる環境を作ることが回遊率向上の大原則です。 - 対策B:優先度ベースの併用型(Combo)
すべてのメニューを等しく扱うのではなく、優先度が高い主要リンクは常時表示し、入り切らなかった「その他(設定、ヘルプ、会社概要など)」の項目だけをハンバーガーメニューに格納する手法です。これにより、画面のシンプルさと回遊性の両立が可能になります。
私が横スクロールメニューを採用した理由
以上を踏まえて、当サイトでは代替案として横スクロールメニューを採用しました。

採用の理由は2点あります
- メニューがそこにあることを伝えられる
- サイト構成の一部を伝えられる
言ってみれば、サイトは私と訪問者のコミュニケーションツール。
会話において、伝えられることはできるだけ伝えたいですよね。
わかりやすく伝えられるなら、より望ましいです。
ただ、横スクロールも完壁ではありません。
- 訪問者にスワイプを強いる
- 見切れている部分はやっぱり隠れる
- 見切れた場所によっては、メニューに続きがあることがわからない
それでも全てが隠れるハンバーガーメニューよりは優れていると判断して採用しました。
見切れた部分への対策は矢印「>」とフェード効果でカバーすることにしました。
メニュー右端に置くことで、続きがあることを伝えます。
GeneratePress(無料版可)の実装コード
/**
* GeneratePress用:モバイル横スクロール対応カスタムヘッダーナビ
* - CSSはインラインのまま1か所に集約
* - モバイル時は横スクロール
* - JSなし
* - 右端にフェード+矢印ヒントを表示
*/
add_action('wp_head', function () {
$header_h = '40px';
$dark_color = '#1c1a1a';
$accent_color = '#ff8c7e';
$container_width = '1200px';
$side_padding_pc = '30px';
$side_padding_sp = '15px';
$css = "
<style id='custom-horizontal-scroll-nav-style'>
/* =========================
共通設定
========================= */
.site-header {
background-color: {$dark_color} !important;
position: sticky !important;
top: 0 !important;
z-index: 100 !important;
width: 100% !important;
min-height: {$header_h} !important;
}
body.admin-bar .site-header {
top: 32px !important;
}
.inside-header {
display: flex !important;
align-items: center !important;
max-width: {$container_width} !important;
margin: 0 auto !important;
padding: 0 {$side_padding_pc} !important;
min-height: {$header_h} !important;
}
.main-title a,
.site-logo a {
font-size: 18px !important;
color: #fff !important;
font-weight: 700 !important;
text-decoration: none !important;
}
.custom-header-nav {
position: relative !important;
flex: 1 1 auto !important;
min-width: 0 !important;
margin-left: 30px !important;
}
.custom-nav-list {
display: flex !important;
align-items: center !important;
flex-wrap: nowrap !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
min-width: 0 !important;
-ms-overflow-style: none;
scrollbar-width: none;
}
.custom-nav-list::-webkit-scrollbar {
display: none;
}
.custom-nav-list > li {
flex: 0 0 auto !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
}
.custom-nav-list > li > a {
display: block !important;
color: #fff !important;
font-size: 14px !important;
line-height: {$header_h} !important;
padding: 0 12px !important;
text-decoration: none !important;
white-space: nowrap !important;
transition: color 0.3s ease, background-color 0.3s ease !important;
}
.custom-nav-list > li > a:hover,
.custom-nav-list > li > a:focus {
background-color: rgba(255, 255, 255, 0.1) !important;
color: {$accent_color} !important;
outline: none !important;
}
.custom-nav-list > li.current-menu-item > a,
.custom-nav-list > li.current-menu-parent > a,
.custom-nav-list > li.current-menu-ancestor > a,
.custom-nav-list > li[class*='current-menu-'] > a {
color: {$accent_color} !important;
}
.nav-x-item {
margin-left: auto !important;
display: flex !important;
align-items: center !important;
padding-left: 10px !important;
}
.nav-x-item a {
display: flex !important;
align-items: center !important;
justify-content: center !important;
color: #fff !important;
line-height: 1 !important;
padding: 0 8px !important;
background: transparent !important;
transition: color 0.3s ease !important;
}
.nav-x-item a:hover,
.nav-x-item a:focus {
color: {$accent_color} !important;
background: transparent !important;
outline: none !important;
}
.nav-x-item svg {
display: block !important;
width: 18px !important;
height: 18px !important;
fill: currentColor !important;
}
/* ヒント矢印はPCでは非表示 */
.custom-nav-scroll-hint {
display: none !important;
}
@keyframes nav-scroll-hint-bounce {
0% { transform: translateX(0); opacity: 0.7; }
35% { transform: translateX(6px); opacity: 1; }
70% { transform: translateX(0); opacity: 0.9; }
100% { transform: translateX(0); opacity: 0.7; }
}
/* =========================
モバイル設定
========================= */
@media screen and (max-width: 768px) {
.inside-header {
padding: 0 {$side_padding_sp} !important;
flex-wrap: wrap !important;
}
.custom-header-nav {
width: 100% !important;
margin-left: 0 !important;
overflow: hidden !important;
}
.custom-nav-list {
overflow-x: auto !important;
overflow-y: hidden !important;
-webkit-overflow-scrolling: touch !important;
width: 100% !important;
padding: 0 36px 0 0 !important;
}
.custom-nav-list > li > a {
padding: 0 10px !important;
}
.nav-x-item {
margin-left: 0 !important;
padding-left: 0 !important;
padding-right: 8px !important;
}
/* 右端フェード */
.custom-header-nav::after {
content: '' !important;
position: absolute !important;
top: 0 !important;
right: 0 !important;
width: 40px !important;
height: 100% !important;
pointer-events: none !important;
z-index: 2 !important;
background: linear-gradient(
to right,
rgba(28, 26, 26, 0) 0%,
rgba(28, 26, 26, 0.75) 55%,
{$dark_color} 100%
) !important;
}
/* 右端矢印 */
.custom-nav-scroll-hint {
position: absolute !important;
top: 0 !important;
right: 12px !important;
bottom: 0 !important;
margin: auto 0 !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
width: 24px !important;
height: 24px !important;
color: #ff8c7e !important;
opacity: 0.95 !important;
pointer-events: none !important;
z-index: 3 !important;
animation: nav-scroll-hint-bounce 1.2s ease-in-out infinite !important;
}
.custom-nav-scroll-hint svg {
display: block !important;
width: 18px !important;
height: 18px !important;
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.25)) !important;
fill: currentColor !important;
}
}
@media screen and (max-width: 768px) and (prefers-reduced-motion: reduce) {
.custom-nav-scroll-hint {
animation: none !important;
}
}
</style>
";
echo $css;
});
/**
* ナビゲーション出力
*/
add_action('generate_after_header_content', function () {
$x_url = 'https://x.com/あなたのXのID';
echo '<nav class="custom-header-nav" aria-label="グローバルナビゲーション" itemscope itemtype="https://schema.org/SiteNavigationElement">';
echo '<span class="custom-nav-scroll-hint" aria-hidden="true">
<svg viewBox="0 0 24 24" focusable="false">
<path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6z"></path>
</svg>
</span>';
wp_nav_menu(array(
'theme_location' => 'primary',
'container' => false,
'menu_class' => 'custom-nav-list',
'fallback_cb' => false,
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s
<li class="nav-x-item">
<a href="' . esc_url($x_url) . '" target="_blank" rel="noopener noreferrer" aria-label="Xを見る">
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path>
</svg>
</a>
</li>
</ul>',
));
echo '</nav>';
});
以下、注意点です。

CSSをインライン化してPHPコードとひとまとめにしています
GeneratePressをテーマに選ぶ時点で、高速化を図るのは前提と言っていいでしょう。
そしてグローバルナビはヘッダー直下ですから、ほぼクリティカルCSSとなるためです。
本来は最小限のCSSのみをインライン化すべきなのですが。
保守性を考えて、全てをインラインにしています。
気に入らなければ、CSSファイルを分離してください。
また、Webフォント読み込みでレンダリングブロックに注意を払わなくてすむようにSVGアイコンを採用しています。

reduced motionに対応しています
静かに閲覧したいセッティングをしている方には、それに対応してあげる方がUXに資するというものです。
そうでない場合は矢印が右(メニューの続き)に向けてアニメーションします。
もしテストで「アニメーション動かない!」という場合は、以下のコードをコメントアウトしてください。
@media screen and (max-width: 768px) and (prefers-reduced-motion: reduce) {
.custom-nav-scroll-hint {
animation: none !important;
}
}

コピペするなら、このコードはGeneratePressでしか使えません
GeneratePress専用のフック(GeneratePress Premium不要)を使っているためです。
generate_after_header_content
ただしお使いのテーマの同一箇所にフックがあるなら、それにあわせれば流用できます。
フックを削除してテンプレートに直書きしても動きますが、保守性の面からおすすめしません。
まとめ
実のところ、現在は別の開閉式メニューを使っています。
この記事ページの上部に「MENU」と書かれたボタンがあるはずです。

じゃあ何のためにこの記事書いたんだ!
とツッコミ入れられるかもしれません。
ごもっともです。
現在のメニューにする前は、実際に横スクロールメニューを設置していました。
ただ「これ、いけるんじゃね?」とデザインを思いつきまして。
私の思想と合っていると思えたので乗りかえた次第です。

現在のメニューについては後編で改めて記させていただきます
UXを実現する方法に正解はないと思います。
どんな目的でどんなサイトを運営しているかによって変わってくるでしょう。
例えばハンバーガーメニューだって、当サイトのようなテックブログであれば一つの正解です。
訪問者の多くはWeb業界人やサイト制作にかかわる人達ですからITリテラシーが高いはず。
ハンバーガーメニューを知っている前提でサイトデザインしてもいいでしょう。
もちろん、今回の横スクロールメニューも一つの正解です。
私としては、少なくともテックブログ以外の一般サイトならハンバーガーメニューよりオススメします。
実際に私自身、またどこか別のサイトで採用することもあると思います。

もしよかったら横スクロールメニューを試してみてください!
私はConoHa以外を勧めない。
2016年からずっとConoHaを使い倒してきました。知人に「一番いいサーバーは?」と聞かれたら、迷わずここを教えます。
レンタルサーバーナンバーワンを誇る高速環境であることはもちろん。私が「黒い画面って何?」というド素人からサイト制作のプロになれたのは、傍らにずっとこのはちゃんがいてくれたから。
私がConoHaを使い続ける、嘘偽りない理由です。
※ConoHaに初めて入会の方限定。
本CTAの画像もしくはボタンを押してWINGパック12か月以上を契約すると、最大5000円割引してもらえます。
