「HTMLとCSSでメニューバーを作りたいけれど、どのタグを使えばよいのか分からない」と悩んでいませんか?
この記事では、初心者向けに横並びのメニューバーを順番に作ります。完成コードだけでなく、HTMLを追加した直後の状態、CSSで見た目が変わる過程、レスポンシブ対応、キーボード操作への配慮まで確認します。
HTMLとCSSで作るメニューバーの完成形

今回は、サイト内の主要ページへ移動するナビゲーションを作ります。メニューバー全体を表すnav要素の中に、リストとリンクを配置するのが基本です。
<nav class="global-nav" aria-label="メインナビゲーション">
<ul class="global-nav__list">
<li><a href="/" aria-current="page">HOME</a></li>
<li><a href="/service/">サービス紹介</a></li>
<li><a href="/news/">最新情報</a></li>
<li><a href="/blog/">ブログ</a></li>
<li><a href="/contact/">お問い合わせ</a></li>
</ul>
</nav>.global-nav {
width: 100%;
background-color: #263238;
}
.global-nav__list {
display: flex;
flex-wrap: wrap;
gap: 0;
max-width: 960px;
margin: 0 auto;
padding: 0;
list-style: none;
}
.global-nav a {
display: block;
padding: 1rem 1.25rem;
color: #fff;
text-decoration: none;
}
.global-nav a:hover {
background-color: #455a64;
}
.global-nav a:focus-visible {
outline: 3px solid #ffca28;
outline-offset: -3px;
}
.global-nav a[aria-current="page"] {
background-color: #00695c;
}
@media (max-width: 600px) {
.global-nav__list {
flex-direction: column;
}
.global-nav a {
border-bottom: 1px solid rgb(255 255 255 / 20%);
}
}先に全体像を確認しました。ここから「変更前の状態→追加するコード→変更後の状態」の順に分けて見ていきましょう。
nav要素でメニューバーの範囲を作る
最初は本文しかないHTMLを想定します。そこへ、ページ内の主要なリンクをまとめるnav要素を追加します。
<nav class="global-nav" aria-label="メインナビゲーション">
</nav>.global-nav {
width: 100%;
min-height: 64px;
background-color: #263238;
}
aria-labelは、このナビゲーションの役割を支援技術へ伝える名前です。ページ内に複数のnav要素がある場合も区別しやすくなります。
高さはheightで固定せず、最低限の高さを決めるmin-heightにしています。文字サイズや項目数が変わっても、内容がはみ出しにくいためです。
ul・li・a要素でメニュー項目を追加する
ulは順序のないリスト、liは各項目、aは移動先へのリンクを表します。メニューはリンクの集まりなので、この構造にすると意味が伝わりやすいHTMLになります。
<nav class="global-nav" aria-label="メインナビゲーション">
<ul class="global-nav__list">
<li><a href="/" aria-current="page">HOME</a></li>
<li><a href="/service/">サービス紹介</a></li>
<li><a href="/news/">最新情報</a></li>
<li><a href="/blog/">ブログ</a></li>
<li><a href="/contact/">お問い合わせ</a></li>
</ul>
</nav>
href="#"は練習では使えますが、実際のサイトでは各ページのURLを指定します。現在表示中のページにはaria-current="page"を付けると、現在位置を支援技術にも伝えられます。
Flexboxでメニュー項目を横並びにする
この時点では、メニュー項目は通常のリストと同じく縦に並んでいます。親要素の.global-nav__listへdisplay: flexを指定します。
.global-nav__list {
display: flex;
flex-wrap: wrap;
max-width: 960px;
margin: 0 auto;
padding: 0;
list-style: none;
}
display: flexは、子要素を一方向に並べやすくするレイアウト方法です。詳しい仕組みは、次の記事で確認できます。
flex-wrap: wrapを指定しているため、横幅が足りない場合は項目が次の行へ折り返します。また、クラス名を付けてCSSの対象を限定し、本文中のほかのリストへ影響しないようにしています。
リンクの余白・色・下線を整える
横並びにはなりましたが、リンク同士の間隔が狭く、クリックできる範囲も文字の周辺だけです。次のCSSで見た目と操作しやすさを整えます。
.global-nav a {
display: block;
padding: 1rem 1.25rem;
color: #fff;
text-decoration: none;
}
display: blockとpaddingにより、文字の周囲までリンクの操作範囲になります。隣の項目との間隔をmargin-rightだけで空けるより、項目全体を押しやすくできます。
ホバーとキーボードフォーカスを分かりやすくする
マウスポインターを重ねたときは:hover、Tabキーでリンクを選んだときは:focus-visibleで状態を示します。色の変化だけに頼らず、フォーカス時は輪郭線も表示します。
.global-nav a:hover {
background-color: #455a64;
}
.global-nav a:focus-visible {
outline: 3px solid #ffca28;
outline-offset: -3px;
}
.global-nav a[aria-current="page"] {
background-color: #00695c;
}
スマートフォンでは縦並びにする
横幅が狭い画面では、5項目を横一列に押し込むと文字が読みにくくなります。ここではJavaScriptを使わず、画面幅600px以下で縦並びに切り替えます。
@media (max-width: 600px) {
.global-nav__list {
flex-direction: column;
}
.global-nav a {
border-bottom: 1px solid rgb(255 255 255 / 20%);
}
}@mediaは、画面幅などの条件に応じてCSSを切り替えるための記述です。ブラウザの幅を狭くすると、横並びだった項目が上から順に並びます。
レスポンシブ対応の基本から確認したい場合は、次の記事も参考にしてください。
メニューバーを画面上部に固定する
スクロール中もメニューを表示したい場合は、position: stickyを使う方法があります。通常の配置を保ったまま、指定位置へ到達した後に固定されるため扱いやすい方法です。
.global-nav {
position: sticky;
top: 0;
z-index: 1000;
width: 100%;
background-color: #263238;
}top: 0は画面上端で固定する指定、z-indexはほかの要素との重なり順を調整する指定です。祖先要素のoverflowなどによってstickyが効かない場合がある点には注意してください。
常に画面へ固定するposition: fixedとの違いは、次の記事で詳しく確認できます。
メニューバーがうまく表示されないときの確認点
- CSSファイルがHTMLへ正しく読み込まれているか
- HTMLのクラス名とCSSのセレクターが一致しているか
ulの初期余白をmargin: 0とpadding: 0で打ち消しているか- リンク先のURLを
hrefへ指定しているか - スマートフォン幅で文字やリンクがはみ出していないか
- Tabキーだけで全リンクを移動でき、選択位置が見えるか
まとめ
HTMLのメニューバーは、nav要素の中にul・li・a要素を置き、CSSのFlexboxで横並びにすると作れます。
見た目だけでなく、CSSの対象をクラスで限定すること、狭い画面で並び方を変えること、ホバーとキーボードフォーカスを示すことも大切です。完成コードを土台に、色や余白をサイトに合わせて調整してみてください。
