ドロワーやモーダルをCSSだけで実現する方法

ドロワーやモーダルといった、いかにもクリックアクションをJavaScriptで操作している系の動きも実はCSSだけで実現できたりします。

仕組みの大枠としては、以下の3つを組み合わせる感じです。

  • チェックボックにあるチェックされた時のスタイルを適応できる:checked
  • クリック要素(チェックボックスのon/off)として使うfor属性
  • アニメーションを制御できるtransition

アニメーションの指定方法を見直すいい機会にもなるかと思うので、コピペするだけでなく実際にご自身で1から書いてみることもおすすめします!

はにわまん
この記事にあるアコーディオンアイコンは全部クリックできるので試してみてね!

事前学習:チェックボックスCSSの理解

CSSでのクリック操作において、チェックボックスのon / off の理解が不可欠になります。まずは、チェックボックスを理解していきましょう!(遠回りに見えますが、ちゃんと理解するためには必要な前提知識です…)

チェックボックのon / offのCSS上での動き

それでは、早速チェックボックスを書いていきましょう(※ わたしのチェックボックス表示はカスタマイズされてるので見栄えがデフォルトではないですが…)

(クリックしてみてください!)

<label><input id="my-checkbox" type="checkbox"><span>チェックしてみて!</span></label>

チェックされた時の文字色を変えてみる

チェックされた時の動きを制御するには、擬似クラスの「:checked」を使います。実際にチェックされた時に文字色を変えてみましょう。

(クリックしてみてください!)

#my-checkbox:checked span {
	color: #F4511E;
}

この:checkedがon / offの役割を果たすことになります。jQueryなどで言うところの、onClickと同様の動きをCSSで実現できるということですね。

チェックボックスとシンクロさせる「for」属性

ドロワーやモーダルを開くのに、チェックボックが表示されていたらダサいですよね(そもそもそんなデザインを見たことがない…)

チェックボックのon / off をチェックボックスの箇所じゃなくても別要素から動作させられる記述があります。それがfor="id-name"。forに対象のチェックボックのidを指定してあげます。

こっちは機能しません


(上部のエリアをクリックしてみてください!)

ここまで扱えるようになれば、チェックボックスの事前学習は終了です!

  • チェックボックス自体は非表示にして
  • forの要素をハンバーガーメニューや閉じるための要素に当てる

という流れで作っていく感じになります。

ドロワーを作ってみよう!

では、事前学習で学んだ:checkedを使ってドロワーメニューを作っていきましょう!

とりあえず完成品をドカッと貼る

まず完成した動くコードを貼ります。その後に個別に解説していく流れで進めていきます。

(クリックしてみてください!)

ここがドロワーとして出てくる部分です。
<input id="drawer-checkbox" type="checkbox">
<label id="drawer-icon" for="drawer-checkbox"><span></span></label>
<label id="drawer-close" for="drawer-checkbox"></label>
<div id="drawer-content">ここがドロワーとして出てくる部分です。</div>
#drawer-checkbox {
  display: none;
}
#drawer-icon {
  cursor: pointer;
  display: inline-block;
  height: 50px;
  position: relative;
  width: 50px;
}
#drawer-icon span {
  background:  #333;
  border-radius: 4px;
  display: block;
  height: 16%;
  left: 50%;
  margin: -8% 0 0 -42%;
  position: absolute;
  top: 50%;
  transition: all 0.3s ease-in-out;
  width: 84%;
}
#drawer-icon span::before,
#drawer-icon span::after {
  -webkit-transform: rotate(0);
  background: #333;
  border-radius: 4px;
  content: "";
  display: block;
  height: 100%;
  left: 50%;
  margin: -8% 0 0 -50%;
  position: absolute;
  top: 50%;
  transform: rotate(0);
  transition: all 0.3s ease-in-out;
  width: 100%;
}
#drawer-icon span::before {
  margin-top: -38%;
}
#drawer-icon span::after {
  margin-top: 19%;
}
#drawer-checkbox:checked ~ #drawer-icon span {
  background: rgba(51, 51, 51, 0);
}
#drawer-checkbox:checked ~ #drawer-icon span::before,
#drawer-checkbox:checked ~ #drawer-icon span::after {
  content: "";
  display: block;
  height: 100%;
  left: 50%;
  margin: -8% 0 0 -42%;
  position: absolute;
  top: 50%;
  width: 100%;
}
#drawer-checkbox:checked ~ #drawer-icon span::before {
  -webkit-transform: rotate(-45deg);
          transform: rotate(-45deg);
}
#drawer-checkbox:checked ~ #drawer-icon span::after {
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
}
#drawer-content {
  overflow: auto;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 40;
  width: 250px;
  max-width: 90%;
  height: 100%;
  background: #fff;
  transition: all 0.3s ease-in-out 0s;
  transform: translateX(-100%);
}
#drawer-checkbox:checked ~ #drawer-content {
  transform: translateX(0);
  box-shadow: 6px 0 25px rgba(0, 0, 0, 0.16);
}

