javascript

[初心者向け]CSSのみで作るドロワーメニュー

2022/04/09

jQuery/javascriptを使わずに、CSSだけでドロワーメニューを作ってみます。

CSSのみでドロワーメニューを作る

以前、jQuery、またはjQueryを使わず純粋なjavascript(Vanilla js)でドロワーメニューを作成する方法を解説しました。今回は以前作ったドロワーメニューと同じものを、jQueryやjavascriptを使用せずにcssのみで作成してみようと思います。

以前作成した、jQuery、javascriptでのドロワーメニューの作り方については下記のリンクからご覧いただけます。今回作成する「CSSのみで作るドロワーメニュー」と比較してみると、初心者の方にはより勉強になると思います。

ドロワーメニューをjQuery / javascript(Vanilla JS)のみで作る

よく使うドロワーメニューをjQueryまたは、javascriptのみで作ってみます。 目次ベースのHTML/CSSjQueryで書いた場合javascript(Vanilla JS)で書いた場合 ベ ...

続きを見る

作成する「CSSのみで作るドロワーメニュー」の完成サンプルは下記になります。レスポンシブ対応になっているので、パソコンで確認する場合はブラウザの横幅を縮めてご確認ください。見た目は、jQuery、javascriptで作成したドロワーメニューとほぼ一緒です。

CSSのみでつくドロワーメニュー サンプル

今回作成したもののコードは以下になります。ポイントとなる箇所のみを抜粋しています。

<body>

  <header class="header-sec">

    <img src="img/logo.svg" alt="" / class="header-logo">
    <nav>
      <ul class="header-ul flex">
        <li>
          <a href="#">Bangkok</a>
        </li>
        <li>
          <a href="#">Chiang Mai</a>
        </li>
        <li>
          <a href="#">Udon Thani</a>
        </li>
        <li>
          <a href="#">Chonburi</a>
        </li>
      </ul>
    </nav>

     <!-- drawer-->
    <div class="drawer">

      <input type="checkbox" id="navTgl" class="checkbox-hidden">
      <label for="navTgl" class="hamburger">
        <span></span>
        <span></span>
        <span></span>
      </label>

      <!-- #spnav -->
      <div class="menu">
        <nav>
          <ul>
            <li><a href="#">Bangkok</a></li>
            <li><a href="#">Chiang Mai</a></li>
            <li><a href="#">Udon Thani</a></li>
            <li><a href="#">Chonburi</a></li>
          </ul>
        </nav>
      </div>

    </div>
    <!--// drawer-->

  </header>

  <div class="inner">
    <img src="img/img_01.jpg" alt="" />
  </div>
  <div class="photo-sec flex inner">
    <div class="photo-box">
      <img src="img/img_02.jpg" alt="" />
    </div>
    <div class="photo-box">
      <img src="img/img_03.jpg" alt="" />
    </div>
    <div class="photo-box">
      <img src="img/img_04.jpg" alt="" />
    </div>
    <div class="photo-box">
      <img src="img/img_05.jpg" alt="" />
    </div>
    <div class="photo-box">
      <img src="img/img_02.jpg" alt="" />
    </div>
    <div class="photo-box">
      <img src="img/img_03.jpg" alt="" />
    </div>
    <div class="photo-box">
      <img src="img/img_04.jpg" alt="" />
    </div>
    <div class="photo-box">
      <img src="img/img_05.jpg" alt="" />
    </div>
  </div>
</body>
html {
  width: 100%;
  margin: 0 auto;
  font-size: 0.625rem;
}

body {
  width: 100%;
  background: #fff;
  color: #000;
  font-family: "Noto Sans JP", sans-serif;
  font-weight: 400;
  line-height: 1.6;
  text-align: left;
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}

