【CSSのみでOK!】ドロップダウンメニューの実装方法について解説します。

CSS HTML Web制作

【CSSのみでOK!】ドロップダウンメニューの実装方法について解説します。

なやむくん
ヘッダーナビゲーションにドロップダウンメニューを実装したい。
なやむさん
jsは難しいからCSSのみで実装できる方法はないかな…。

などの疑問や悩みを解決してまいります。

Webサイトのほとんどにヘッダーコンテンツがあり、その中にナビゲーションメニューがあります。

そこに主要なページタイトルを表示させて、ユーザーに閲覧してもらえるようアプローチをかけるのが一般的です。

しかし、ナビゲーションに表示させているページが親ページの場合、関連する子ページが増えてくるとその内容も何とかナビゲーションに追加できないものかと悩まれる方もいるのではないでしょうか。

そんな悩みを解決するのがドロップダウンメニューです。

なやむさん
え、でもドロップダウンメニューってjsを使わないと実装できないですよね…?
みつた
js使わなくても実装することは可能ですよ!

ということで今回はHTMLとCSSのみでドロップダウンメニューを実装する方法を解説していきます。

そもそもドロップダウンメニューとは

ドロップダウンメニューとは、通常時はメニューが閉じられており、ユーザーがメニューをクリックまたはホバーすると、選択可能な項目の一覧がドロップダウンとして表示されるメニューのことをいいます。

クリックまたはホバー(カーソルを対象要素に乗せる)することで、下層メニューが表示される。

今回はHTMLとCSSのみで実装しますので、初心者の方や動きのあるUIの実装を苦手としている方でも簡単に作成することができると思います。

もちろんコピペしていただいても問題ありません。

みつた
コピペで実装を済ませるのもいいですが、どのような仕組みでドロップダウンメニューは表示非表示されているのか、ぜひ記事を読んで学んでいただけると嬉しいです!

ドロップダウンメニューの実装方法

それではドロップダウンメニューの実装方法を解説していきます。

今回は以下6種類のドロップダウンメニューの実装方法を解説していきたいと思います。

解説するドロップダウンメニュー6種

  1. シンプルなドロップダウンメニュー
  2. 上から下に表示されるドロップダウンメニュー
  3. フェードで表示されるドロップダウンメニュー
  4. ドロップダウンメニューが吹き出し風
  5. 多階層に対応できるドロップダウンメニュー
  6. メガドロップダウンメニュー

様々な種類のドロップダウンメニューを紹介していきますので、実装するWebサイトにあったものを選んで実装いただけると幸いです。

みつた
それでは解説していきます。
よろこびくん
宜しくお願いいたします!

シンプルなドロップダウンメニュー

最初はナビゲーションメニューにカーソルを乗せると、ドロップダウンメニューが表示されるシンプルなタイプです。

HTMLとCSSのコードは以下になります。

  <header>
    <div class="inner">
      <div class="logo"><img src="https://mitsutano-oshiro.com/wp-content/uploads/2024/03/logo.png" alt=""></div>
      <nav>
        <ul class="menu">
          <li>
            <!-- dropdownクラスhoverでドロップダウンメニュー表示 -->
            <a class="dropdown child" href="">親メニュー01</a>
            <!-- ドロップダウンメニューはここから -->
            <ul class="dropdown_menu child_menu">
              <li><a href="">子メニュー01</a></li>
              <!-- 以下省略 -->
            </ul>
          </li>
          <li>
            <!-- dropdownクラスhoverでドロップダウンメニュー表示 -->
            <a class="dropdown child" href="">親メニュー02</a>
            <!-- ドロップダウンメニューはここから -->
            <ul class="dropdown_menu child_menu">
              <li><a href="">子メニュー02</a></li>
              <!-- 以下省略 -->
            </ul>
          </li>
          <li>
            <!-- dropdownクラスhoverでドロップダウンメニュー表示 -->
            <a class="dropdown child" href="">親メニュー03</a>
            <!-- ドロップダウンメニューはここから -->
            <ul class="dropdown_menu child_menu">
              <li><a href="">子メニュー03</a></li>
              <!-- 以下省略 -->
            </ul>
          </li>
          <li>
            <!-- dropdownクラスhoverでドロップダウンメニュー表示 -->
            <a class="dropdown child" href="">親メニュー04</a>
            <!-- ドロップダウンメニューはここから -->
            <ul class="dropdown_menu child_menu">
              <li><a href="">子メニュー04</a></li>
              <!-- 以下省略 -->
            </ul>
          </li>
        </ul>
      </nav>
    </div>
  </header>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

