これまで何度か記事で取り上げてきました。
▼Part1ではハンバーガーメニューの概要からUI/UX考察。
webabc.hatenablog.jp ▼Part2ではCSSのみのシンプル実装コードをまとめています。
今回はそのハンバーガーメニューのコードレシピ解説と題して、いくつか動きのバリエーションをつくって解説したいと思います。
CSSアニメーションでタップで動くハンバーガーメニュー
基本コードはPart.2の記事をベースに、アイコンの動きに必要な部分だけに絞って省略しています。
#1「二本線メニューアイコン→交差して閉じるアイコン」
2本線のアイコン。タップすると交差して×になり、閉じるアイコンに切り替わります。
一番シンプルなアニメーションですね。
線が2本だとハンバーガーには見えづらいですが、一応ハンバーガーメニューの亜種ということでご容赦を。。
HTML
<div id="top-editarea">
<!-- メニュー表示切り替え用チェックボックス -->
<input type="checkbox" id="main-nav" class="d-none">
<!-- スマホ用ハンバーガーメニューアイコン -->
<div class="nav-icon-wrap">
<label for="main-nav" class="nav-icon"></label>
</div>
</div>
CSS
*{
margin: 0;padding: 0;
box-sizing: border-box;
}
.d-none{
display: none;
}
.nav-icon-wrap{
position: absolute;
top: 0;
left: 0;
box-shadow: 0 0 1px #333;
}
.nav-icon{
position: relative;
display: block;
width: 10em;
height: 10em;
}
.nav-icon::before, .nav-icon::after{
content: "";
display: block;
width: 60%;
border-top: 1px solid #555;
position: absolute;
top: 30%;
left: 20%;
transition: .3s all;
}
.nav-icon::after{
top: 70%;
}
#main-nav:checked ~ nav{
display: block;
left: 0;
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon::before{
top: 50%;
transform: rotate(45deg);
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon::after{
top: 50%;
transform: rotate(-45deg);
}
今回解説用にわかりやすくnav-iconクラスで幅高さを10emとして大きくしています。
実際に使用する際には2emあたりが丁度いいのではないかなと思います。
適宜調節してください。
コード解説
.nav-iconクラスの:beforeと:afterの疑似要素が上下のボーダーになっています。
.nav-iconにposition: relative;を指定し、疑似要素にposition: absolute;を指定。
.nav-iconの位置を基準とし、疑似要素をそれぞれ上下に、top: 30%;とtop: 70%;の位置へ配置しています。
▼checkboxとlabelを使ったオンオフ切り替えについては過去記事にて詳細解説していますのでご参照ください。
webabc.hatenablog.jp
▼positionを使った配置については以下の記事で詳しく解説しています。
#2「三本線ハンバーガーメニュー→交差して閉じるアイコン」
三本線がハンバーガーに見えるいわゆるハンバーガーメニューのアイコン。
動きも真ん中の線が消えて上下がクロスする定番のシンプルなものです。
HTML
<div id="top-editarea">
<!-- メニュー表示切り替え用チェックボックス -->
<input type="checkbox" id="main-nav" class="d-none">
<!-- スマホ用ハンバーガーメニューアイコン -->
<div class="nav-icon-wrap">
<label for="main-nav" class="nav-icon">
<span></span>
<span></span>
<span></span>
</label>
</div>
</div>
CSS
*{
margin: 0;padding: 0;
box-sizing: border-box;
}
.d-none{
display: none;
}
.nav-icon-wrap{
position: absolute;
top: 0;
left: 0;
box-shadow: 0 0 1px #333;
}
.nav-icon{
position: relative;
display: block;
width: 10em;
height: 10em;
}
.nav-icon span{
content: "";
display: block;
width: 60%;
border-top: 1px solid #555;
position: absolute;
top: 30%;
left: 20%;
transition: .3s all;
}
.nav-icon span:nth-child(2){
top: 50%;
}
.nav-icon span:nth-child(3){
top: 70%;
}
#main-nav:checked ~ nav{
display: block;
left: 0;
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(1){
top: 50%;
transform: rotate(45deg);
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(2){
opacity: 0;
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(3){
top: 50%;
transform: rotate(-45deg);
}
コード解説
2本線アイコンでは疑似要素を使いましたが、こちらは<span></span>を3つ。
それぞれがアイコンの線になっています。
<span></span>にはクラスをつけていないので、セレクタを.nav-icon span:nth-child()としています。
疑似クラス「:nth-child()」
:nth-child()はその階層内の兄弟要素の中で何番目の要素かを、順番で指定できる疑似クラス。
これによって上中下の位置へ配置したり動きを指定しています。
.nav-icon span:nth-child(2)は2番目、つまり真ん中の線なので、クリックした時にopacity: 0;として透明に消えるようにしています。
#3「スピンするハンバーガーメニューアイコン」
基本の動きはほぼ#2と同じですが、さらに回転の度合いを増やしたパターンです。
コードもほぼ#2と同じなのでCSSの記述の下部、3本線の動きの部分のみ置き換えて頂ければと思います。
CSS
/* 3本線クリック後以外省略 */
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(1){
top: 50%;
transform: rotate(405deg);
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(2){
transform: rotate(360deg);
opacity: 0;
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(3){
top: 50%;
transform: rotate(-405deg);
}
コード解説
上下の線はtransform: rotate(405deg);、またはrotate(-405deg);として、1回転+45度の回転をさせています。
真ん中の線もopacity: 0;によって消えながらtransform: rotate(360deg);と1回転させています。
これによって回転速度を上げてよりスピン感を増した動きになっています。
#4「ステンシル風ハンバーガーメニューアイコン」
クリックして閉じた時の×アイコンが、線の重なり部分が白く縁とられ、ステンシル風になります。
CSS
/* 3本線クリック後以外省略 */
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(1){
top: 50%;
transform: rotate(225deg);
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(2){
transform: rotate(-225deg);
border-top-width: 9px;
border-color: #fff;
top: calc(50% - 5px);
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(3){
top: 50%;
transform: rotate(-225deg);
}
コード解説
回転はそれぞれ225度にして、#3より少し遅めています。
真ん中の線の色をborder-color: #fff;で白く、太さをborder-top-width: 9px;で太くして、太くしてもちょうど真ん中にくるようtop: calc(50% - 5px);と太くなった分calc()を使って位置調整しています。
この白く太くした2本目の線が、1本目と3本目の線の間に挟まって、上に来る3本目の線がステンシル風に白く縁とられて見えるようになっています。
#5「ブラインド風ハンバーガーメニューアイコン」
ブラインドやのれんを上にあげるように、3本の線が上に動いて束になって消え、×が浮かび上がります。
CSS
/* クリック後以外省略 */
#main-nav:checked ~ nav{
display: block;
left: 0;
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span{
top: 20%;
border-color: #fff;
}
.nav-icon span:nth-child(2)::before, .nav-icon span:nth-child(2)::after{
content: "";
display: block;
width: 100%;
border-top: 1px solid #555;
position: absolute;
top: 2em;
left: 0;
transition: .3s all;
opacity: 0;
z-index: 1;
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(2)::before{
top: 0;
transform: translateY(2.5em) rotate(45deg);
opacity: 1;
}
#main-nav:checked ~ .nav-icon-wrap>.nav-icon span:nth-child(2)::after{
top: 0;
transform: translateY(2.5em) rotate(-45deg);
opacity: 1;
}
コード解説
まず、ブラインド風に3本の線が全てtop: 20%; border-color: #fff;となって、上に移動しながら白くなって消えたようになります。
opacityを使っていないのは、浮かび上がる×の閉じるアイコンが疑似要素で作られているため、親の線をopacityで透明にすると子も消えてしまうからです。
.nav-icon span:nth-child(2)::before, .nav-icon span:nth-child(2)::afterというセレクタで、2本目の線の疑似要素として×アイコンになる部分を用意しています。
こちらのクリック前はopacity: 0;で消して問題ないです。
top: 2em;や、クリック後のtransform: translateY(2.5em)としている部分は、表示させる際に少し下から浮かび上がるように設定しています。
ただ、今回分かりやすいよう全体を幅高さ10emと大きくとっているので、実際の利用の際にはそれぞれtop: 0.2em;、transform: translateY(0.5em)といったように調整して頂ければと思います。
動くハンバーガーアイコン5種、是非使ってください
今回自分でアイコンの動きのパターンを作成してみて思ったのは、案外時間がかかるということ。
CSSでの動きの理解が既に出来ているのであれば、コードはあまり気にせず流用してサイト制作にご活用いただければ嬉しいです。
実際の制作現場では車輪の再発明をしていると時間がいくらあっても足りませんからね。
ただ、車輪がどんな仕組みで動いてるのか、理屈を自分の目で確かめることは重要です。
動きの理解がまだという方は今回や過去記事のコード解説を読み返して、学習に役立ててもらえたらと思います。
▼こういったサンプルがたくさん掲載されているレシピブックなども、実際自分で使うと非常に勉強になると思います。
最後までお読みいただきありがとうございました!
▼基礎からレスポンシブまでカバーしたプロになるシリーズ。スマホサイトの作成の参考になると思います。