Using CSS and HTML, a checkbox, an index
and a content
div were created.
The index
has a fixed position and is floated floated at the left.
The content
adjusts its width to the available space and thus takes its place next to index
.
The checkbox
toggles between two states:
:not(:checked)
moves the index and content to the right.
:checked
moves the index and content to the left, pushing index
off-screen.
These moves are CSS3 animations: moveindexleft
, movecontentleft
, moveindexright
and movecontentright
.
index
and content
have their animation-play-state
initially set at paused
. Ticking the checkbox
changes that to running
. This is to prevent the animation being played right after the initial loading of the page.
Testing in Firefox 42.0 and Chromium 47.0.2526.80 (64-bit), the issue is that this initial animation-play-state: paused
is ignored.
The result: https://jsfiddle.net/Lmzyxzhs/
How can animation-play-state
in CSS be initially set to paused
and changed to running
?
N.b.: If initially set to animation-play-state: paused !important;
, then the checkbox toggle does not override this, disabling all animations.
Additionally, there seems to be a slight delay after clicking on the checkbox and initiating the animation. Can this be optimized?
CSS animation-play-state property specifies if the animation is running or it is paused. If you resume a paused animation it will start from where it was left off at the time it was paused, rather than starting from the beginning of the animation sequence.
The only way to truly pause an animation in CSS is to use the animation-play-state property with a paused value. In JavaScript, the property is “camelCased” as animationPlayState and set like this: We can create a toggle that plays and pauses the animation by reading the current value of animationPlayState:
The animation-play-state CSS property sets whether an animation is running or paused. Resuming a paused animation will start the animation from where it left off at the time it was paused, rather than starting over from the beginning of the animation sequence. The animation is currently playing. The animation is currently paused.
The animation-play-state property is used to specify whether an animation is running or paused. Animations in CSS allow you to change the state of an element.
There is no problem with the animation-play-state
property and none of the browsers ignore it. The problem that you are facing is because of the selectors and the way they work. The :not(:checked)
selector would match the original/default state of your checkbox also because, well, it is not selected. This combined with the fact that that the :not(:checked)
selector appears later in your CSS file and that it has more specificity than div#index
or div#content
selector makes the animation play state setting defined within this :not(:checked)
selector (which is running
) take precedence. This is the reason why the animation is getting executed on page load also.
As far as I am aware you cannot achieve both (a) pause the animation on load and (b) have a reverse animation when the checkbox is not checked using CSS selectors alone. At any given point, you can get only one of those to work.
Hence, the recommended solution for you would be to use JavaScript (or any preferred libraries) and add a class to the element the very first time the user clicks on the checkbox. Then the :checked
or :not(:checked)
styling can be applied only when the checkbox has this extra class.
var chkBox = document.getElementById('toggle');
chkBox.addEventListener('click', function(){
this.classList.add('user-interacted');
});
div#index {
position: fixed;
float: left;
width: 10em;
left: 0em;
animation-fill-mode: both;
animation-play-state: paused;
animation-duration: 1s;
}
div#content {
width: auto;
margin-left: 10em;
animation-fill-mode: both;
animation-play-state: paused;
animation-duration: 1s;
}
@keyframes moveindexleft {
0% {
left: 0em;
}
100% {
left: -10em;
}
}
@keyframes movecontentleft {
0% {
margin-left: 10em;
}
100% {
margin-left: 0em;
}
}
@keyframes moveindexright {
0% {
left: -10em;
}
100% {
left: 0em;
}
}
@keyframes movecontentright {
0% {
margin-left: 0em;
}
100% {
margin-left: 10em;
}
}
input[type=checkbox] {
display: none;
}
/* note the change in selectors */
input[type=checkbox].user-interacted:not(:checked) ~ div#index {
animation-play-state: running;
animation-name: moveindexright;
}
input[type=checkbox].user-interacted:not(:checked) ~ div#content {
animation-play-state: running;
animation-name: movecontentright;
}
input[type=checkbox].user-interacted:checked ~ div#index {
animation-play-state: running;
animation-name: moveindexleft;
}
input[type=checkbox].user-interacted:checked ~ div#content {
animation-play-state: running;
animation-name: movecontentleft;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<label for="toggle">
Button
</label>
<input id="toggle" type=checkbox>
<div id="index">
index
</div>
<div id="content">
content
</div>
Alternately, you can achieve the same effect by just using CSS transition
(as pointed out by vals in his comment). Transitions get triggered only when user clicks on the checkbox (unlike animation
which starts automatically on page load). Below is a sample snippet for this approach.
div#index {
position: fixed;
float: left;
width: 10em;
left: 0em;
transition: left 1s linear;
}
div#content {
width: auto;
margin-left: 10em;
transition: margin-left 1s linear;
}
input[type=checkbox] {
display: none;
}
input[type=checkbox]:not(:checked) ~ div#index {
left: 0em;
}
input[type=checkbox]:not(:checked) ~ div#content {
margin-left: 10em;
}
input[type=checkbox]:checked ~ div#index {
left: -10em;
}
input[type=checkbox]:checked ~ div#content {
margin-left: 0em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<label for="toggle">
Button
</label>
<input id="toggle" type=checkbox>
<div id="index">
index
</div>
<div id="content">
content
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With