8192.jp

【CSS】ハンバーガーメニューに使えそうなボタンのアニメーションを4つ作っておいた

Web制作 2022/07/12 2022/07/12

実務でも結構な頻度で作ることになるハンバーガーメニューですが、毎回1から作るのは面倒なのでコピペで使えるように4パターンほど用意してみました。

基本パターン(三本線から✕に)

HTML

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<div class="menu_btn">
<i></i>
<i></i>
<i></i>
</div>
<div class="menu_btn btn_w">
<i></i>
<i></i>
<i></i>
</div>
<div class="menu_btn btn_b">
<i></i>
<i></i>
<i></i>
</div>
<div class="menu_btn"> <i></i> <i></i> <i></i> </div> <div class="menu_btn btn_w"> <i></i> <i></i> <i></i> </div> <div class="menu_btn btn_b"> <i></i> <i></i> <i></i> </div>
<div class="menu_btn">
	<i></i>
	<i></i>
	<i></i>
</div>
<div class="menu_btn btn_w">
	<i></i>
	<i></i>
	<i></i>
</div>
<div class="menu_btn btn_b">
	<i></i>
	<i></i>
	<i></i>
</div>

.btn_w.btn_bは白黒の見た目をチェックするために並べただけです。iは三本線に使うパーツですね。ここは疑似要素を使っても良かったかなぁ…