header {
  background-color: #1b63a7;
}

.inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 60px;
}

.logo img {
  width: 250px;
}

.menu {
  display: flex;
}

.menu li {
  position: relative;
  list-style: none;
}

.menu li a {
  display: block;
  text-decoration: none;
  font-weight: bold;
  color: #fff;
  padding: 30px;
}

/* 通常時は非表示 */
.child_menu {
  position: absolute;
  top: 100%;
  left: 0;
  transition: all 1s;
  background-color: #ebebeb;
  display: none;
  width: 100%;
}

.dropdown {
  position: relative;
}

/* ナビゲーション下矢印部分 */
.dropdown::after {
  content: '';
  position: absolute;
  top: 43%;
  right: 10px;
  transform: rotate(135deg);
  width: 5px;
  height: 5px;
  border-top: 2px solid #fff;
  border-right: 2px solid #fff;
}

/* dropdownクラスhoverしたら隣接要素のdropdown_menuクラスを表示 */
.dropdown:hover+.dropdown_menu,
.dropdown_menu:hover {
  display: block;
}

.child_menu li {
  padding: 0;
}

.child_menu li a {
  display: block;
  text-align: center;
  padding: 20px 0;
  border-bottom: 1px solid #444;
  color: #444;
  font-size: 14px;
  font-weight: bold;
}

.child_menu li a:hover {
  background-color: #acacac;
}

今回ドロップダウンメニューに設定している、dropdown_menuクラスは初期表示時はdisplay: none;で非表示設定にします。

そして、dropdownクラス(ナビゲーションメニュー)にカーソルを乗せたら、そのカーソルを乗せたdropdownクラスに隣接している要素のdropdown_menuクラス(ドロップダウンメニュー)をdisplay: block;で表示するようにします。

みつた
ホバーでドロップダウンメニューを表示する仕様の場合は、この方法が一般的になります。

また表示されたdropdown_menuクラスにカーソルを乗せた際にドロップダウンメニューが非表示にならないよう、dropdown_menuクラスにもhover指定してdisplay: block;で表示し続けるようにしています。

みつた
HTMLでコメントアウト「以下省略」としている箇所は、メニューの部分になりますので、お好みでリンクを増やしてください。

上から下にスライド表示されるドロップダウンメニュー

次に先程解説したドロップダウンメニューで、ドロップダウンメニューの表示が上から下にスライドして表示されるようになっています。

HTML自体の変更はありませんので、CSSのみ解説いたします。

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

header {
  background-color: #1b63a7;
}

.inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 60px;
}

.logo img {
  width: 250px;
}

.menu {
  display: flex;
}

.menu li {
  position: relative;
  list-style: none;
}

.menu li a {
  display: block;
  text-decoration: none;
  font-weight: bold;
  color: #fff;
  padding: 30px;
}

/* 通常時は非表示 */
.child_menu {
  position: absolute;
  top: 100%;
  left: 0;
  background-color: #ebebeb;
  /* ドロップダウンメニューを透明化 */
  opacity: 0;
  /* 透明化だけではクリックできてしまうので以下も追記 */
  visibility: hidden;
  /* フェードで表示非表示される時間の指定 */
  transition: all 1s;
  width: 100%;
}

