Webサイトのヘッダーナビゲーションなどで、マウスを乗せると下層メニューがパッと表示される「ドロップダウンメニュー」。
限られたスペースに多くのリンクを整理して配置できるため、ユーザビリティを高める上で非常に重要なUIパーツです。
この記事では、マウスオーバー(ホバー)で開く基本的な実装方法から、スマホ向けにクリックで開閉させるテクニック、そしてレスポンシブ対応まで、実際のコードを見ながら徹底解説します。
![]() 執筆者:マヒロ |
|
- OS:Windows 11 / macOS Sequoia
- IDE:Visual Studio / VS Code / IntelliJ IDEA
- その他:Chrome DevTools / 各言語最新安定版
※本メディアでは、上記環境にてコードの動作と情報の正確性を検証済みです。
CSSだけでドロップダウンメニューを作る基本の仕組み
まずは、PCサイトでよく見かける「マウスを乗せるとメニューが開く」基本的な仕組みを理解しましょう。
仕組みはとてもシンプルです。
通常時は子メニューを「非表示」にしておき、親メニューにマウスが乗った時だけ「表示」するようにCSSを指定します。
【基本編】ホバーで開くドロップダウンの実装コード
<nav class="nav-basic">
<ul>
<li><a href="#">メニュー1</a></li>
<li>
<a href="#">メニュー2 ▼</a>
<!-- ここからドロップダウンの中身 -->
<ul>
<li><a href="#">子メニューA</a></li>
<li><a href="#">子メニューB</a></li>
<li><a href="#">子メニューC</a></li>
</ul>
</li>
<li><a href="#">メニュー3</a></li>
</ul>
</nav>
<style>
/* 親メニューのリストを横並びにする */
.nav-basic ul {
display: flex;
list-style: none;
}
/* 子メニューの基準位置とするためにrelativeを指定 */
.nav-basic li {
position: relative;
width: 150px;
}
/* 子メニュー(最初は非表示) */
.nav-basic ul ul {
display: none; /* ここで隠す */
position: absolute; /* 親メニューの直下に配置 */
top: 100%;
left: 0;
flex-direction: column; /* 子メニューは縦並び */
}
/* ★重要:ホバー時に子メニューを表示 */
.nav-basic li:hover > ul {
display: block;
}
/* デザイン調整(見やすくするための装飾) */
.nav-basic a {
display: block;
background: #333;
color: #fff;
padding: 15px;
text-decoration: none;
text-align: center;
}
.nav-basic a:hover {
background: #555;
}
.nav-basic ul ul a {
background: #444; /* 子メニューの色を変える */
border-bottom: 1px solid #555;
}
</style>
li)の中に、子となるリスト(ul)を入れ子にします。これがドロップダウンの基本構造です。
display: none; を指定して隠しておきます。li:hover > ul { display: block; } という記述です。これは「親のliタグにマウスが乗った時、その直下にあるulタグを表示する(ブロック要素にする)」という意味になります。
position: absolute; を使うことで、子メニューが他のコンテンツを押し下げることなく、上に重なって表示されるように調整しています。【スマホ対応】クリックで開閉するドロップダウンの作り方
マウスホバーで開くメニューはPCでは便利ですが、マウスのないスマートフォンやタブレットではうまく機能しません。
スマホ対応(レスポンシブデザイン)を考えるなら、タップ(クリック)で開閉する仕組みが必要です。
JavaScriptを使わずにCSSだけで「クリック開閉」を実現するには、主に2つの方法があります。
方法1:チェックボックスの「チェック状態」を利用する
HTMLのチェックボックス(<input type="checkbox">)が持つ「ON/OFF」の状態変化を利用して、メニューの表示・非表示を切り替えるテクニックです。
<div class="nav-click">
<!-- 状態管理用のチェックボックス(隠す) -->
<input type="checkbox" id="menu-switch">
<!-- 開閉ボタン(ラベル) -->
<label for="menu-switch" class="menu-label">メニューを開く</label>
<!-- 開閉する中身 -->
<div class="dropdown-content">
<p>ここはクリックで開閉するエリアです。</p>
<a href="#">リンク1</a><br>
<a href="#">リンク2</a>
</div>
</div>
<style>
/* チェックボックス本体は非表示にする */
#menu-switch {
display: none;
}
/* ドロップダウンの中身(最初は隠す) */
.dropdown-content {
display: none;
background: #f9f9f9;
padding: 10px;
border: 1px solid #ddd;
}
/* ★重要:チェックが入ったら、直後のラベルの隣にあるコンテンツを表示 */
#menu-switch:checked + .menu-label + .dropdown-content {
display: block;
}
/* デザイン調整 */
.menu-label {
display: inline-block;
padding: 10px 20px;
background: #2980b9;
color: white;
cursor: pointer; /* クリックできることを示す */
border-radius: 4px;
}
</style>
label タグと input タグの連携です。label の for 属性とチェックボックスの id を一致させることで、ラベル(ボタンに見える部分)をクリックするとチェックボックスのON/OFFが切り替わります。:checked 擬似クラスと隣接セレクタ(+)を使い、「チェックが入った状態のinputタグの後ろにある要素」のスタイルを変更しています。方法2:detailsタグとsummaryタグを使う(モダンな方法)
現在のHTML標準仕様では、開閉式のウィジェットを作るための専用タグ <details> と <summary> が用意されています。
ブラウザ標準の機能を使うため、コードが非常に短くなり、アクセシビリティ(読み上げ機能などへの対応)にも優れています。
<details>
<summary>詳細メニューを表示</summary>
<div class="details-content">
<p>標準タグだけで実装できるアコーディオンメニューです。</p>
<a href="#">リンクA</a> / <a href="#">リンクB</a>
</div>
</details>
<style>
/* 開閉時のデザイン調整も可能 */
details {
border: 1px solid #ccc;
padding: 0.5em;
border-radius: 4px;
}
summary {
cursor: pointer;
font-weight: bold;
}
</style>
<details> タグで全体を囲み、常に見せておきたい見出し部分を <summary> タグで記述します。それ以外のコンテンツは自動的に隠され、summaryをクリックした時だけ展開されます。
デザインを整える!おしゃれな矢印やアニメーション
基本の動きができたら、ユーザーが使いやすいように見た目を整えましょう。
特に「メニューが開くかどうか」を視覚的に伝える矢印アイコンや、ふわっと開くアニメーションは重要です。
CSSで矢印アイコンを作る
画像を使わなくても、CSSの border プロパティを使えば簡単な矢印を作れます。
/* 下向き矢印 */
.arrow-down::after {
content: "";
display: inline-block;
width: 6px;
height: 6px;
border-right: 2px solid #fff;
border-bottom: 2px solid #fff;
transform: rotate(45deg); /* 45度回転させて矢印にする */
margin-left: 10px;
vertical-align: 2px;
}
/* ホバー時に矢印を回転させる(180度) */
.nav-basic li:hover .arrow-down::after {
transform: rotate(225deg);
transition: 0.3s;
}
ふわっと表示させるアニメーション
display: none; から display: block; への切り替えでは、CSSの transition(アニメーション)が効きません。
ふわっと表示させたい場合は、opacity(不透明度)と visibility を組み合わせて制御します。
/* 初期状態(見えないがそこに存在する) */
.nav-basic ul ul {
/* display: none; は使わない */
opacity: 0;
visibility: hidden;
transition: all 0.3s ease; /* 0.3秒かけて変化 */
/* 位置を少し下にずらしておく */
transform: translateY(10px);
}
/* ホバー時の状態 */
.nav-basic li:hover > ul {
opacity: 1;
visibility: visible;
/* 元の位置に戻す */
transform: translateY(0);
}
HTML/CSSのスキルを活かして年収を上げる方法
以上、CSSでのドロップダウンメニューの作り方について解説してきました。
| 年収アップにこだわりたい方 (平均アップ額138万円の実績) | テックゴー |
| 未経験・経験者問わず幅広く探したい方 | ユニゾンキャリア |
| 業界に精通した担当者に相談したい方 | キッカケエージェント |
| ゲーム業界への転職を志望する方 | ファミキャリ |
| エンジニア未経験からキャリアを築く方 | イーチキャリア |



