Started working with CSS animations and I'm wondering if there's a more elegant way to manage (with class names) when an animation is on or off. The general pattern I have is like this:
<div class="base-class"></div>
<div class="base-class base-class-rest"></div>
<div class="base-class base-class-active"></div>
I really dislike the idea of having a css class for base-class-rest
that is different than just the base-class
. I came up with this solution because I needed a css state that animates from the end of the base-class-active
state back to a state of "rest". base-class
alone cannot achieve this because there is no animation defined in its css.
tl;dr: I'm toggling a color on and off but I've written too much code for a task this simple. How can I write less code?
Here's a pen: http://codepen.io/anon/pen/GpaJQa
html
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
css
@keyframes box-active {
0% { background-color: black; }
100% { background-color: green; }
}
@keyframes box-rest {
0% { background-color: green; }
100% { background-color: currentColor; }
}
.box {
height: 50px;
width: 50px;
background-color: black;
display: inline-block;
margin: 5px;
}
.box-active {
animation: box-active 1s 1 forwards;
}
.box-rest {
animation: box-rest 1s 1 forwards;
}
js
Array.prototype.slice.call(document.querySelectorAll(".box")).forEach(function(el) {
el.addEventListener("click", click("box", "box-rest", "box-active"));
});
function click(none, rest, active) {
return function(e) {
var classname = e.target.className;
var arr = classname.split(" ");
var index = [arr.indexOf(none), arr.indexOf(rest), arr.indexOf(active)];
//no state
if (index[1] < 0 && index[2] < 0) {
arr.push(active);
return e.target.className = arr.join(" ");
}
//at rest
if (index[2] > -1) {
arr.splice(index[1], 1);
arr.push(rest);
}
//active
else {
arr.splice(index[2], 1);
arr.push(active);
}
e.target.className = arr.join(" ");
};
}