.header-sec {
  height: 126px;
  padding: 0 5%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-logo {
  width: 107px;
  height: auto;
}

.header-ul {
  list-style: none;
  position: relative;
  display: flex;
}

.header-ul li {
  font-size: 1.6rem;
  margin-right: 45px;
}

.header-ul li a {
  display: block;
  color: #333;
  font-weight: bold;
  padding-bottom: 3px;
}

.header-ul li a:hover {
  color: #999;
  border-bottom: 1px solid #ccc;
  transition: 0s;
}

.header-ul li:last-child {
  margin-right: 0px;
}

.drawer {
  display: none;
}

/* ハンバーガーメニュー input */
.checkbox-hidden {
  display: none;
}

label {
  position: absolute;
  top: 2.2rem;
  right: 5.2%;
  width: 20px;
  height: 16px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.hamburger {
  z-index: 100;
}

.hamburger span {
  display: block;
  width: 100%;
  height: 2px;
  background-color: #333;
  position: absolute;
  transition: transform 0.5s, opacity 0.5s, width 0.3s;
}

.hamburger span:nth-child(1) {
  top: 0;
}

.hamburger span:nth-child(2) {
  top: 0;
  bottom: 0;
  margin: auto;
}

.hamburger span:nth-child(3) {
  bottom: 0;
}

#navTgl:checked + .hamburger span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
  background-color: #fff;
}

#navTgl:checked + .hamburger span:nth-child(2) {
  top: 0;
  bottom: 0;
  margin: auto;
  width: 0px;
  opacity: 0;
  background-color: #fff;
}

#navTgl:checked + .hamburger span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
  background-color: #fff;
}

.menu {
  width: 100%;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 100%;
  opacity: 0;
  z-index: 99;
  background: rgba(0, 0, 0, 0.9);
  transition: 0.5s ease-in-out;
}

.menu ul {
  text-align: center;
  margin-top: 20%;
}

.menu ul li {
  position: relative;
  margin-bottom: 70px;
  transform: translateX(-200px);
  transition: transform 1.3s ease;
}

.menu ul li:nth-child(2) {
  transition-delay: 0.15s;
}

.menu ul li:nth-child(3) {
  transition-delay: 0.3s;
}

.menu ul li:nth-child(4) {
  transition-delay: 0.45s;
}

.menu ul li a {
  font-size: 2.4rem;
  color: #fff;
}

#navTgl:checked ~ .menu {
  left: 0;
  opacity: 1;
}

#navTgl:checked ~ .menu li {
  transform: translateX(0px);
}

.inner {
  position: relative;
  width: 100%;
  max-width: 1000px;
  margin: 0 auto;
  padding: 0;
}

.photo-sec {
  margin-top: 5%;
  margin-bottom: 5%;
}

.photo-box {
  width: 47.5%;
  margin-top: 5%;
}

.photo-box img {
  width: 100%;
  margin-bottom: 3.5%;
}

@media only screen and (max-width: 767px) {
  /* body
--------------------------------*/
  .inner {
    position: relative;
    width: calc(100% - 40px);
    max-width: 1000px;
    margin: 0 auto;
    padding: 0;
  }
  .header-sec {
    height: 55px;
    padding: 0 20px;
  }
  .header-logo {
    width: 54px;
    height: auto;
  }
  .header-ul {
    display: none;
  }
  .drawer {
    display: block;
  }
  .photo-box p {
    font-size: 1.6rem;
  }
  .text-sec p {
    font-size: 1.6rem;
    line-height: 1.9;
  }
  .photo-sec {
    margin-top: 3rem;
    margin-bottom: 3rem;
  }
}

大まかな仕組みを説明すると、[inputタグ type="checkbox"]をクリックすると[input]タグ部分に[checked]が追加されます。[checked]がついたり消えたりすることによって、「[checked]がある場合のドロワーメニュー、ハンバーガーメニューのCSS」と、「[checked]がない場合のドロワーメニュー、ハンバーガーメニューのCSS」とを切り替えて表示させています。

試しに上のHTMLソースの

<input type="checkbox" id="navTgl" class="checkbox-hidden">

の部分に[checked]を付け加えてみると、ハンバーガーメニューをクリックした後、ドロワーメニューが表示されている状態になると思います。

<input type="checkbox" id="navTgl" class="checkbox-hidden" checked>

つまり、「ドロワーメニューが表示される前」の状態と「ドロワーメニューが表示された後」の状態を、[input]タグをクリックすることによって切り替えて表示させています。

inputタグについて

cssでドロワーメニューを作る際にポイントとなるのが[inputタグ]の理解だと思います。
ので、簡単に[inputタグ]の使い方について簡単に説明します。

