目次
- はじめに|スライドメニュー、作ったのに「なぜかズレる」問題
- スライドメニューとは
- CSSだけでスライドメニューは作れる?
- 最小構成のHTML(まず動かす)
- 構造のポイント
- ハンバーガーボタンのCSS(最低限)
- チェックボックスを“見えないけど使える”状態にする
- 右からスライドするメニュー(基本形)
- ここが実務的に効くポイント
- 背景(オーバーレイ)を出して、タップで閉じる
- 左からスライドするメニューにする方法
- レスポンシブ対応(PCでは通常メニューにする)
- よくあるトラブルと対処(リアルにハマるやつ)
- メニューが表示されない
- DevToolsでの確認手順
- メニュー内がスクロールできない
- 背景が操作できてしまう(押せる・スクロールする)
- 横スクロールが出る(スマホ崩れの温床)
- 対策の基本
- CSSだけのスライドメニューのメリット・デメリット
- メリット
- デメリット
- まずはこれでOK|コピペ用まとめコード
- まとめ|CSSだけでも“実務で使える”スライドメニューは作れる
はじめに|スライドメニュー、作ったのに「なぜかズレる」問題
スマホ対応のWebサイトを作るとき、
ハンバーガーメニューとセットでよく使うのが「スライドメニュー」です。
- 右や左からメニューがスーッと出てくる
- 画面を広く使えて操作しやすい
- JavaScriptなしでも形になる
…なんですが、実際に作ると、妙な事故が起きます。
- メニューが出ない(セレクタが合ってない)
- 出るけど背景が押せる(z-indexが足りない)
- メニュー内がスクロールできない(高さとoverflow)
- スマホで横スクロールが出る(right:-100% / 100vwの罠)
私も昔、right: -100% で隠したつもりが、スマホだけ横スクロールが出て焦りました。
原因はメニューの幅と位置指定の組み合わせで、画面外に“実体”が残っていたこと。
見た目は隠れてても、レイアウト的にははみ出してる…ってやつです。
この記事では「スライドメニュー css」で検索してきた人が、
実装 → よくある事故回避 → デバッグまで一気に進められるようにまとめます。
スライドメニューとは
スライドメニューは、画面の外から横方向にスライドして表示されるナビゲーションのことです。
よくあるパターンはこの3つ。
- 右からスライド
- 左からスライド
- 画面全体を覆う(フルスクリーン)
スマホでは特に、メニューを常に表示しなくて済むので、見た目も操作も整えやすいです。
CSSだけでスライドメニューは作れる?
結論、作れます。
ポイントはこれだけ。
- チェックボックスで「開いてる/閉じてる」を持つ
- 画面外に置いておいて、開いたら戻す
- transitionで滑らかに動かす
ただし、実務で使うなら「背景クリックで閉じる」「スクロール」「横スクロール対策」「フォーカス」も入れておくと安心です。
最小構成のHTML(まず動かす)
まずは構造を固定します。これがズレるとCSSが効きません。
<input type="checkbox" id="menu-toggle" class="menu-toggle">
<label for="menu-toggle" class="menu-btn" aria-label="メニューを開く">
<span></span>
<span></span>
<span></span>
</label>
<label for="menu-toggle" class="menu-overlay" aria-hidden="true"></label>
<nav class="slide-menu" aria-label="グローバルナビゲーション">
<ul class="slide-menu__list">
<li><a href="#">ホーム</a></li>
<li><a href="#">サービス</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</nav>
構造のポイント
- checkbox(menu-toggle)が状態を持つ
- menu-btn(label)をタップすると checked が切り替わる
- overlay(label)も同じcheckboxに紐づけて、背景タップで閉じられる
- navはメニュー本体
ハンバーガーボタンのCSS(最低限)
.menu-btn {
width: 32px;
height: 26px;
display: inline-flex;
flex-direction: column;
justify-content: space-between;
cursor: pointer;
}
.menu-btn span {
display: block;
height: 3px;
background: #333;
border-radius: 2px;
}
「見た目ができればOK」なら、まずここまでで十分。
チェックボックスを“見えないけど使える”状態にする
display: none; にすると、状況によってはフォーカスや支援機能に不利になることがあります。
見えない場所に置く形が扱いやすいです。
.menu-toggle {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
}
右からスライドするメニュー(基本形)
.slide-menu {
position: fixed;
top: 0;
right: 0;
width: min(80vw, 360px);
height: 100svh;
background: #fff;
transform: translateX(100%);
transition: transform 0.3s ease;
z-index: 1001;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.menu-toggle:checked ~ .slide-menu {
transform: translateX(0);
}
ここが実務的に効くポイント
right: -100%ではなく、transformで隠す
→ はみ出しが原因の横スクロール問題を起こしにくいheight: 100svh
→ スマホのアドレスバーで高さが変わる問題を減らせるoverflow-y: auto
→ メニュー項目が多くてもスクロールできる
背景(オーバーレイ)を出して、タップで閉じる
「背景が操作できてしまう」問題は、これでほぼ解決します。
.menu-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.35);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
z-index: 1000;
}
.menu-toggle:checked ~ .menu-overlay {
opacity: 1;
pointer-events: auto;
}
overlayがlabelなので、タップするとチェックが外れて閉じます。
JavaScriptなしで「背景タップで閉じる」が成立します。
左からスライドするメニューにする方法
右から → 左からは、transform方向を変えるだけ。
.slide-menu {
left: 0;
right: auto;
transform: translateX(-100%);
}
.menu-toggle:checked ~ .slide-menu {
transform: translateX(0);
}
レスポンシブ対応(PCでは通常メニューにする)
「スマホだけスライド・PCは普通のナビ」が定番です。
@media (min-width: 769px) {
.menu-btn,
.menu-overlay {
display: none;
}
.slide-menu {
position: static;
transform: none;
height: auto;
width: auto;
overflow: visible;
transition: none;
z-index: auto;
}
}
よくあるトラブルと対処(リアルにハマるやつ)
メニューが表示されない
だいたい原因は2つです。
- HTMLの並び順が違う
- CSSのセレクタが合ってない
今回の例は ~(一般兄弟セレクタ)を使っています。
checkboxより後ろに .slide-menu が存在していないと効きません。
DevToolsでの確認手順
- F12 → Elements
<input id="menu-toggle">を選択- checked が付いているか見る
.slide-menuを選択- Stylesで
transformが当たっているか確認(打ち消し線が出てないか)
「チェックは付くけどCSSが動かない」なら、HTMLの順番かセレクタです。
メニュー内がスクロールできない
高さが固定されていなかったり、overflowが無いと起きます。
.slide-menu {
height: 100svh;
overflow-y: auto;
}
背景が操作できてしまう(押せる・スクロールする)
- overlayを入れる
- z-indexをメニューより1つ下にする
この記事の構成なら、overlayが先に出て背景をブロックします。
横スクロールが出る(スマホ崩れの温床)
原因として多いのはこのあたり。
right: -100%+width: 80%などで画面外に実体が残る100vwを多用して微妙にオーバー- メニュー内の長い文字(英数字)が折り返されない
対策の基本
- transformで隠す(今回の方式)
- 長い文字は折り返す
.slide-menu a {
overflow-wrap: anywhere;
}
CSSだけのスライドメニューのメリット・デメリット
メリット
- JavaScriptなしで軽い
- 実装がシンプル
- LPや小規模サイトなら十分使える
デメリット
- フォーカス制御(キーボード操作)などは限界がある
- 開閉状態に合わせて aria-expanded を切り替える…みたいな細かい制御は苦手
「とりあえず動く」ならCSSのみでOK。
アクセシビリティを徹底するなら、最終的にJavaScript併用も検討する、でバランスが取れます。
まずはこれでOK|コピペ用まとめコード
最後に、動く形をまとめて置きます。
<input type="checkbox" id="menu-toggle" class="menu-toggle">
<label for="menu-toggle" class="menu-btn" aria-label="メニューを開く">
<span></span><span></span><span></span>
</label>
<label for="menu-toggle" class="menu-overlay" aria-hidden="true"></label>
<nav class="slide-menu" aria-label="グローバルナビゲーション">
<ul class="slide-menu__list">
<li><a href="#">ホーム</a></li>
<li><a href="#">サービス</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</nav>
.menu-toggle {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
}
.menu-btn {
width: 32px;
height: 26px;
display: inline-flex;
flex-direction: column;
justify-content: space-between;
cursor: pointer;
}
.menu-btn span {
display: block;
height: 3px;
background: #333;
border-radius: 2px;
}
.menu-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.35);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
z-index: 1000;
}
.slide-menu {
position: fixed;
top: 0;
right: 0;
width: min(80vw, 360px);
height: 100svh;
background: #fff;
transform: translateX(100%);
transition: transform 0.3s ease;
z-index: 1001;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.menu-toggle:checked ~ .menu-overlay {
opacity: 1;
pointer-events: auto;
}
.menu-toggle:checked ~ .slide-menu {
transform: translateX(0);
}
.slide-menu a {
overflow-wrap: anywhere;
}
@media (min-width: 769px) {
.menu-btn,
.menu-overlay {
display: none;
}
.slide-menu {
position: static;
transform: none;
height: auto;
width: auto;
overflow: visible;
transition: none;
z-index: auto;
}
}
まとめ|CSSだけでも“実務で使える”スライドメニューは作れる
CSSだけのスライドメニューは、仕組みさえ押さえれば十分実用です。
- checkboxで開閉状態を持つ
- transform + transition でスライド演出
- overlayで背景タップ閉じ・誤操作防止
- overflowでメニュー内スクロール
- 横スクロール問題はtransform方式で回避しやすい
- DevToolsでcheckedと打ち消し線を見れば原因が特定できる
「スライドメニュー css」で探しているなら、
まずはこの記事の基本形をコピペして動かしてみてください。
動いたら、右/左、幅、デザインを自分のサイトに合わせて整えるだけです。