This is a recreation of Android L's toggle menu icon in the action bar. The icon morphs into a back button when toggled.
A Pen by Jaune Sarmiento on CodePen.
<a href="#" class="toggle"> | |
<i class="icon"></i> | |
</a> | |
<br /> | |
<a href="#" class="toggle"> | |
<i class="icon"></i> | |
</a> |
(function () { | |
var findTarget = function (target) { | |
var i, toggles = document.querySelectorAll('.toggle'); | |
for (; target && target !== document; target = target.parentNode) { | |
for (i = toggles.length; i--;) { if (toggles[i] === target) return target; } | |
} | |
}; | |
var getTarget = function (e) { | |
var target = findTarget(e.target); | |
if (!target) return; | |
return target; | |
}; | |
var handleClick = function (e) { | |
var target = getTarget(e); | |
if (!target) return; | |
else e.preventDefault(); | |
toggleMenu(target); | |
}; | |
var toggleMenu = function (target) { | |
var icon = target.querySelector(".icon"); | |
icon.classList.add("transitioning"); | |
icon.addEventListener("webkitAnimationEnd", onAnimationEnd, false); | |
function onAnimationEnd(e) { | |
icon.classList.toggle("active"); | |
icon.classList.remove("transitioning"); | |
e.stopImmediatePropagation(); | |
} | |
}; | |
document.addEventListener("click", handleClick, false); | |
})(); |
* { | |
box-sizing: border-box; | |
} | |
.toggle { | |
display: inline-block; | |
padding: 12px; | |
width: 48px; | |
height: 48px; | |
} | |
.icon { | |
display: block; | |
margin: 10px 1px; | |
width: 22px; | |
height: 2px; | |
background-color: black; | |
position: relative; | |
} | |
.icon:before { | |
position: absolute; | |
display: block; | |
content: ''; | |
background-color: black; | |
bottom: 6px; | |
width: 22px; | |
height: 2px; | |
} | |
.icon:after { | |
position: absolute; | |
display: block; | |
content: ''; | |
background-color: black; | |
top: 6px; | |
width: 22px; | |
height: 2px; | |
} | |
.icon.transitioning { | |
-webkit-animation: rotate 0.3s ease-in-out; | |
} | |
.icon.transitioning:before { | |
-webkit-animation: rotate-top 0.3s ease-in-out; | |
} | |
.icon.transitioning:after { | |
-webkit-animation: rotate-bottom 0.3s ease-in-out; | |
} | |
.icon.active { | |
-webkit-transform: rotate(180deg); | |
width: 18px; | |
margin-left: 4px; | |
} | |
.icon.active:before { | |
-webkit-transform: rotate(45deg); | |
width: 13px; | |
margin-left: 9px; | |
bottom: 4px; | |
} | |
.icon.active:after { | |
-webkit-transform: rotate(-45deg); | |
width: 13px; | |
margin-left: 9px; | |
top: 4px; | |
} | |
.icon.active.transitioning { | |
-webkit-animation: rotate-back 0.3s ease-in-out; | |
} | |
.icon.active.transitioning:before { | |
-webkit-animation: rotate-top-back 0.3s ease-in-out; | |
} | |
.icon.active.transitioning:after { | |
-webkit-animation: rotate-bottom-back 0.3s ease-in-out; | |
} | |
@-webkit-keyframes rotate { | |
from { | |
-webkit-transform: rotate(0deg); | |
} | |
to { | |
-webkit-transform: rotate(180deg); | |
width: 18px; | |
margin-left: 4px; | |
} | |
} | |
@-webkit-keyframes rotate-back { | |
from { | |
width: 18px; | |
margin-left: 4px; | |
} | |
to { | |
-webkit-transform: rotate(360deg); | |
width: 22px; | |
margin-left: 1px; | |
} | |
} | |
@-webkit-keyframes rotate-top { | |
from { | |
-webkit-transform: rotate(0deg); | |
} | |
to { | |
-webkit-transform: rotate(45deg); | |
width: 13px; | |
margin-left: 9px; | |
bottom: 4px; | |
} | |
} | |
@-webkit-keyframes rotate-top-back { | |
from { | |
width: 13px; | |
margin-left: 9px; | |
bottom: 4px; | |
} | |
to { | |
-webkit-transform: rotate(0deg); | |
width: 22px; | |
bottom: 6px; | |
margin-left: 0; | |
} | |
} | |
@-webkit-keyframes rotate-bottom { | |
from { | |
-webkit-transform: rotate(0deg); | |
} | |
to { | |
-webkit-transform: rotate(-45deg); | |
width: 13px; | |
margin-left: 9px; | |
top: 4px; | |
} | |
} | |
@-webkit-keyframes rotate-bottom-back { | |
from { | |
width: 13px; | |
margin-left: 9px; | |
top: 4px; | |
} | |
to { | |
-webkit-transform: rotate(0deg); | |
width: 22px; | |
margin-left: 0; | |
top: 6px; | |
} | |
} |