Is there a pure CSS way to move a div from one place to another and stop. What I have jumps back to original place.
#animate {
position: absolute;
top: 0px;
left: 0px;
animation: move 3s ease;
}
#keyframes move {
from { transform: translateX(0px); }
to { transform: translateX(500px); }
}
If I need JS for this, is there are way to condition on the end of the animation instead of moving it with timeout??
Try adding:
#animate {
// other styles...
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
You can see this working here.
Credit to this answer.
Related
I have worked on a searchbar that appears when user scrolls down the page, and disappears when they scroll up. I was able to get the animation working perfectly with position: fixed, however, the same styling is not working with position: absolute.
Apparently when the iOS keyboard appears, elements with position: fixed go haywire - so I must make this work with position: absolute. The problem now is that the behavior does not work at all. It is actually behaving almost in reverse, where it appears when the page load and immediately translates upward in a flickering manner. Can anyone come up with a solution?
My code below and is in ReactJS and Scss and you can find the sandbox version here: https://codesandbox.io/s/lxyx58jo4m?fontsize=14. If you are unfamiliar with React, isSearchBar is determining if the class is show-search-bar or hide-search-bar based on the scroll
<div className={`search-bar-mobile-container ${isSearchBar ? "show-search-bar" : "hide-search-bar"}`} >
<form>
</form>
</div>
#keyframes exit-up-search-bar {
from {
transform: translateY(0);
}
to {
transform: translateY(-76px);
height: 0;
}
}
#keyframes entrance-down-search-bar {
from {
transform: translateY(-100%);
}
to {
transform: translateY(0);
height: 76px;
}
}
.search-bar-mobile-container{
width: 100%;
height: 76px;
background-color: #00c0d1;
position: absolute;
z-index: 1000000001;
top:-76px;
transition: all 0.3s ease-out;
&.show-search-bar{
animation: entrance-down-search-bar 0.3s forwards;
animation-timing-function: ease-out;
top:0;
}
&.hide-search-bar{
animation: exit-up-search-bar 5s forwards;
animation-timing-function: ease-out;
top:-76px;
}
}
I am making a label pop up for the user, if the user tries to drag and drop an element that has already been dragged.
Problem is, that the animations only happens once, and at the end of the animation, it will have an opacity of 0 forever.
CSS
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0;}
}
.o_tip{
position: absolute;
z-index: 999;
display: none;
opacity: 0;
-webkit-animation: smooth 2s ease-in;
-moz-animation: smooth 2s ease-in;
-o-animation: smooth 2s ease-in;
-ms-animation: smooth 2s ease-in;
animation: smooth 2s ease-in;
}
To illustrate my problem, if I 'end' the animation on opacity: 0.2 instead of opacity: 0:
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0.2;}
}
... then the label will reappear for each event - but it will not fade out again, which I want to do.
You can put the animation rule in a specific css class rule, and then on clicking add that class again. Just keep these points in mind:
You need to remove the animation class first before adding it again to have any effect.
Even if you follow first point, removing the class and adding it back right then won't have any visual effect. To trigger reflow, you can use this statement: void targetDiv.offsetWidth;.
document.querySelector("#start-animation").onclick = function(e){
var targetDiv = document.querySelector("#mydiv");
targetDiv.className = "";
void targetDiv.offsetWidth; // this triggers UI reflow
targetDiv.classList.add("o_tip");
}//onclick
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0;}
}
.o_tip{
z-index: 999;
animation: smooth 2s ease-in forwards;
}
#mydiv{
background-color: yellow;
height: 50px;
width: 100px;
}
#mydiv.o_top{
display: block;
}
<div id="mydiv"></div>
<button id="start-animation">Start animation</button>
I am trying to animate a div element (slide and fade) with a button click. At first, the element is not visible to a user. When the button is clicked, it will slide to right and fade in. Once the button is clicked again, it will slide to left and fade out. I come up with two solutions, with css and with JQuery.
In the first one, I used JQuery. You can find the example in this JSFiddle 1.
HTML
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
CSS
#my-modal {
opacity: 1;
position: fixed;
top: 50px;
left: 0;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
}
JQuery
$("#my-button").click(function () {
var $modal = $("#my-modal");
$modal.stop(true, true).animate({
left: "toggle",
opacity: "toggle"
}, 1000);
});
Here, everything seems working but it does directly opposite of what I want. It first fades out, and with the second click, it fades in. It is because that the opacity of the element is 1, but if I turn it to 0, nothing happens.
Secondly, I tried to do that with css animation by using key-frames (changing opacity from 0 to 1) but it has also problem. It starts the animation exactly the way I want. However, when I click the button again, it disappears immediately. Here is the JSFiddle 2.
HTML
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
CSS
#my-modal {
opacity: 0;
position: fixed;
top: 50px;
left: 0;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
-moz-transition: all 1s ease;
-webkit-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
}
.move-my-modal {
-moz-transform: translate(250px, 0px);
-webkit-transform: translate(250px, 0px);
-ms-transform: translate(250px, 0px);
-o-transform: translate(250px, 0px);
}
.animate-opacity {
-webkit-animation: toggle-opacity 1s ease;
-moz-animation: toggle-opacity 1s ease;
-o-animation: toggle-opacity 1s ease;
animation: toggle-opacity 1s ease;
-webkit-animation-fill-mode: forwards;
}
#-webkit-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-moz-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-o-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
JQuery
$("#my-button").click(function () {
var $modal = $("#my-modal");
$modal.toggleClass("move-my-modal");
$modal.toggleClass("animate-opacity");
});
To this end, I have these questions;
1) What are the problems with these two approaches? Is there something that I missed or forgot to use? How can I correct them to meet the requirements that I mentioned at the beginning.
2) Which one is the better way to make this action? Is there any cons or pros of these approaches?
3) Is there any other way to make this action? I am new on this area and I might not notice a simpler way.
You can toggle an .active class to the element and use CSS transitions.
This way, if the browser is old enough to not support animations, it will still work but it won't slow down computers that do not handle animations well.
$("#my-button").click(function () {
$("#my-modal").toggleClass('active');
});
#my-modal.active {
opacity: 1;
left: 0;
}
$("#my-button").click(function () {
$("#my-modal").toggleClass('active');
});
#my-modal {
opacity: 0;
position: fixed;
top: 50px;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
transition: all 1s linear;
}
#my-modal.active {
opacity: 1;
left: 0;
}
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am try to have the caret in the following rotate 180 degrees on click for my dropdown menu. In the solution Im trying to implement, it changes the class of the the caret to toggle-up or toggle-down on click. The first time I click on it rotates up, the second time it immediately goes back to its starting position and then rotates back up. I smell dirty code, whats the easiest way to add this toggle rotation animation. Thanks in advance for any help. Heres my current css:
.toggle-up {
animation-name: toggle-up;
animation-delay: 0.25s;
animation-duration: 0.75s;
animation-fill-mode: forwards;
}
.toggle-down {
animation-name: toggle-down;
animation-delay: 0.25s;
animation-duration: 0.75s;
animation-fill-mode: forwards;
}
/*animations*/
#keyframes toggle-up {
100% {
transform: rotate(180deg);
}
}
#keyframes toggle-down {
100% {
transform: rotate(180deg);
}
}
You don't really need a keyframe animation for something this simple. If you just add a class to your icon on click then remove it this will apply your rotation. Here is a working plunkr using font awesome and a simple rotation. This is just a simple example, you will want to make use of vendor prefixes and be aware that css transitions do not work in older browsers.
<div id="container">
<i id="icon" class="fa fa-arrow-down"></i>
</div>
.fa-arrow-down{
transform: rotate(0deg);
transition: transform 1s linear;
}
.fa-arrow-down.open{
transform: rotate(180deg);
transition: transform 1s linear;
}
(function(document){
var div = document.getElementById('container');
var icon = document.getElementById('icon');
var open = false;
div.addEventListener('click', function(){
if(open){
icon.className = 'fa fa-arrow-down';
} else{
icon.className = 'fa fa-arrow-down open';
}
open = !open;
});
})(document);
.square {
width: 100px;
height: 100px;
background-color: #ff0000;
transition: all 0.75s 0.25s;
}
.toggle-up {
transform: rotate(180deg);
}
.toggle-down {
transform: rotate(0);
}
You should have an initial state in order to complete your animation.
Here is the example: codepen
UPDATE
Here is the version without using javascript: codepen
<label for="checkbox">
<input type="checkbox" id="checkbox">
<div class="square toggle-down"></div>
</label>
#checkbox {
display: none;
}
.square {
width: 100px;
height: 100px;
background-color: #ff0000;
transition: all 0.75s 0.25s;
transform: rotate(0);
}
#checkbox:checked + .square {
transform: rotate(180deg);
}
The general idea is to change the block class using Adjacent sibling selectors and the checkbox checked state.
I'm working on a game and just found out about -webkit-animation-play-state CSS attribute. I want certain text to show itself as a short animation, then hide and show when called again (in javascript).
I figured out how to start animation when I want to in javascript, but after its finished, the text stays on the screen, which I don't want to.
HTML:
<p id="INFO">
TEST
</p>
CSS:
#-webkit-keyframes pulse {
from {
opacity: 0.0;
font-size: 100%;
}
to {
opacity: 1.0;
font-size: 400%;
}
}
#INFO {
position: absolute;
left: 400px;
top: 200px;
-webkit-animation-name: pulse;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-play-state:paused;
visibility: hidden;
}
JS:
var INFO = document.getElementById("INFO");
INFO.innerHTML = "WRONG";
INFO.style.color = "RED";
INFO.style.webkitAnimationPlayState = "running";
INFO.style.visibility = "visible";
I read some questions/answers about -webkit-animation-play-state on this site, but none regarding the issue I am having.
One thing I read about was that animation goes to its default values when its ended. But my default values say that animation is "hidden" ? source: how to stop my webkit frame animation?
If anyone can point me in the right direction I'd be grateful.
If I was not clear enough, ask for more info please.
Thank you
For what you are trying to do, you don't need to use -webkit-animation-play-state.
Instead, try starting the animation by applying a class with the animation properties set. Then use a JavaScript event listener to remove the class once the animation finishes.
You should also keep the element hidden with opacity instead of visibility:hidden since you are manipulating the opacity in the animation.
CSS:
#-webkit-keyframes pulse {
from {
opacity: 0.0;
font-size: 100%;
}
to {
opacity: 1.0;
font-size: 400%;
}
}
#INFO {
opacity:0;
position: absolute;
left: 400px;
top: 200px;
}
.pulse {
-webkit-animation-name: pulse;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
}
JS:
var INFO = document.getElementById("INFO");
INFO.innerHTML = "WRONG";
INFO.style.color = "RED";
INFO.addEventListener('webkitAnimationEnd', function (e) {
this.classList.remove('pulse');
});
DEMO >> CodePen