Animation for a mobile menu toggle. Three horizontal lines transform into a cross and back again. The top and bottom lines fall into the center, transforming into one line. The line(s) rotate clockwise, spawning a line at 45deg and stop at 135 deg, forming a cross. Demo: http://jsfiddle.net/SYYr5/7/
Annotations:
- the animation uses four additional elements inside the a tag. This is not semantic, but at we can at least use elements without a semantic meaning, like div and span
- using a div as a second container, we are able to apply a padding to our a tag
- inTop/outTop, inMiddle/outMiddle and inBottom/outBottom are the same animation. This seemed to be the only way to 'restart' the animation.
- Adding 180deg looks even better ;) but is a bit laggy sometimes :/
- We may need to use vendor prefixes :/
The HTML-Snippet:
<a id="toggle-menu">
<div>
<span class="top"></span>
<span class="middle"></span>
<span class="bottom"></span>
</div>
</a>
The SCSS-Snippet:
#toggle-menu {
display: block;
width: 15px;
height: 15px;
padding: 20px;
cursor: pointer;
div {
width: 15px;
height: 15px;
position: relative;
}
span {
display: block;
width: 15px;
height: 3px;
background: black;
position: absolute;
animation-fill-mode:forwards;
&.top {
top: 0px;
}
&.middle {
top: 6px;
}
&.bottom {
top: 12px;
}
}
&.visible {
span.top {
animation: inTop 0.8s forwards;
}
span.middle {
animation: inMiddle 0.8s forwards;
}
span.bottom {
animation: inBottom 0.8s forwards;
}
}
&.hidden {
span.top {
animation: outTop 0.8s backwards;
animation-direction: reverse;
}
span.middle {
animation: outMiddle 0.8s backwards;
animation-direction: reverse;
}
span.bottom {
animation: outBottom 0.8s backwards;
animation-direction: reverse;
}
}
}
@keyframes inMiddle {
25% {
transform: rotate(0deg);
}
100% {
transform: rotate(45deg);
}
}
@keyframes outMiddle {
50% {
transform: rotate(0deg);
}
100% {
transform: rotate(45deg);
}
}
@keyframes inTop {
0% {
top: 0;
}
25% {
top: 6px;
transform: rotate(0deg);
}
100% {
top: 6px;
transform: rotate(135deg);
}
}
@keyframes outTop {
0% {
top: 0;
}
50% {
top: 6px;
transform: rotate(0deg);
}
100% {
top: 6px;
transform: rotate(135deg);
}
}
@keyframes inBottom {
0% {
top: 12px;
}
25% {
top: 6px;
transform: rotate(0deg);
opacity: 1;
}
100% {
top: 6px;
transform: rotate(135deg);
opacity: 0;
}
}
@keyframes outBottom {
0% {
top: 12px;
}
50% {
top: 6px;
transform: rotate(0deg);
opacity: 0;
}
100% {
top: 6px;
transform: rotate(135deg);
opacity: 1;
}
}