CSS

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
.menu_btn{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 80px;
height: 80px;
cursor: pointer;
}
.menu_btn i{
border-radius: 100vw;
margin: 6% 0;
width: 60%;
height: 4%;
background: #000;
transition: 0.5s;
}
.menu_btn.show i:nth-child(1){
transform: translateY(400%) rotate(45deg);
}
.menu_btn.show i:nth-child(2){
opacity: 0;
}
.menu_btn.show i:nth-child(3){
transform: translateY(-400%) rotate(-45deg);
}
/* 白黒ボタン用 */
.btn_w{
background: #fff;
}
.btn_b{
background: #000;
}
.btn_b i{
background: #fff;
}
.menu_btn{ display: flex; flex-direction: column; justify-content: center; align-items: center; width: 80px; height: 80px; cursor: pointer; } .menu_btn i{ border-radius: 100vw; margin: 6% 0; width: 60%; height: 4%; background: #000; transition: 0.5s; } .menu_btn.show i:nth-child(1){ transform: translateY(400%) rotate(45deg); } .menu_btn.show i:nth-child(2){ opacity: 0; } .menu_btn.show i:nth-child(3){ transform: translateY(-400%) rotate(-45deg); } /* 白黒ボタン用 */ .btn_w{ background: #fff; } .btn_b{ background: #000; } .btn_b i{ background: #fff; }
.menu_btn{
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	width: 80px;
	height: 80px;
	cursor: pointer;
}
.menu_btn i{
	border-radius: 100vw;
	margin: 6% 0;
	width: 60%;
	height: 4%;
	background: #000;
	transition: 0.5s;
}
.menu_btn.show i:nth-child(1){
	transform: translateY(400%) rotate(45deg);
}
.menu_btn.show i:nth-child(2){
	opacity: 0;
}
.menu_btn.show i:nth-child(3){
	transform: translateY(-400%) rotate(-45deg);
}

/* 白黒ボタン用 */
.btn_w{
	background: #fff;
}
.btn_b{
	background: #000;
}
.btn_b i{
	background: #fff;
}

今回紹介するハンバーガーメニューはボタンクリック時に.showというクラスをjQueryで付与するので、三本線それぞれに動作を指定しています。

あと、サイズを気にせずコピペ出来るように、メニューボタンの縦横以外は固定値を使わずに%で指定しました。

…なので、メニューボタンのwidthheightが同じ値(正方形)なら常に同じサイズ感で三本線が配置・リサイズされます。

jQuery

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$(".menu_btn").on("click",function(){
$(this).toggleClass("show")
});
$(".menu_btn").on("click",function(){ $(this).toggleClass("show") });
$(".menu_btn").on("click",function(){
	$(this).toggleClass("show")
});

.menu_btnクリック時に、.showというクラスをトグルさせて動きを制御しています。

表示結果

これが一番良く見る形ですよね。

正直これだけ用意しとけば十分っちゃ十分なんですが、一応別パターンも作ったのでそちらも紹介します。

アニメーション追加Ver.1

三本線が一度中央に集まってから✕に変形するアニメーション。これは使い勝手が良さそうです。

CSS・jQuery

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
.menu_btn.close i:nth-child(1){
animation: anm_close_1 0.5s forwards;
}
.menu_btn.show i:nth-child(1){
animation: anm_show_1 0.5s forwards;
}
.menu_btn.show i:nth-child(2) {
opacity: 0;
}
.menu_btn.close i:nth-child(3){
animation: anm_close_3 0.5s forwards;
}
.menu_btn.show i:nth-child(3){
animation: anm_show_3 0.5s forwards;
}
@keyframes anm_show_1{
50% {transform: translateY(400%) rotate(0deg)}
100%{transform: translateY(400%) rotate(45deg)}
}
@keyframes anm_close_1{
0% {transform: translateY(400%) rotate(45deg)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
}
@keyframes anm_show_3{
50% {transform: translateY(-400%) rotate(0deg)}
100%{transform: translateY(-400%) rotate(-45deg)}
}
@keyframes anm_close_3{
0% {transform: translateY(-400%) rotate(-45deg)}
50% {transform: translateY(-400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
}
.menu_btn.close i:nth-child(1){ animation: anm_close_1 0.5s forwards; } .menu_btn.show i:nth-child(1){ animation: anm_show_1 0.5s forwards; } .menu_btn.show i:nth-child(2) { opacity: 0; } .menu_btn.close i:nth-child(3){ animation: anm_close_3 0.5s forwards; } .menu_btn.show i:nth-child(3){ animation: anm_show_3 0.5s forwards; } @keyframes anm_show_1{ 50% {transform: translateY(400%) rotate(0deg)} 100%{transform: translateY(400%) rotate(45deg)} } @keyframes anm_close_1{ 0% {transform: translateY(400%) rotate(45deg)} 50% {transform: translateY(400%) rotate(0)} 100%{transform: translateY(0) rotate(0)} } @keyframes anm_show_3{ 50% {transform: translateY(-400%) rotate(0deg)} 100%{transform: translateY(-400%) rotate(-45deg)} } @keyframes anm_close_3{ 0% {transform: translateY(-400%) rotate(-45deg)} 50% {transform: translateY(-400%) rotate(0)} 100%{transform: translateY(0) rotate(0)} }
.menu_btn.close i:nth-child(1){
	animation: anm_close_1 0.5s forwards;
}
.menu_btn.show i:nth-child(1){
	animation: anm_show_1 0.5s forwards;
}
.menu_btn.show i:nth-child(2) {
	opacity: 0;
}
.menu_btn.close i:nth-child(3){
	animation: anm_close_3 0.5s forwards;
}
.menu_btn.show i:nth-child(3){
	animation: anm_show_3 0.5s forwards;
}
@keyframes anm_show_1{
	50% {transform: translateY(400%) rotate(0deg)}
	100%{transform: translateY(400%) rotate(45deg)}
}
@keyframes anm_close_1{
	0%  {transform: translateY(400%) rotate(45deg)}
	50% {transform: translateY(400%) rotate(0)}
	100%{transform: translateY(0) rotate(0)}
}
@keyframes anm_show_3{
	50% {transform: translateY(-400%) rotate(0deg)}
	100%{transform: translateY(-400%) rotate(-45deg)}
}
@keyframes anm_close_3{
	0%  {transform: translateY(-400%) rotate(-45deg)}
	50% {transform: translateY(-400%) rotate(0)}
	100%{transform: translateY(0) rotate(0)}
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$(".menu_btn").on("click",function(){
if($(this).hasClass("show")){
$(this).removeClass("show").addClass("close")
}else{
$(this).addClass("show").removeClass("close")
}
});
$(".menu_btn").on("click",function(){ if($(this).hasClass("show")){ $(this).removeClass("show").addClass("close") }else{ $(this).addClass("show").removeClass("close") } });
$(".menu_btn").on("click",function(){
	if($(this).hasClass("show")){
		$(this).removeClass("show").addClass("close")
	}else{
		$(this).addClass("show").removeClass("close")
	}
});

CSSのanimationプロパティを使って、少し凝った動きをさせてみました。

jQuery部分ですが、最初のサンプルと同じコードだとページ読み込み時に余計なアニメーションが走ってしまったのでちょっとだけ書き換えています(なんかもっと良い方法ありそう)。

アニメーション追加Ver.2

Z回転させつつ、回転中は背景を丸めてみました。なんかお洒落だけど使い所はあんまり無さそう。

CSS

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
.menu_btn.show{
animation: anm_show 0.5s forwards;
}
.menu_btn.close{
animation: anm_close 0.5s forwards;
}
.menu_btn i{
border-radius: 100vw;
margin: 6% 0;
width: 60%;
height: 4%;
background: #000;
transition: 0.5s;
}
.menu_btn.close i:nth-child(1){
animation: anm_close_1 0.5s forwards;
}
.menu_btn.show i:nth-child(1){
animation: anm_show_1 0.5s forwards;
}
.menu_btn.show i:nth-child(2) {
opacity: 0;
}
.menu_btn.close i:nth-child(3){
animation: anm_close_3 0.5s forwards;
}
.menu_btn.show i:nth-child(3){
animation: anm_show_3 0.5s forwards;
}
@keyframes anm_show{
0% {transform: rotateZ(0);}
50% {border-radius:50%;}
100%{transform: rotateZ(180deg);}
}
@keyframes anm_close{
0% {transform: rotateZ(180deg);}
50% {border-radius:50%;}
100%{transform: rotateZ(360deg);}
}
@keyframes anm_show_1{
0% {transform: translateY(0%) rotate(0)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(400%) rotate(45deg)}
}
@keyframes anm_close_1{
0% {transform: translateY(400%) rotate(45deg)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
}
@keyframes anm_show_3{
0% {transform: translateY(0%) rotate(0)}
50% {transform: translateY(-400%) rotate(0)}
100%{transform: translateY(-400%) rotate(-45deg)}
}
@keyframes anm_close_3{
0% {transform: translateY(-400%) rotate(-45deg)}
50% {transform: translateY(-400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
}
.menu_btn.show{ animation: anm_show 0.5s forwards; } .menu_btn.close{ animation: anm_close 0.5s forwards; } .menu_btn i{ border-radius: 100vw; margin: 6% 0; width: 60%; height: 4%; background: #000; transition: 0.5s; } .menu_btn.close i:nth-child(1){ animation: anm_close_1 0.5s forwards; } .menu_btn.show i:nth-child(1){ animation: anm_show_1 0.5s forwards; } .menu_btn.show i:nth-child(2) { opacity: 0; } .menu_btn.close i:nth-child(3){ animation: anm_close_3 0.5s forwards; } .menu_btn.show i:nth-child(3){ animation: anm_show_3 0.5s forwards; } @keyframes anm_show{ 0% {transform: rotateZ(0);} 50% {border-radius:50%;} 100%{transform: rotateZ(180deg);} } @keyframes anm_close{ 0% {transform: rotateZ(180deg);} 50% {border-radius:50%;} 100%{transform: rotateZ(360deg);} } @keyframes anm_show_1{ 0% {transform: translateY(0%) rotate(0)} 50% {transform: translateY(400%) rotate(0)} 100%{transform: translateY(400%) rotate(45deg)} } @keyframes anm_close_1{ 0% {transform: translateY(400%) rotate(45deg)} 50% {transform: translateY(400%) rotate(0)} 100%{transform: translateY(0) rotate(0)} } @keyframes anm_show_3{ 0% {transform: translateY(0%) rotate(0)} 50% {transform: translateY(-400%) rotate(0)} 100%{transform: translateY(-400%) rotate(-45deg)} } @keyframes anm_close_3{ 0% {transform: translateY(-400%) rotate(-45deg)} 50% {transform: translateY(-400%) rotate(0)} 100%{transform: translateY(0) rotate(0)} }
.menu_btn.show{
	animation: anm_show 0.5s forwards;
}
.menu_btn.close{
	animation: anm_close 0.5s forwards;
}
.menu_btn i{
	border-radius: 100vw;
	margin: 6% 0;
	width: 60%;
	height: 4%;
	background: #000;
	transition: 0.5s;
}
.menu_btn.close i:nth-child(1){
	animation: anm_close_1 0.5s forwards;
}
.menu_btn.show i:nth-child(1){
	animation: anm_show_1 0.5s forwards;
}
.menu_btn.show i:nth-child(2) {
	opacity: 0;
}
.menu_btn.close i:nth-child(3){
	animation: anm_close_3 0.5s forwards;
}
.menu_btn.show i:nth-child(3){
	animation: anm_show_3 0.5s forwards;
}

@keyframes anm_show{
	0%  {transform: rotateZ(0);}
	50% {border-radius:50%;}
	100%{transform: rotateZ(180deg);}
}
@keyframes anm_close{
	0%  {transform: rotateZ(180deg);}
	50% {border-radius:50%;}
	100%{transform: rotateZ(360deg);}
}

@keyframes anm_show_1{
	0%  {transform: translateY(0%) rotate(0)}
	50% {transform: translateY(400%) rotate(0)}
	100%{transform: translateY(400%) rotate(45deg)}
}
@keyframes anm_close_1{
	0%  {transform: translateY(400%) rotate(45deg)}
	50% {transform: translateY(400%) rotate(0)}
	100%{transform: translateY(0) rotate(0)}
}
@keyframes anm_show_3{
	0%  {transform: translateY(0%) rotate(0)}
	50% {transform: translateY(-400%) rotate(0)}
	100%{transform: translateY(-400%) rotate(-45deg)}
}
@keyframes anm_close_3{
	0%  {transform: translateY(-400%) rotate(-45deg)}
	50% {transform: translateY(-400%) rotate(0)}
	100%{transform: translateY(0) rotate(0)}
}

スクリプトはVer1と同じです。

アニメーション追加Ver.3

X回転にperspectiveを加えることで、立体感を出しています。これはそこまで派手じゃないので割と使えるかも?

CSS

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
.menu_btn.show{
animation: anm_show 0.5s forwards;
}
.menu_btn.close{
animation: anm_close 0.5s forwards;
}
.menu_btn i{
border-radius: 100vw;
margin: 6% 0;
width: 60%;
height: 4%;
background: #000;
transition: 0.5s;
}
.menu_btn.close i:nth-child(1){
animation: anm_close_1 0.5s forwards;
}
.menu_btn.show i:nth-child(1){
animation: anm_show_1 0.5s forwards;
}
.menu_btn.show i:nth-child(2) {
opacity: 0;
}
.menu_btn.close i:nth-child(3){
animation: anm_close_3 0.5s forwards;
}
.menu_btn.show i:nth-child(3){
animation: anm_show_3 0.5s forwards;
}
@keyframes anm_show{
0% {transform: perspective(500px) rotateX(0);}
100%{transform: perspective(500px) rotateX(180deg);}
}
@keyframes anm_close{
0% {transform: perspective(500px) rotateX(180deg);}
100%{transform: perspective(500px) rotateX(360deg);}
}
@keyframes anm_show_1{
0% {transform: translateY(0%) rotate(0)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(400%) rotate(45deg)}
}
@keyframes anm_close_1{
0% {transform: translateY(400%) rotate(45deg)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
}
@keyframes anm_show_3{
0% {transform: translateY(0%) rotate(0)}
50% {transform: translateY(-400%) rotate(0)}
100%{transform: translateY(-400%) rotate(-45deg)}
}
@keyframes anm_close_3{
0% {transform: translateY(-400%) rotate(-45deg)}
50% {transform: translateY(-400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
}
.menu_btn.show{ animation: anm_show 0.5s forwards; } .menu_btn.close{ animation: anm_close 0.5s forwards; } .menu_btn i{ border-radius: 100vw; margin: 6% 0; width: 60%; height: 4%; background: #000; transition: 0.5s; } .menu_btn.close i:nth-child(1){ animation: anm_close_1 0.5s forwards; } .menu_btn.show i:nth-child(1){ animation: anm_show_1 0.5s forwards; } .menu_btn.show i:nth-child(2) { opacity: 0; } .menu_btn.close i:nth-child(3){ animation: anm_close_3 0.5s forwards; } .menu_btn.show i:nth-child(3){ animation: anm_show_3 0.5s forwards; } @keyframes anm_show{ 0% {transform: perspective(500px) rotateX(0);} 100%{transform: perspective(500px) rotateX(180deg);} } @keyframes anm_close{ 0% {transform: perspective(500px) rotateX(180deg);} 100%{transform: perspective(500px) rotateX(360deg);} } @keyframes anm_show_1{ 0% {transform: translateY(0%) rotate(0)} 50% {transform: translateY(400%) rotate(0)} 100%{transform: translateY(400%) rotate(45deg)} } @keyframes anm_close_1{ 0% {transform: translateY(400%) rotate(45deg)} 50% {transform: translateY(400%) rotate(0)} 100%{transform: translateY(0) rotate(0)} } @keyframes anm_show_3{ 0% {transform: translateY(0%) rotate(0)} 50% {transform: translateY(-400%) rotate(0)} 100%{transform: translateY(-400%) rotate(-45deg)} } @keyframes anm_close_3{ 0% {transform: translateY(-400%) rotate(-45deg)} 50% {transform: translateY(-400%) rotate(0)} 100%{transform: translateY(0) rotate(0)} }
.menu_btn.show{
	animation: anm_show 0.5s forwards;
}
.menu_btn.close{
	animation: anm_close 0.5s forwards;
}
.menu_btn i{
	border-radius: 100vw;
	margin: 6% 0;
	width: 60%;
	height: 4%;
	background: #000;
	transition: 0.5s;
}
.menu_btn.close i:nth-child(1){
	animation: anm_close_1 0.5s forwards;
}
.menu_btn.show i:nth-child(1){
	animation: anm_show_1 0.5s forwards;
}
.menu_btn.show i:nth-child(2) {
	opacity: 0;
}
.menu_btn.close i:nth-child(3){
	animation: anm_close_3 0.5s forwards;
}
.menu_btn.show i:nth-child(3){
	animation: anm_show_3 0.5s forwards;
}

@keyframes anm_show{
	0%  {transform: perspective(500px) rotateX(0);}
	100%{transform: perspective(500px) rotateX(180deg);}
}
@keyframes anm_close{
	0%  {transform: perspective(500px) rotateX(180deg);}
	100%{transform: perspective(500px) rotateX(360deg);}
}
@keyframes anm_show_1{
	0%  {transform: translateY(0%) rotate(0)}
	50% {transform: translateY(400%) rotate(0)}
	100%{transform: translateY(400%) rotate(45deg)}
}
@keyframes anm_close_1{
	0%  {transform: translateY(400%) rotate(45deg)}
	50% {transform: translateY(400%) rotate(0)}
	100%{transform: translateY(0) rotate(0)}
}
@keyframes anm_show_3{
	0%  {transform: translateY(0%) rotate(0)}
	50% {transform: translateY(-400%) rotate(0)}
	100%{transform: translateY(-400%) rotate(-45deg)}
}
@keyframes anm_close_3{
	0%  {transform: translateY(-400%) rotate(-45deg)}
	50% {transform: translateY(-400%) rotate(0)}
	100%{transform: translateY(0) rotate(0)}
}

これもスクリプトはVer1と同じです。


以上、ハンバーガーメニューのアニメーション紹介でした。

こういうWebサイト制作で頻繁に使うパーツは、備忘録も兼ねてブログで積極的に公開していこうかなぁと思っているんで、興味のある方はフォローや購読をお願いします🙄