#drawer-close {
  display: none;
  position: fixed;
  z-index: 39;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: 0;
  transition: all 0.3s ease-in-out 0s;
}
#drawer-checkbox:checked ~ #drawer-close {
  display: block;
  opacity: 0.3;
}

ドロワーを構成する要素は大きく2つですね。「ハンバーガーアイコン」とハンバーガーアイコンを押した時に表示される「ドロワーのエリア」。それぞれのパーツを小分けして見ていきましょう。

ハンバーガーとバツが切り替わるハンバーガーアイコンを作る

手前味噌で恐縮ですが、以下のハンバーガーアイコンを使いました。こちらも:checkedの仕組みで動いているものなので、そのまま使えそうです。

「ハンバーガー」アイコンをクリックしたら「バツ」アイコンにアニメーションする CSS

(クリックしてみてください!)

<input id="drawer-checkbox" type="checkbox">
<label id="drawer-icon" for=drawer-checkbox"><span></span></label>
#drawer-checkbox {
  display: none;
}
#drawer-icon {
  cursor: pointer;
  display: inline-block;
  height: 50px;
  position: relative;
  width: 50px;
}

#drawer-icon span {
  background:  #333;
  border-radius: 4px;
  display: block;
  height: 16%;
  left: 50%;
  margin: -8% 0 0 -42%;
  position: absolute;
  top: 50%;
  transition: all 0.3s ease-in-out 0s;
  width: 84%;
}
#drawer-icon span::before,
#drawer-icon span::after {
  -webkit-transform: rotate(0);
  background: #333;
  border-radius: 4px;
  content: "";
  display: block;
  height: 100%;
  left: 50%;
  margin: -8% 0 0 -50%;
  position: absolute;
  top: 50%;
  transform: rotate(0);
  transition: all 0.3s ease-in-out;
  width: 100%;
}
#drawer-icon span::before {
  margin-top: -38%;
}
#drawer-icon span::after {
  margin-top: 19%;
}
#drawer-checkbox:checked ~ #drawer-icon span {
  background: rgba(51, 51, 51, 0);
}
#drawer-checkbox:checked ~ #drawer-icon span::before,
#drawer-checkbox:checked ~ #drawer-icon span::after {
  content: "";
  display: block;
  height: 100%;
  left: 50%;
  margin: -8% 0 0 -42%;
  position: absolute;
  top: 50%;
  width: 100%;
}
#drawer-checkbox:checked ~ #drawer-icon span::before {
  -webkit-transform: rotate(-45deg);
          transform: rotate(-45deg);
}
#drawer-checkbox:checked ~ #drawer-icon span::after {
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
}

いきなり難しくなったように感じる方もいるかもしれません…。

言葉でザックリ解説すると、、、

  1. チェックボックスは非表示にする
  2. forの要素のチェックが押されていない状態をハンバーガーアイコンにして、
  3. チェックが押された状態をバツアイコンにする

という処理を行っています。

アイコンの実態は<span></span>に擬似要素のbeforeafterをするだけで実現させています。

滑らかにバツのアイコンに移行しているのは、transition: all 0.3s ease-in-out;を仕込んでいるからですね。ドロワーメニューやモーダルをCSSで表現する際には絶対に理解しておかなければならないアニメーションプロパティなので、理解していない方は以下の記事を参考に使えるようにしてください!

移ろいゆくアニメーションを表現するCSS「transition」について解説

ドロワーのコンテンツエリアを作る

横からニューって出てくるドロワーの本体(?)も作っていきましょう。ハンバーガーアイコンの動きが完璧に理解できている方なら、おおよその作りもイメージできるかもしれません。

(クリックしてみてください!)

ここがドロワーとして出てくる部分です。
<input id="drawer-checkbox" type="checkbox">
<label id="drawer-icon" for="drawer-checkbox"><span></span></label>
<div id="drawer-content">ここがドロワーとして出てくる部分です。</div>
#drawer-content {
	overflow: auto;
	position: fixed;
	top: 0;
	left: 0;
	z-index: 40;
	width: 250px;
	max-width: 90%;
	height: 100%;
	background: #fff;
	transition: all 0.3s ease-in-out 0s;
	transform: translateX(-100%);
}
#drawer-checkbox:checked ~ #drawer-content {
	transform: translateX(0);
	box-shadow: 6px 0 24px rgba(0, 0, 0, 0.16);
}

