実務でも結構な頻度で作ることになるハンバーガーメニューですが、毎回1から作るのは面倒なのでコピペで使えるように4パターンほど用意してみました。
基本パターン(三本線から✕に)
HTML
<div class="menu_btn btn_w">
<div class="menu_btn btn_b">
<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
.menu_btn.show i:nth-child(1){
transform: translateY(400%) rotate(45deg);
.menu_btn.show i:nth-child(2){
.menu_btn.show i:nth-child(3){
transform: translateY(-400%) rotate(-45deg);
.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で付与するので、三本線それぞれに動作を指定しています。
あと、サイズを気にせずコピペ出来るように、メニューボタンの縦横以外は固定値を使わずに%で指定しました。
…なので、メニューボタンのwidth
とheight
が同じ値(正方形)なら常に同じサイズ感で三本線が配置・リサイズされます。
jQuery
$(".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
.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) {
.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;
50% {transform: translateY(400%) rotate(0deg)}
100%{transform: translateY(400%) rotate(45deg)}
0% {transform: translateY(400%) rotate(45deg)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
50% {transform: translateY(-400%) rotate(0deg)}
100%{transform: translateY(-400%) rotate(-45deg)}
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)}
}
$(".menu_btn").on("click",function(){
if($(this).hasClass("show")){
$(this).removeClass("show").addClass("close")
$(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
animation: anm_show 0.5s forwards;
animation: anm_close 0.5s forwards;
.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) {
.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;
0% {transform: rotateZ(0);}
100%{transform: rotateZ(180deg);}
0% {transform: rotateZ(180deg);}
100%{transform: rotateZ(360deg);}
0% {transform: translateY(0%) rotate(0)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(400%) rotate(45deg)}
0% {transform: translateY(400%) rotate(45deg)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
0% {transform: translateY(0%) rotate(0)}
50% {transform: translateY(-400%) rotate(0)}
100%{transform: translateY(-400%) rotate(-45deg)}
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
animation: anm_show 0.5s forwards;
animation: anm_close 0.5s forwards;
.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) {
.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;
0% {transform: perspective(500px) rotateX(0);}
100%{transform: perspective(500px) rotateX(180deg);}
0% {transform: perspective(500px) rotateX(180deg);}
100%{transform: perspective(500px) rotateX(360deg);}
0% {transform: translateY(0%) rotate(0)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(400%) rotate(45deg)}
0% {transform: translateY(400%) rotate(45deg)}
50% {transform: translateY(400%) rotate(0)}
100%{transform: translateY(0) rotate(0)}
0% {transform: translateY(0%) rotate(0)}
50% {transform: translateY(-400%) rotate(0)}
100%{transform: translateY(-400%) rotate(-45deg)}
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サイト制作で頻繁に使うパーツは、備忘録も兼ねてブログで積極的に公開していこうかなぁと思っているんで、興味のある方はフォローや購読をお願いします
この記事が気に入ったらフォロー・シェアしてね!