inputタグは一般的にお問い合わせなどのようなフォームを作成する時によく使われます。
inputにはtype属性があり、例えば[password][radio]など用意されており、今回のドロワーメニューではこのtype属性[checkbox]を利用します。詳しいinputタグの使用については下記のリンクからご確認できます。

<input>の解説|クロノドライブのHTML辞典

inputタグは一般的にlabelタグとセットで使用されます。
labelタグは、input要素を紐づけるために利用され、「label要素のfor属性」「input要素のid属性」に同じ値を指定することによってお互いを関連付けします。
inputタグtype属性[checkbox][radio]だった場合、label要素部分をクリックすることでチェックのつけ外しが行われます。

<input type="checkbox" id="check">
    <br><br><br><br><br><br><br>
<label for="check">チェック</label>

inputタグ テスト

上のリンクを開いてもらって、ページ内の「チェック」のテキストをクリックすると上のchekboxにチェックが入ることが確認できると思います。inputタグid属性「check」を指定し、labelタグfor属性で同じように「check」を指定することで、お互いを関連付けています。

今回作成するドロワーメニューでは、inputtype属性[checkbox]を指定して、css[display: none]にしてチェックボックスを非表示にしています。そして、labelタグでハンバーガーメニューをくくりinputタグと関連付けています。labelタグでくくられたハンバーガーメニューをクリックすることで、inputタグにチェックが付いたり消えたりする仕組みになっています。

<input type="checkbox" id="navTgl" class="checkbox-hidden">
<label for="navTgl" class="hamburger">
   <span></span>
   <span></span>
   <span></span>
</label>
.checkbox-hidden {
  display: none;
}

label {
  position: absolute;
  top: 2.2rem;
  right: 5.2%;
  width: 20px;
  height: 16px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.hamburger {
  z-index: 100;
}

ハンバーガーメニューを作る

ハンバーガーメニューは、htmlとcssを利用して作成しています。

<label for="navTgl" class="hamburger">
   <span></span>
   <span></span>
   <span></span>
</label>
.hamburger span {
  display: block;
  width: 100%;
  height: 2px;
  background-color: #333;
  position: absolute;
  transition: transform 0.5s, opacity 0.5s, width 0.3s;
}

.hamburger span:nth-child(1) {
  top: 0;
}

.hamburger span:nth-child(2) {
  top: 0;
  bottom: 0;
  margin: auto;
}

.hamburger span:nth-child(3) {
  bottom: 0;
}

上のcssはドロワーメニューが開いていない状態、つまりinputタグにチェックが入っていない状態のハンバーガーメニューのcssです。inputタグにチェックが入りドロワーメニューが開いた状態のハンバーガーメニューのcssは以下になります。

#navTgl:checked + .hamburger span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
  background-color: #fff;
}

#navTgl:checked + .hamburger span:nth-child(2) {
  top: 0;
  bottom: 0;
  margin: auto;
  width: 0px;
  opacity: 0;
  background-color: #fff;
}

#navTgl:checked + .hamburger span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
  background-color: #fff;
}

#navTgl:checked + .open span:nth-child(1) は、「id属性nvTglがcheckedが付いた状態の時、同階層のクラス属性hamburgerの下階層の最初のspan要素」を示しています。ハンバーガーメニューの見た目で言うと、一番上のバーになります。span:nth-child(2)が真ん中のバー、span:nth-child(3)が一番下のバーを示しています。

#navTgl:checked~のcssは、ハンバーガーメニューがクリックされた後の見た目のcssを記述しています一番上と一番下のバーが回転(rotate)して縦方向に移動(translateY)し色が白に変化(background-color)して、真ん中のバーは横幅が0になり消えるようになっています。

cssのセレクタの解説とtansformの解説については別記事でより詳しく書いているので、気になる方はご覧ください。

【初心者向け】CSSセレクタとは?基本18パターン使い方解説

CSSはHTMLで指定された範囲または要素に対して装飾を適用するものです。そして、CSSによる装飾をどのHTML要素に適用させるかを指定するのに用いられるのが「CSSセレクタ」です。「CSSセレクタ」 ...

続きを見る

【css】transitionの使い方【各プロパティ サンプルあり】