.dropdown {
  position: relative;
}

/* ナビゲーション下矢印部分 */
.dropdown::after {
  content: '';
  position: absolute;
  top: 43%;
  right: 10px;
  transform: rotate(135deg);
  width: 5px;
  height: 5px;
  border-top: 2px solid #fff;
  border-right: 2px solid #fff;
}

.dropdown:hover+.dropdown_menu,
.dropdown_menu:hover {
  visibility: visible;
  opacity: 1;
}

.child_menu li {
  padding: 0;
}

.child_menu li a {
  display: block;
  text-align: center;
  padding: 20px 0;
  border-bottom: 1px solid #444;
  color: #444;
  font-size: 14px;
  font-weight: bold;
}

.child_menu li a:hover {
  background-color: #acacac;
}

変更になった点はドロップダウンメニューの表示方です。

なので先程のCSSから表示非表示にする部分が変更になっています。

まずはドロップダウンメニューに設定している、dropdown_menuクラスにtransform: scaleY(0);を指定して、高さを0とし非表示にします。

そして、dropdownクラスにカーソルを乗せたら、そのカーソルを乗せたdropdownクラスに隣接している要素にtransform: scaleY(1);を指定することで上から下に表示される仕組みになっています。

しかし、これだけでは理想とする動きにはなりません。

scaleY()関数以外に必要なのが2つあり、まず1つ目が transform-origin: top;です。

transform-originプロパティとはtransformプロパティによって変形の起点となる位置を指定します。

初期値がcenterであるため、指定をしない場合は以下のような動きとなってしまいます。

<失敗例>

そのため上から変形がスタートするように  transform-origin: top;を指定しています。

そしてもう1つは  transition: all .5s;です。

これは変形する時間(今回はscaleY(0)からscaleY(1)にするまでの時間)を設定していますが、この指定がないと上から下への動きを実現することができませんので、必ず記述するようにしましょう。

フェードで表示されるドロップダウンメニュー

次はドロップダウンメニューをフェードで表示非表示させる方法です。

先程の説明ではドロップダウンメニューが上から下に表示される仕様でしたが、今回はフェードで表示非表示できるようになっています。

HTMLの変更はないのでCSSのみ解説いたします。

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

header {
  background-color: #1b63a7;
}

.inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 60px;
}

.logo img {
  width: 250px;
}

.menu {
  display: flex;
}

.menu li {
  position: relative;
  list-style: none;
}

.menu li a {
  display: block;
  text-decoration: none;
  font-weight: bold;
  color: #fff;
  padding: 30px;
}

/* 通常時は非表示 */
.child_menu {
  position: absolute;
  top: 100%;
  left: 0;
  background-color: #ebebeb;
  /* ドロップダウンメニューを透明化 */
  opacity: 0;
  /* 透明化だけではクリックできてしまうので以下も追記 */
  visibility: hidden;
  /* フェードで表示非表示される時間の指定 */
  transition: all 1s;
  width: 100%;
}

.dropdown {
  position: relative;
}

/* ナビゲーション下矢印部分 */
.dropdown::after {
  content: '';
  position: absolute;
  top: 43%;
  right: 10px;
  transform: rotate(135deg);
  width: 5px;
  height: 5px;
  border-top: 2px solid #fff;
  border-right: 2px solid #fff;
}

/* dropdownクラスhoverしたら隣接要素のdropdown_menuクラスを表示 */
.dropdown:hover+.dropdown_menu,
.dropdown_menu:hover {
  visibility: visible;
  /* transitionを設定することで指定した時間で表示される */
  opacity: 1;
}

.child_menu li {
  padding: 0;
}

.child_menu li a {
  display: block;
  text-align: center;
  padding: 20px 0;
  border-bottom: 1px solid #444;
  color: #444;
  font-size: 14px;
  font-weight: bold;
}

.child_menu li a:hover {
  background-color: #acacac;
}

