Transform not working properly on anchor - html

I am trying to animate a button making it translate a little bit to the right for a specific time, but somehow the transition never happens.
#keyframes moveXpath {
0% {
transform: translateX(-10px);
}
100% {
transform: translateX(100px);
}
}
.btn-animate {
animation-name: moveXpath;
animation-duration: 10s;
}
<body>
<div class="container">
<h1>button animation</h1>
<div class="buttons">
rotating button
</div>
</div>
</body>
lost some time and can't figure out what is wrong any help?

Anchor are inline elements transform does not work on these type of elements.
Add a different display (block or inline-block) to your anchor
.btn-animate {
animation-name: moveXpath;
animation-duration: 10s;
display: inline-block;
}
Source: w3.org

Related

CSS Animations skip in Firefox when animated element is out of viewport

Try using this JSFiddle in Chrome and in Firefox.
Here's the code:
(HTML)
<div class="slide-down">
<h1>Hello!</h1>
</div>
(CSS)
.slide-down {
font-size: 3em;
-moz-animation-duration: 3s;
-webkit-animation-duration: 3s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-moz-animation-name: slideDown;
-webkit-animation-name: slideDown;
}
#-moz-keyframes slideDown {
0% {
-moz-transform:translateY(-300px);
}
100% {
-moz-transform:translateY(0px);
}
}
#-webkit-keyframes slideDown {
0% {
-webkit-transform: translateY(-300px);
}
100% {
-webkit-transform: translateY(0px);
}
}
My issue is that it works in Chrome but only works in Firefox when the starting coordinates (at the "0%" point of the animation) of the animated div are within the viewport. Otherwise, it can completely skip the animation. Try changing the translateY() parameter to something more conservative, like -50px, and it will work.
Is there a workaround for this? It would be nice to be able to bring something in from outside the screen without having to write a script to figure out what its initial y-coordinate should be.
I would consider animating the margin instead:
.slide-down {
font-size: 3em;
animation:slideDown 3s forwards;
}
#keyframes slideDown {
0% {
margin-top:-300px;
}
100% {
margin-top:0;
}
}
<div class="slide-down">
<h1>Hello!</h1>
</div>

css animation-name property does not allow transform property