目次transitionとは基本形transitionの4つのプロパティ① transition-duration② transition-property③ transition-timing-fu ...

続きを見る

ドロワーメニューの記述

ドロワーメニューについてもハンバーガーメニューと同じように、ハンバーガーメニューがクリックされる前(inputタグにcheckedなし)と、ハンバーガーメニューがクリックされてドロワーメニューが表示された後(inputタグにcheckedあり)のそれぞれの状態のcssを記述します。

以下はハンバーガーメニューがクリックされる前のドロワーメニュー部分のhtmlとcssになります。

      <div class="menu">
        <nav>
          <ul>
            <li><a href="#">Bangkok</a></li>
            <li><a href="#">Chiang Mai</a></li>
            <li><a href="#">Udon Thani</a></li>
            <li><a href="#">Chonburi</a></li>
          </ul>
        </nav>
      </div>
.menu {
  width: 100%;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 100%;
  opacity: 0;
  z-index: 99;
  background: rgba(0, 0, 0, 0.9);
  transition: 0.5s ease-in-out;
}

ポイントとしては、事前にcssでleft: 100%;と記述してドロワーメニューを画面の右端に移動させて見えないようにしておき、 opacity: 0;で不透明にして見えなくしておきます。

次にハンバーガーメニューがクリックされた状態のドロワーメニューのcssを記述します。left: 0;にすることで、メニューが右から左に出てくるようにして、あわせてopacity: 1;にします。コードは以下になります。

#navTgl:checked ~ .menu {
  left: 0;
  opacity: 1;
}

ドロワーメニューのテキストに動きをつける

次にドロワーメニューの各テキストに動きをつけていきます。メニュー自体は右から左へ出てくるのに対して、各テキスト左から右へ移動させています(translateX)。テキストの移動も各テキストごとに時差で上からの順番に移動するようにしています(transition-delay)。translateXの値やtransition-delayの値を自分で色々と変えて確認するとより分かりやすいと思います。

[ ハンバーガーメニュー クリック前 ]

.menu ul {
  text-align: center;
  margin-top: 20%;
}

.menu ul li {
  position: relative;
  margin-bottom: 70px;
  transform: translateX(-200px);
  transition: transform 1.3s ease;
}

.menu ul li:nth-child(2) {
  transition-delay: 0.15s;
}

.menu ul li:nth-child(3) {
  transition-delay: 0.3s;
}

.menu ul li:nth-child(4) {
  transition-delay: 0.45s;
}

.menu ul li a {
  font-size: 2.4rem;
  color: #fff;
}

[ ハンバーガーメニュー クリック後 ]

#navTgl:checked ~ .menu {
  left: 0;
  opacity: 1;
}

#navTgl:checked ~ .menu li {
  transform: translateX(0px);
}

以上で終了です。

同じドロワーメニューをjQueryまたは純粋なjavascript(vanilla js)のみでつくったものも別ページで解説しているので、興味ある方は合わせて見てもらうとより理解が深まると思います。

ドロワーメニューをjQuery / javascript(Vanilla JS)のみで作る

よく使うドロワーメニューをjQueryまたは、javascriptのみで作ってみます。 目次ベースのHTML/CSSjQueryで書いた場合javascript(Vanilla JS)で書いた場合 ベ ...

続きを見る

個人的な感想で言うと、ドロワーメニュー作成の難易度というかお手軽度的には、jQuery > javascript > cssと言う感じです。とは言え案件によってはjQueryが使えない場合やjavascriptが使えない場合もあるので、できるに越したことはないと思います。

脱初心者、中級者プログラマー、WEBデザイナーにUdemyがオススメです

脱初心者を目指しているプログラマー、WEBデザイナーの方にUdemyがオススメです。 もちろんプログラマー、WEBデザイナー以外にも3DCGデザイナー、CGデザイナーの方にもオススメです! これまで自 ...

続きを見る

そろそろ転職を考えた方が良いWEB制作会社の特徴チェックリスト

・転職したほうがいいWEB制作会社は?・もしかしてうちの会社ブラック? そんな疑問を持っている人にお答えします。 自分は約15年間WEB業界にいて、これまで2社ほどWEB制作会社を経験してきました。こ ...

続きを見る


-javascript

© 2022 MUKOLOG