今回ドロップダウンメニューを表示非表示にするために指定しているプロパティは2つあります。

1つはopacityプロパティです。

opacityプロパティは要素を透明にするプロパティです。

0~1で透明度を指定することができるのでフェードで表示非表示する動きを実現することができます。

しかし、透明にすることで非表示のように見せていますが実際はクリックすることができてしまうので、これだけでは不十分です。

そのためもう1つのvisibilityプロパティを使用して、レイアウトを変更することなく要素を表示非表示にすることができます。

よろこびくん
この2つのプロパティがセットとなりドロップダウンメニューの表示非表示を切り替えているのですね!

あとはどれぐらい時間をかけてフェードでの表示非表示を完了するのかを指定するのは、先程の説明でも出てきましたtransitionプロパティですので忘れずに指定してください。

ドロップダウンメニューが吹き出し風

次にドロップダウンメニューを吹き出し風にレイアウトを変更しています。

こちらもHTMLに変更はないので、CSSのみの解説になります。

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

header {
  background-color: #1b63a7;
}

.inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 60px;
}

.logo img {
  width: 200px;
}

.menu {
  display: flex;
}

.menu li {
  position: relative;
  list-style: none;
}

.menu li a {
  display: block;
  text-decoration: none;
  font-weight: bold;
  color: #fff;
  padding: 30px;
}

/* 通常時は非表示 */
.child_menu {
  display: none;
  position: absolute;
  top: 80%;
  left: 50%;
  transform: translateX(-50%);
  background-color: #ebebeb;
  width: 100%;
}

.dropdown {
  position: relative;
}

/* ナビゲーション下矢印部分 */
.dropdown::after {
  content: '';
  position: absolute;
  top: 43%;
  right: 10px;
  transform: rotate(135deg);
  width: 5px;
  height: 5px;
  border-top: 2px solid #fff;
  border-right: 2px solid #fff;
}

/* dropdownクラスhoverしたら隣接要素のdropdown_menuクラスを表示 */
.dropdown:hover+.dropdown_menu,
.dropdown_menu:hover {
  display: block;
}

/* 吹き出しの△の部分 */
.child_menu::after {
  content: '';
  position: absolute;
  top: -5px;
  left: 50%;
  transform: translateX(-50%) rotate(45deg);
  width: 10px;
  height: 10px;
  background-color: #ebebeb;
}

.child_menu li {
  padding: 0;
}

.child_menu li a {
  display: block;
  text-align: center;
  padding: 20px 0;
  border-bottom: 1px solid #444;
  color: #444;
  font-size: 14px;
  font-weight: bold;
  transition: all .5s;
}

.child_menu li a:hover {
  opacity: .6;
}

見た目はほとんど最初に解説したシンプルなドロップダウンメニューと変わりませんが、吹き出し三角の部分が追加になっています。

child_menuクラス(ドロップダウンメニュー)にafter疑似要素を追加して三角部分を作成しています。

まず四角を作成し、それをrotate()関数を指定して回転させて中央から下はドロップダウンメニューと同化させ、中央から上部を見せることで三角を表現しています。

多階層に対応できるドロップダウンメニュー

次はドロップダウンメニューの項目をさらに細分化する場合やナビゲーションを多階層に分けたいときに使用すると便利なドロップダウンメニューになります。

