JSFiddle - React, Tailwind, and code Playground
HTML
<div class="options">
<label>Roundnefss <input onchange="update()" type="range" min="0" max="100" id="roundness" value="50"></label><br>
<label>Opacity <input onchange="update()" type="range" min="0" max="60" id="opacity" value="0"></label><br>
<label>Color <input onchange="update()" type="color" id="color" value="#333333"></label><br>
<label>Spin <input onchange="update()" type="checkbox" id="spin"></label>
</div>
<div id="workspace">
<div style="font-size: 16px">
<div class="menu">
<span class="bar bar-1"></span>
<span class="bar bar-2"></span>
<span class="bar bar-3"></span>
</div>
</div>
<div style="font-size: 32px">
<div class="menu">
<span class="bar bar-1"></span>
<span class="bar bar-2"></span>
<span class="bar bar-3"></span>
</div>
</div>
<div style="font-size: 64px">
<div class="menu">
<span class="bar bar-1"></span>
<span class="bar bar-2"></span>
<span class="bar bar-3"></span>
</div>
</div>
<div style="font-size: 128px">
<div class="menu">
<span class="bar bar-1"></span>
<span class="bar bar-2"></span>
<span class="bar bar-3"></span>
</div>
</div>
<div style="font-size: 256px">
<div class="menu">
<span class="bar bar-1"></span>
<span class="bar bar-2"></span>
<span class="bar bar-3"></span>
</div>
</div>
</div>
CSS
body {
font-family: sans-serif;
}
.options {
color: black;
position: fixed;
top: 5px;
right: 5px;
z-index: 1;
background: white;
border: 1px solid #ccc;
padding: 0.5em;
border-radius: 3px;
}
.options label {
cursor: pointer;
}
.menu {
display: inline-block;
width: 1em;
cursor: pointer;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-webkit-tap-highlight-color: transparent;
}
.bar {
position: relative;
width: 0.8em;
height: 0.15em;
top: 0;
left: 0.1em;
margin: 0.1em 0;
background-color: currentColor;
display: block;
transition: 500ms all cubic-bezier(.87,-.41,.19,1.44), 0ms color, 0ms opacity;
}
.round .menu .bar {
border-radius: 0.15em;
}
.trans .menu .bar {
opacity: 0.5;
}
.hide .menu .bar {
display: none;
}
.spin .menu {
transform: rotate(180deg);
transition: 500ms all cubic-bezier(.87,-.41,.19,1.44);
}
.spin .menu:hover {
transform: rotate(0deg);
}
.menu:hover .bar-2 {
width: 0.85em;
left: 0.15em;
}
.menu:hover .bar-1 {
width: 0.5em;
left: 0;
top: 0.125em;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.menu:hover .bar-3 {
width: 0.5em;
left: 0;
top: -0.125em;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
JavaScript
// this script is not used for animation
// it is only used to update user-changed variables
var workspace = document.getElementById('workspace');
var bars = workspace.getElementsByTagName('span');
function update() {
var roundness = document.getElementById('roundness').value / 100 * 0.15 / 2;
var opacity = document.getElementById('opacity').value / 100;
workspace.className = document.getElementById('spin').checked ? 'spin' : '';
workspace.style.color = document.getElementById('color').value;
for(var i=0; i<bars.length; i++) (function(bar) {
bar.style.borderRadius = roundness + 'em';
bar.style.opacity = opacity;
forceReflow(bar);
})(bars[i]);
}
update();
function forceReflow(elem) {
elem.style.display = 'none';
// we call this twice to skip a frame rather than render in the next
(window.requestAnimationFrame || setTimeout)(function() {
(window.requestAnimationFrame || setTimeout)(function() {
elem.style.display = '';
}, 20);
}, 20);
}