ドロワー以外の部分をクリックで閉じるようにする

ついでにドロワー以外の部分をクリックしたら閉じるようにしてみましょう。この辺を入れるか入れないかはサイトの設計によるかと思いますが。

以下のようにもう1つ:checkedのon/offとシンクロさせるためのforのラベルを追加してあげます。

(クリックしてみてください!)

ここがドロワーとして出てくる部分です。
<input id="drawer-checkbox" type="checkbox">
<label id="drawer-icon" for="drawer-checkbox"><span></span></label>
<label id="drawer-close" for="drawer-checkbox"></label>
<div id="drawer-content">ここがドロワーとして出てくる部分です。</div>
#drawer-close {
	display: none;
	position: fixed;
	z-index: 39;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: #000;
	opacity: 0;
	transition: all 0.3s ease-in-out 0s;
}
#drawer-checkbox:checked ~ #drawer-close {
	display: block;
	opacity: 0.3;
}

ポイントは、ドロワーのコンテンツアイテムよりも、#drawer-closez-indexを小さく設定することです。z-indexだけの並びで見てみると、以下のようになります。

#drawer-content {
	z-index: 40;
}
#drawer-close {
	z-index: 39;
}

この上下関係を逆にしてしまうと、ドロワーのコンテンツ部分も覆われてしまうことになるので、z-indexの値は意識して決めましょう!

on/offの要素はいくつでも作成可能

今までで、ハンバーガーアイコンと、全体を覆うクローズエリアの2つのon / offを扱うエリアができました。復習すると、チェックボックスをチェックさせるための要素をforで指定することで作れる仕組みだったと思います。

ハンバーガーと全体覆うためのクローズエリアだけのHTMLにすると以下のとおりです。

<input id="drawer-checkbox" type="checkbox">
<label id="drawer-icon" for="drawer-checkbox"><span></span></label>
<label id="drawer-close" for="drawer-checkbox"></label>

2つともチェックボックスのid="drawer-checkbox"forで指し示していることが分かります。このon / offの要素ですが、いくつでも作ることができます。

例えば、ドロワーメニュー内の下に閉じるボタンを追加したくなったときもfor="drawer-checkbox"の要素を作れば簡単に追加できるわけですね。意外と柔軟性があって、使い勝手いいドロワーメニューだと思います。

ドロワーの中に「閉じる」ボタンを追加してみた例です。
(クリックしてみてください!)

ここがドロワーとして出てくる部分です。

モーダルをCSSで作る

ドロワーがCSSで作れるようになったらモーダルはめっちゃ簡単です。仕組みとては、:chekedで表示/非表示を切り替えるだけなのでドロワーの作り方と全く同じです。

細かな説明はドロワーの方を見てもらうとして、早速つくってみます。

(クリックしてみてください!)

ここがモーダルとして表示される部分です。
<input id="modal-checkbox" type="checkbox">
<label id="modal-open" for="modal-checkbox">モーダルを開く</label>
<label id="modal-close" for="modal-checkbox"></label>
<div id="modal-content">ここがモーダルとして表示される部分です。</div>
#modal-checkbox {
  display: none;
}
#modal-open {
  cursor: pointer;
  display: inline-block;
  position: relative;
}
#modal-content {
  overflow: auto;
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: 40;
  background: #fff;
  transition: all 0.3s ease-in-out 0s;
  transform: translate(-50%, -50%);
  opacity: 0;
  box-shadow: 0 0 24px rgba(0, 0, 0, 0.16);
  padding: 1em;
}
#modal-checkbox:checked ~ #modal-content {
  opacity: 1;
}
#modal-close {
  display: none;
  position: fixed;
  z-index: 39;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: 0;
  transition: all 0.3s ease-in-out 0s;
}
#modal-checkbox:checked ~ #modal-close {
  display: block;
  opacity: 0.6;
}

ドロワーと:checkedの時の表示のさせ方を変えているだけです。モーダルでは、画面全体の中央にopacity: 0;からopacity: 1;で表示させるというやり方です。

おわり


CSSでドロワーとモーダルを実現する方法でした。この作り方が分かっていたら、jQueryなどのドロワー系のプラグイン等を使わなくても簡単に作成することができると思います。

閉じるボタンも好きなだけ増やせますし、CSSのスキル次第で色んなカスタマイズができるはずです。

ぜひ、チェックボックスの:checkedを覚えて自由自在にドロワーやモーダルを操ってみましょう!

このページが役に立ったら
いいね!お願いします

運営の励みになります...。

関連の記事