HTMLとCSSは以下になります。

  <header>
    <div class="inner">
      <div class="logo"><img src="https://mitsutano-oshiro.com/wp-content/uploads/2024/03/logo.png" alt=""></div>
      <nav>
        <ul class="menu">
          <li>
            <a class="dropdown child" href="">親メニュー01</a>
            <ul class="dropdown_menu child_menu">
              <li><a href="">子メニュー01</a></li>
              <li>
                <a class="dropdown grandchild" href="">子メニュー01</a>
                <ul class="dropdown_menu grandchild_menu">
                  <li><a href="">孫メニュー01</a></li>
                  <!-- 以下省略 -->
                </ul>
              </li>
              <li><a href="">子メニュー01</a></li>
              <li>
                <a class="dropdown grandchild" href="">子メニュー01</a>
                <ul class="dropdown_menu grandchild_menu">
                  <li><a href="">孫メニュー01</a></li>
                  <!-- 以下省略 -->
                </ul>
              </li>
            </ul>
          </li>
          <li>
            <a class="dropdown child" href="">親メニュー02</a>
            <ul class="dropdown_menu child_menu">
              <li><a href="">子メニュー02</a></li>
                  <!-- 以下省略 -->
            </ul>
          </li>
          <li>
            <a class="dropdown child" href="">親メニュー03</a>
            <ul class="dropdown_menu child_menu">
              <li><a href="">子メニュー03</a></li>
                  <!-- 以下省略 -->
            </ul>
          </li>
          <li>
            <a class="dropdown child" href="">親メニュー04</a>
            <ul class="dropdown_menu child_menu">
              <li><a href="">子メニュー04</a></li>
                  <!-- 以下省略 -->
            </ul>
          </li>
        </ul>
      </nav>
    </div>
  </header>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

header {
  background-color: #1b63a7;
}

.inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 60px;
}

.logo img {
  width: 250px;
}

.menu {
  display: flex;
}

.menu li {
  position: relative;
  list-style: none;
}

.menu li a {
  display: block;
  text-decoration: none;
  font-weight: bold;
  color: #fff;
  padding: 30px;
}

/* 多階層用のメニューgrandchild_menuクラスを用意 */
.child_menu,
.grandchild_menu {
  position: absolute;
  top: 100%;
  left: 0;
  background-color: #ebebeb;
  display: none;
  width: 100%;
}

.grandchild_menu {
  background-color: #acacac;
}

.child_menu li {
  padding: 0;
}

.child_menu li a,
.grandchild_menu li a {
  display: block;
  text-align: center;
  padding: 20px 0;
  border-bottom: 1px solid #444;
  color: #444;
  font-size: 14px;
  font-weight: bold;
}

.grandchild_menu li:first-child a {
  border-top: 1px solid #444;
}

.child_menu li a:hover,
.grandchild_menu:hover {
  background-color: #acacac;
}

.grandchild_menu li a:hover {
  opacity: .6;
}

/* 多階層メニューの位置調整 */
.grandchild_menu {
  top: -1px;
  left: 100%;
}

.dropdown {
  position: relative;
}

/* ナビゲーション下矢印部分 */
.dropdown.child::after,
.dropdown.grandchild::after {
  content: '';
  position: absolute;
  top: 43%;
  right: 10px;
  transform: rotate(135deg);
  width: 5px;
  height: 5px;
  border-top: 2px solid #fff;
  border-right: 2px solid #fff;
}

/* 多階層メニュー用の下矢印部分 */
.dropdown.grandchild::after {
  transform: rotate(45deg);
  border-top: 2px solid #444;
  border-right: 2px solid #444;
}

/* dropdownクラスhoverしたら隣接要素のdropdown_menuクラスとgrandchild_menuクラスを表示 */
.dropdown:hover+.dropdown_menu,
.dropdown:hover+.grandchild_menu,
.dropdown_menu:hover {
  display: block;
}

実装内容は、最初に説明したシンプルなドロップダウンメニューに多階層用のメニューgrandchild_menuクラスと、調整用のCSSを用意したぐらいなので見た目のわりにそこまで難しい実装ではないかと思います。

ページ数の多いWebサイトになるほど使用する頻度が増えると思いますので、ぜひ参考にして実装していただけたらと思います。

メガドロップダウンメニュー

最後にメガドロップダウンメニューについて紹介していきます。

メガドロップダウンメニューとは、ナビゲーションメニューにカーソルを乗せたら、画面幅一杯に表示させるドロップダウンメニューです。

