Edited at

三本線のメニューアイコンから×マークに変化するアニメーションいろいろ

More than 1 year has passed since last update.

CSSでアニメーションができるわけですし、どうせならちょっとアクセントをつけたいって感じのやつです。


三本線から×に変化させる

いろいろアイデアありますね。

JavaScriptはクラス名を変更するためだけにちょろっと使ってるだけなのでシンプルです。

チェックボックスを活用したJavaScriptを完全に使わない方法もありますが割愛。

まず、以下のHTMLとCSSは共通で使用するものとします。


HTML

<div class="menuWrapper">

<a href="#menu" id="menuButton"><span>MENU</span></a>
</div>


CSS

.menuWrapper {

position: relative;
z-index: 0;
border: 1px solid #ccc;
width: 50px;
height: 50px;
}

#menuButton {
overflow: hidden;
display: block;
position: relative;
z-index: 0;
width: 50px;
height: 50px;
cursor: pointer;
}

#menuButton span,
#menuButton::before,
#menuButton::after {
display: block;
position: absolute;
top: 0;
bottom: 0;
left:0;
right: 0;
width: 36px;
height: 4px;
margin: auto;
background: #000;
}
#menuButton span {
overflow: hidden;
z-index: 1;
color: #000;
}
#menuButton::before {
z-index: 2;
transform: translate(0, -12px);
content: "";
}
#menuButton::after {
z-index: 2;
transform: translate(0, 12px);
content: "";
}


こんな感じの表示になります。

sample.png


サンプル1

sample1.gif

実際の動作サンプル1


CSS

#menuButton span {

opacity: 1;
transition: opacity 150ms 50ms;
}
#menuButton::before,
#menuButton::after {
transition: transform 200ms;
}

#menuButton.active span {
opacity: 0;
transition: opacity 150ms;
}
#menuButton.active::before {
transform: rotate(45deg);
}
#menuButton.active::after {
transform: rotate(-45deg);
}



JavaScript

document.addEventListener('DOMContentLoaded', function () {

document.getElementById('menuButton').addEventListener('click', function (ev) {
ev.preventDefault();
this.classList.toggle('active');
});
});


サンプル2

sample2.gif

実際の動作サンプル2


CSS

#menuButton span {

transition: transform 150ms 50ms;
}
#menuButton::before,
#menuButton::after {
transition: transform 200ms;
}

#menuButton.active span {
transform: translate(-50px, 0);
transition: transform 150ms;
}
#menuButton.active::before {
transform: rotate(45deg);
}
#menuButton.active::after {
transform: rotate(-45deg);
}



JavaScript

document.addEventListener('DOMContentLoaded', function () {

document.getElementById('menuButton').addEventListener('click', function (ev) {
ev.preventDefault();
this.classList.toggle('active');
});
});


サンプル3

sample3.gif

実際の動作サンプル3


CSS

#menuButton {

transition: transform 300ms;
}
#menuButton span {
opacity: 1;
transition: opacity 200ms;
}
#menuButton::before,
#menuButton::after {
transition: transform 200ms;
}

#menuButton.active {
transform: rotate(180deg);
}
#menuButton.active span {
opacity: 0;
}
#menuButton.active::before {
transform: rotate(45deg);
}
#menuButton.active::after {
transform: rotate(-45deg);
}



JavaScript

document.addEventListener('DOMContentLoaded', function () {

document.getElementById('menuButton').addEventListener('click', function (ev) {
ev.preventDefault();
this.classList.toggle('active');
});
});


サンプル4

sample4.gif

実際の動作サンプル4


CSS

@keyframes lineTop {

50% {
transform: translate(0, 0);
}
100% {
transform: rotate(45deg);
}
}
@keyframes lineMiddle {
50%, 100% {
opacity: 0;
}
}
@keyframes lineBottom {
50% {
transform: translate(0, 0);
}
100% {
transform: rotate(-45deg);
}
}

#menuButton.active span {
animation: lineMiddle 250ms step-end forwards;
}
#menuButton.active::before {
animation: lineTop 250ms forwards;
}
#menuButton.active::after {
animation: lineBottom 250ms forwards;
}

#menuButton.default span {
animation: lineMiddle 250ms step-end reverse;
}
#menuButton.default::before {
animation: lineTop 250ms reverse;
}
#menuButton.default::after {
animation: lineBottom 250ms reverse;
}



JavaScript

document.addEventListener('DOMContentLoaded', function () {

document.getElementById('menuButton').addEventListener('click', function (ev) {
var classList = this.classList;
ev.preventDefault();
if (classList.contains('active')) {
classList.remove('active');
requestAnimationFrame(function () {
classList.add('default');
});
} else {
classList.remove('default');
requestAnimationFrame(function () {
classList.add('active');
});
}
});
});


大きさやアニメーションの速度などいじって自分好みにカスタマイズしてみるといいかもしれません。