I have the library animate.css loaded on my website and I animate an arrow moving onto the page using "fadeInLeftBig"
My html:
<div class="swipe-button b-left animated fadeInLeftBig"></div>
My css:
.swipe-button.b-left {
left: 10px;
background-image: url(/images/left-arrow.png);
}
.swipe-button:hover {
transform: rotate(90deg) !important;
}
Animate.css
.fadeInLeftBig {
animation-name: fadeInLeftBig;
}
.animated {
animation-duration: 1s;
animation-fill-mode: both;
}
#keyframes fadeInLeftBig {
0% {
opacity: 0;
transform: translateX(-2000px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
The transform: rotate(90deg) does not work on hover as long as animation-name: fadeInLeftBig is set on the element. But works if you unceck or comment it out.
I can see now there are two transform properties on the element, but Why does setting the animation-name property override the transform property with an !important flag from taking effect?
As vals stated earlier..an animation overrides the static properties. For what you're trying to achieve, you're best bet is to wrap your swipe-button class with a new fadeInLeftBig div:
<div class="fadeInLeftBig animated">
<div class="swipe-button b-left animated"></div>
</div>
Then use keyframe animations on both divs. This separates your animations so that your "fade in" doesn't start over once you unhover your swipe-button. Here's a working fiddle. https://jsfiddle.net/kj4v36ye/2/ Let me know if you're trying to achieve something else and I can easily modify it.
First at you code your don't close '}' in .fadeInLeftBig.
look at this fiddle:
<div class="swipe-button b-left animated fadeInLeftBig"></div>
and css
.swipe-button.b-left {
left: 10px;
background-color: blue;
width: 50px;
height: 50px;
}
.swipe-button:hover {
transform: rotate(45deg);
}
.fadeInLeftBig {
animation-name: fadeInLeftBig;
}
.animated {
animation-duration: 1s;
animation-fill-mode: both;
}
https://jsfiddle.net/kj4v36ye/

How to smoothly revert CSS animation to its current state?

I've got not animated element as default. There's also a trigger that lets me turn on & off animation on that element. The animation itself is very simple: moves element from left to the right and back.
When I stop animation, then my element obviously goes back to initial position. But it goes back suddenly, not smoothly. So it just changes its position from the one when I turned off animation to initial one. My question is: is there a way to stop it smoothly, so when I turn off the animation it goes back to initial position but smoothly/animating.
Here's my element and animation: http://jsfiddle.net/2Lwftq6r/
HTML:
<input type="checkbox" id="anim">
<label for="anim">Start / stop animation</label>
<div></div>
CSS:
div {
margin-top: 50px;
width: 50px; height: 10px;
background: #000;
transform: translateX(0);
}
#anim:checked ~ div {
-webkit-animation: dance 2s infinite ease-in-out;
-moz-animation: dance 2s infinite ease-in-out;
}
#-webkit-keyframes dance {
0%, 100% { -webkit-transform: translateX(0); }
50% { -webkit-transform: translateX(300px); }
}
#-moz-keyframes dance {
0%, 100% { -moz-transform: translateX(0); }
50% { -moz-transform: translateX(300px); }
}
I just had the same problem and I solved it by not using animation and it works perfectly! Check out my solution:
So I had this spatula that I had to move when hovered over only, and I wanted it to transition back smoothly, so this is what I did:
#Spatula:hover{
animation-direction:alternate;
transform: translate(1.2cm,1cm);
transition: all 1.5s;
-webkit-transition: all 1.5s;
}
#Spatula{
-webkit-transition: all 1.5s;
transition: all 1.5s;
}
Good luck!
You can't archive this effect only CSS3 way, but if you really need it, you could use jQuery + CSS3 Transitions. My solution (http://jsfiddle.net/sergdenisov/3jouzkxr/10/):
HTML:
<input type="checkbox" id="anim-input">
<label for="anim-input">Start / stop animation</label>
<div class="anim-div"></div>
CSS:
.anim-div {
margin-top: 50px;
width: 50px;
height: 10px;
background: #000;
}
.anim-div_active {
-webkit-animation: moving 2s ease-in-out infinite alternate;
animation: moving 2s ease-in-out infinite alternate;
}
.anim-div_return {
-webkit-transition: -webkit-transform 0.5s ease-in-out;
transition: transform 0.5s ease-in-out;
}
#-webkit-keyframes moving {
0% { -webkit-transform: translateX(0); }
100% { -webkit-transform: translateX(300px); }
}
#keyframes moving {
0% { transform: translateX(0); }
100% { transform: translateX(300px); }
}
Javascript:
$('#anim-input').on('change', function() {
var $animDiv = $('.anim-div');
if (this.checked) {
$animDiv.removeClass('anim-div_return')
.addClass('anim-div_active');
return;
}
var transformValue = $animDiv.css('webkitTransform') ||
$animDiv.css('transform');
$animDiv.css({'webkitTransform': transformValue,
'transform': transformValue})
.removeClass('anim-div_active');
requestAnimationFrame(function() {
$animDiv.addClass('anim-div_return')
.css({'webkitTransform': 'translateX(0)',
'transform': 'translateX(0)'});
});
});
P.S.
Vendor prefixes are based on actual browsers list from http://caniuse.com.
Check out This StackOverflow question.
You aren't going to like this answer, but reality is that CSS3
animations aren't really useful to achieve this. To make this work you
would need to replicate a lot of your CSS in your Javascript which
kind of destroys the point (Like for example in this closely related
answer
Change speed of animation CSS3?).
To really make it stop smoothly your best bet would be to write the
animation on a platform like the Greensock animation library
which provides all the tools you need to make it actually smoothly
stop instead of suddenly stop.
There's also another answer below it that does make an effort at using CSS, you can look at that one.
There is also an alternate solution, it might not give you the desired effect of going back to it's original state, but since nobody mentioned it and this problem seems to have no solution, it's possible to pause the animation purely in css, locking it's state until it's started again
To pause the animation you need first to make the animation available even when the checkbox is not checked
And make use of the animation-play-state property
div {
margin-top: 50px;
width: 50px; height: 10px;
background: #000;
animation: dance 2s infinite ease-in-out paused;
}
#anim:checked ~ div {
animation-play-state: running;
}
#keyframes dance {
0%, 100% { transform: translateX(0); }
50% { transform: translateX(300px); }
}
<input type="checkbox" id="anim">
<label for="anim">Start / stop animation</label>
<div></div>

Adding class via js won't trigger css animation