こちらもページ数が多いサイトや、画像やイラストデータを挿入してデザイン性を高めたりユーザーへの視覚的情報をより明確にするために使用されます。

HTMLとCSSは以下になります。

  <header>
    <div class="inner">
      <div class="logo"><img src="https://mitsutano-oshiro.com/wp-content/uploads/2024/03/logo.png" alt=""></div>
      <nav>
        <ul class="menu">
          <li>
            <a class="dropdown" href="">親メニュー01</a>
            <ul class="dropdown_menu mega_menu">
              <li><a href="">子メニュー01</a></li>
              <!-- 以下省略 -->
            </ul>  
          </li>
          <li>
            <a class="dropdown" href="">親メニュー02</a>
            <ul class="dropdown_menu mega_menu">
              <li><a href="">子メニュー02</a></li>
              <!-- 以下省略 -->
            </ul>
          </li>
          <li>
            <a class="dropdown" href="">親メニュー03</a>
            <ul class="dropdown_menu mega_menu">
              <li><a href="">子メニュー03</a></li>
              <!-- 以下省略 -->
            </ul>
          </li>
          <li>
            <a class="dropdown" href="">親メニュー04</a>
            <ul class="dropdown_menu mega_menu">
              <li><a href="">子メニュー04</a></li>
              <!-- 以下省略 -->
            </ul>
          </li>
        </ul>
      </nav>
    </div>
  </header>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

header {
  background-color: #1b63a7;
  position: relative;
}

.inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 60px;
}

.logo img {
  width: 250px;
}

.menu {
  display: flex;
}

.menu li {
  list-style: none;
}

.menu li a {
  display: block;
  text-decoration: none;
  font-weight: bold;
  color: #fff;
  padding: 30px;
}

.menu li a:hover {
  background-color: #ebebeb;
  color: #444;
}

/* 通常時は非表示 */
.mega_menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  background-color: #ebebeb;
  width: 100%;
  padding: 30px 60px;
}

.mega_menu li {
  padding: 0;
}

.mega_menu li a {
  display: block;
  padding: 0;
  margin: 10px 0;
  color: #444;
  font-size: 14px;
  font-weight: bold;
  transition: all .5s;
  float: left;
  width: 25%;
  border: none;
}

.mega_menu li a:hover {
  background-color: #ebebeb;
}

/* dropdownクラスhoverしたら隣接要素のdropdown_menuクラスを表示 */
.dropdown:hover+.dropdown_menu,
.dropdown_menu:hover {
  display: block;
}

これまで紹介したドロップダウンメニューの表示非表示の仕組みは同じですので、表示するドロップダウンメニューを画面幅一杯に広げてあげるなどレイアウトを調整するぐらいで実装することができます。

ドロップダウンメニューのコンテンツ幅が、紹介したどのドロップダウンメニューよりも大きいので、ユーザーに有効な見せ方を表現できる選択肢が多いのもメガドロップダウンメニューを実装するメリットの1つとも言えます。

みつた
状況に応じて使い分けましょう!

まとめ

計6種類のドロップダウンメニューの実装方法について解説させていただきました。

また今回はPCのみでレスポンシブ非対応となっています。

理由としまして、レスポンシブ時にはどのように表示させるかは案件によって異なるからです。

案件によっては子メニューは表示させないというところもあれば、アコーディオン機能を実装して多階層のドロップダウンメニューに対応するといったこともあります。

なので、ドロップダウンメニューを実装される際はPCサイズはこちらの記事を参考にしていただき、レスポンシブ時は案件に合わせた実装を行っていただけると幸いです。

ここまで読んでいただきありがとうございました!

  • この記事を書いた人
  • 最新記事

みつた

完全未経験&異業種から30歳の年でIT企業に転職。

Web系開発言語が好き。
どちらかというとバックエンドよりもフロントエンドが好き(現時点では…)

最近はサウナと観葉植物にハマっている。
野球が好きで一応投手。

-CSS, HTML, Web制作