I have a modified version of animate.css (added some delay, new timings and new positions), and it works really great when the classes are set by default (html document). But when I am adding the animate class dynamically via js, the animation is not executed!
Even more annoying, I did have it working at some point, but I can't get it to work again (using gumby framework and inview js to add a class when the element is on screen (adding .animated)) . The left box had the classes already in the html, and the right box have the .animate class added by js.
Example:
http://onepageframework.com/28_2_14/strange_anim.html
Any ideas why the right box is not animating?
Using the Gumby inview extension: http://gumbyframework.com/docs/extensions/#!/inview
Edit: added html:
<div class="six columns text-center fadeInLeftMedium delay_2 animated">
<!-- left box content here -->
</div>
<div class="six columns text-center fadeInLeftMedium delay_2 inview" data-classname="animated">
<!-- right box content here -->
</div>
css:
.animated {
-webkit-animation-duration: 1s;
-moz-animation-duration: 1s;
-o-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
}
.delay_2 {
-webkit-animation-delay: 2s;
-moz-animation-delay: 2s;
-o-animation-delay: 2s;
animation-delay: 2s;
}
#-webkit-keyframes fadeInLeftMedium {
0% {
opacity: 0;
-webkit-transform: translateX(-400px);
}
100% {
opacity: 1;
-webkit-transform: translateX(0);
}
}
#-moz-keyframes fadeInLeftMedium {
0% {
opacity: 0;
-moz-transform: translateX(-400px);
}
100% {
opacity: 1;
-moz-transform: translateX(0);
}
}
#-o-keyframes fadeInLeftMedium {
0% {
opacity: 0;
-o-transform: translateX(-400px);
}
100% {
opacity: 1;
-o-transform: translateX(0);
}
}
#keyframes fadeInLeftMedium {
0% {
opacity: 0;
transform: translateX(-400px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
.fadeInLeftMedium {
-webkit-animation-name: fadeInLeftMedium;
-moz-animation-name: fadeInLeftMedium;
-o-animation-name: fadeInLeftMedium;
animation-name: fadeInLeftMedium;
}
The reason is the same why you can't re-trigger CSS based animations by just subsequently removing and adding a class. The reason is that browsers batch-up these modifications and optimize away the animation.
Reason and solutions are discussed here.
From the article, your options are (paraphrased):
Add a small delay before re-adding the class (not recommended)
Clone the element, remove it, and insert the clone
Have 2 identical animations (attached to different css rules) and switch between them
Trigger a reflow between removing and adding the class name:
element.classList.remove("run-animation");
// element.offsetWidth = element.offsetWidth; //doesn't work in strict mode
void element.offsetWidth; // reading the property requires a recalc
element.classList.add("run-animation");
Change (cycle) the element's CSS animation-play-state attribute to paused or running (does not restart animation)
By swaping the classes, it looks like it got it to work (aminated in the class, and fadeInLeftMedium as the data-classname):
<div class="six columns text-center fadeInLeftMedium delay_2 animated">
<!-- left box content here -->
</div>
<div class="six columns text-center animated delay_2 inview" data-classname="fadeInLeftMedium">
<!-- right box content here -->
</div>
I think you just need to add animated as a class rather than as data-classname="animated"...
So basically:
<div class="six columns text-center fadeInLeftMedium delay_2 inview" data-classname="animated">
<!-- right box content here -->
</div>
Should be:
<div class="six columns text-center fadeInLeftMedium delay_2 inview animated">
<!-- right box content here -->
</div>
Otherwise the animation lacks a specified animation duration and without the animation-duration property specified the animation won't work.

Hover Animation won't disappear when not hovering

I have a div I've animated on hover. However when I am not hovering the div won't disappear
This is what the entire thing looks like in action: http://jsfiddle.net/Vbxtc/
This is the html:
<nav>
<div id="controls">
<button id="playButton">Play</button>
<div id="defaultBar">
<div id="progressBar"></div>
</div>
<button id="vol" onclick="level()">Vol</button>
<button id="mute">Mute</button>
<button id="full" onclick="toggleFullScreen()">Full</button>
</div>
<div id="playlist" class="animated fadeInRight">
<div>cats</div>
<div>cats</div>
<div>cats</div>
</div>
</nav>
This is the CSS i've made:
#playlist{
position:absolute;
display:block;
border:1px solid red;
height: 82%;
width: 25%;
top: 20px;
right: 0px;
z-index: 2;
float:right;
padding: 0px;
margin: 0px;
color:white;
background-color:#999999;
opacity: 0;
}
#playlist:hover {
opacity: 1;
}
This is the animation im trying
.animated:hover {
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-ms-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: 1s;
-moz-animation-duration: 1s;
-ms-animation-duration: 1s;
-o-animation-duration: 1s;
animation-duration: 1s;
}
.fadeInRight {
-webkit-animation-name: fadeInRight;
-moz-animation-name: fadeInRight;
-o-animation-name: fadeInRight;
animation-name: fadeInRight;
}
#-webkit-keyframes fadeOutRight {
0% {
opacity: 1;
-webkit-transform: translateX(0);
}
100% {
opacity: 0;
-webkit-transform: translateX(20px);
}
}
#-webkit-keyframes fadeInRight {
0% {
opacity: 0;
-webkit-transform: translateX(20px);
}
100% {
opacity: 1;
-webkit-transform: translateX(0);
}
}
I noticed that when you time the mouse over exactly right (hover for about 1 second and move mouse up top), it DOES fade out nicely.
The other thing is, if you add the class fadeOutRight as follows:
<div id="playlist" class="animated fadeInRight fadeOutRight">
It fades out too quickly.
I know I didn't help much but the answer lies in the timing.
Also, if you had the fadeOutRight class on, for example, the sidebar, it works nicely!
<aside id="sidebar" class="fadeOutRight">
Perhaps, put the class of fadeOutRight on everything EXCEPT the fadeInRight div.
It's not a good idea to play with an element position in the hover state.
Even if you get to program it right (that is not easy), most of the time the user won't understand what's happening.
You can get flickering scenarios where, without the user moving the cursor, your div leaves the cursor position, canceling the hover, the div re-entering the cursor, the hover triggering , and so on.
I would recomend to trigger the hover on another div that covers the full area where the moving div will be.