I am trying to animate an element's transform property, but I noticed it's not working as I expect on IE (surprisingly).
when animating from
0% { transform: translateX(-50%) translateY(150px); }
to
100% { transform: translateX(-50%); }
It seems to ignore the translateX(-50%);
This is the way I use the animation on the html element (I use forwards so the final state of the animation is the one that remains applied to the element):
animation: myanimation 1s ease-out forwards;
I've being trying to solve this for a while, even trying from translate(-50%, 150px) to translate(-50%, 0px) but still it won't work.
Here's a working fiddle to quickly see the difference. It works well on Chrome, but misbehaves on IE.
use transform: translate(X, Y) it works on IE ( use vendor prefix for IE9 -ms-transform )
#keyframes myanimation {
0% { transform: translate(50%, 150px); } /* i suppose -50% is a typo, if it's not replace it with -50% */
100% { transform: translate(-50%, 0); }
}
#anim {
display: inline-block;
animation: myanimation 1s ease-out forwards;
}
<h1 id="anim">Hello World</h1>
You want to animate X from -50% to -50%? If you want to animate the Y coordinate, then set the value on your target percent.
100% { transform: translateX(-50%) translateY(0); }
why not? This works on IE. I've tested.
Related
So, it is possible to have reverse animation on mouse out such as:
.class{
transform: rotate(0deg);
}
.class:hover{
transform: rotate(360deg);
}
but, when using #keyframes animation, I couldn't get it to work, e.g:
.class{
animation-name: out;
animation-duration:2s;
}
.class:hover{
animation-name: in;
animation-duration:5s;
animation-iteration-count:infinite;
}
#keyframe in{
to {transform: rotate(360deg);}
}
#keyframe out{
to {transform: rotate(0deg);}
}
What is the optimal solution, knowing that I'd need iterations and animation itself?
http://jsfiddle.net/khalednabil/eWzBm/
I think that if you have a to, you must use a from.
I would think of something like :
#keyframe in {
from: transform: rotate(0deg);
to: transform: rotate(360deg);
}
#keyframe out {
from: transform: rotate(360deg);
to: transform: rotate(0deg);
}
Of course must have checked it already, but I found strange that you only use the transform property since CSS3 is not fully implemented everywhere. Maybe it would work better with the following considerations :
Chrome uses #-webkit-keyframes, no particuliar version needed
Safari uses #-webkit-keyframes since version 5+
Firefox uses #keyframes since version 16 (v5-15 used #-moz-keyframes)
Opera uses #-webkit-keyframes version 15-22 (only v12 used #-o-keyframes)
Internet Explorer uses #keyframes since version 10+
EDIT :
I came up with that fiddle :
http://jsfiddle.net/JjHNG/35/
Using minimal code. Is it approaching what you were expecting ?
Its much easier than all this: Simply transition the same property on your element
.earth { width: 0.92%; transition: width 1s; }
.earth:hover { width: 50%; transition: width 1s; }
https://codepen.io/lafland/pen/MoEaoG
I don't think this is achievable using only CSS animations. I am assuming that CSS transitions do not fulfil your use case, because (for example) you want to chain two animations together, use multiple stops, iterations, or in some other way exploit the additional power animations grant you.
I've not found any way to trigger a CSS animation specifically on mouse-out without using JavaScript to attach "over" and "out" classes. Although you can use the base CSS declaration trigger an animation when the :hover ends, that same animation will then run on page load. Using "over" and "out" classes you can split the definition into the base (load) declaration and the two animation-trigger declarations.
The CSS for this solution would be:
.class {
/* base element declaration */
}
.class.out {
animation-name: out;
animation-duration:2s;
}
.class.over {
animation-name: in;
animation-duration:5s;
animation-iteration-count:infinite;
}
#keyframes in {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#keyframes out {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
And using JavaScript (jQuery syntax) to bind the classes to the events:
$(".class").hover(
function () {
$(this).removeClass('out').addClass('over');
},
function () {
$(this).removeClass('over').addClass('out');
}
);
Creating a reversed animation is kind of overkill to a simple problem. What you need is:
animation-direction: reverse
However, this won't work on its own because animation spec forgot to add a way to restart the animation, so here is how you do it with the help of JS
let item = document.querySelector('.item')
// play normal
item.addEventListener('mouseover', () => {
item.classList.add('active')
})
// play in reverse
item.addEventListener('mouseout', () => {
item.style.opacity = 0 // avoid showing the init style while switching the 'active' class
item.classList.add('in-active')
item.classList.remove('active')
// force dom update
setTimeout(() => {
item.classList.add('active')
item.style.opacity = ''
}, 5)
item.addEventListener('animationend', onanimationend)
})
function onanimationend() {
item.classList.remove('active', 'in-active')
item.removeEventListener('animationend', onanimationend)
}
#keyframes spin {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(180deg);
}
}
div {
background: black;
padding: 1rem;
display: inline-block;
}
.item {
/* because span cant be animated */
display: block;
color: yellow;
font-size: 2rem;
}
.item.active {
animation: spin 1s forwards;
animation-timing-function: ease-in-out;
}
.item.in-active {
animation-direction: reverse;
}
<div>
<span class="item">ABC</span>
</div>
we can use requestAnimationFrame to reset animation and reverse it when browser paints in next frame.
Also use onmouseenter and onmouseout event handlers to reverse animation direction
As per
Any rAFs queued in your event handlers will be executed in the same
frame. Any rAFs queued in a rAF will be executed in the next frame.
function fn(el, isEnter) {
el.className = "";
requestAnimationFrame(() => {
requestAnimationFrame(() => {
el.className = isEnter? "in": "out";
});
});
}
.in{
animation: k 1s forwards;
}
.out{
animation: k 1s forwards;
animation-direction: reverse;
}
#keyframes k
{
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
<div style="width:100px; height:100px; background-color:red"
onmouseenter="fn(this, true)"
onmouseleave="fn(this, false)"
></div>
Would you be better off having just the one animation, but having it reverse?
animation-direction: reverse
Using transform in combination with transition works flawlessly for me:
.ani-grow {
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
-ms-transition: all 0.5s ease;
transition: all 0.5s ease;
}
.ani-grow:hover {
transform: scale(1.01);
}
I've put together a CodePen with a CSS-only fix and one with 2 lines of jQuery to fix the on-page load issue. Continue reading to understand the 2 solutions in a simpler version.
https://codepen.io/MateoStabio/pen/jOVvwrM
If you are searching how to do this with CSS only, Xaltar's answer is simple, straightforward, and is the correct solution. The only downside is that the animation for the mouse out will play when the page loads. This happens because to make this work, you style your element with the OUT animation and the :hover with the IN animation.
svg path{
animation: animateLogoOut 1s;
}
svg:hover path{
animation: animateLogoIn 1s;
}
#keyframes animateLogoIn {
from {stroke-dashoffset: -510px;}
to {stroke-dashoffset: 0px;}
}
#keyframes animateLogoOut {
from {stroke-dashoffset: 0px;}
to {stroke-dashoffset: -510px;}
}
Some people found this solution to be useless as it played on page load. For me, this was the perfect solution. But I made a Codepen with both solutions as I will probably need them in the near future.
If you do not want the CSS animation on page load, you will need to use a tiny little script of JS that styles the element with the OUT animation only after the element has been hovered for the first time. We will do this by adding a class of .wasHovered to the element and style the added class with the OUT Animation.
jQuery:
$("svg").mouseout(function() {
$(this).addClass("wasHovered");
});
CSS:
svg path{
}
svg.wasHovered path{
animation: animateLogoOut 1s;
}
svg:hover path{
animation: animateLogoIn 1s;
}
#keyframes animateLogoIn {
from {stroke-dashoffset: -510px;}
to {stroke-dashoffset: 0px;}
}
#keyframes animateLogoOut {
from {stroke-dashoffset: 0px;}
to {stroke-dashoffset: -510px;}
}
And voila! You can find all of this and more on my codepen showing in detail the 2 options with an SVG logo hover animation.
https://codepen.io/MateoStabio/pen/jOVvwrM
Have tried several solutions here, nothing worked flawlessly; then Searched the web a bit more, to find GSAP at https://greensock.com/ (subject to license, but it's pretty permissive); once you reference the lib ...
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>
... you can go:
var el = document.getElementById('divID');
// create a timeline for this element in paused state
var tl = new TimelineMax({paused: true});
// create your tween of the timeline in a variable
tl
.set(el,{willChange:"transform"})
.to(el, 1, {transform:"rotate(60deg)", ease:Power1.easeInOut});
// store the tween timeline in the javascript DOM node
el.animation = tl;
//create the event handler
$(el).on("mouseenter",function(){
//this.style.willChange = 'transform';
this.animation.play();
}).on("mouseleave",function(){
//this.style.willChange = 'auto';
this.animation.reverse();
});
And it will work flawlessly.
Try this:
#keyframe in {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#keyframe out {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
supported in Firefox 5+, IE 10+, Chrome, Safari 4+, Opera 12+
I am trying to implement flip animation. Here is the sample link: http://animista.net/play/basic/flip
and this is the class:
.flip-horizontal-bottom {
-webkit-animation: flip-horizontal-bottom 0.4s cubic-bezier(0.455, 0.030, 0.515, 0.955) both;
animation: flip-horizontal-bottom 0.4s cubic-bezier(0.455, 0.030, 0.515, 0.955) both;
}
/**
* ----------------------------------------
* animation flip-horizontal-bottom
* ----------------------------------------
*/
#-webkit-keyframes flip-horizontal-bottom {
0% {
-webkit-transform: rotateX(0);
transform: rotateX(0);
}
100% {
-webkit-transform: rotateX(-180deg);
transform: rotateX(-180deg);
}
}
#keyframes flip-horizontal-bottom {
0% {
-webkit-transform: rotateX(0);
transform: rotateX(0);
}
100% {
-webkit-transform: rotateX(-180deg);
transform: rotateX(-180deg);
}
}
It works fine in Chrome and Firefox but does not work at all in IE11. What changes would I require to make it work in IE 11?
From their "How to" notes:
Also, some of the animations are experimental and may not work as expected in older browsers no matter how you prefix them. Use your own judgement or better yet – consult the super-useful caniuse.com to check for browser support.
Besides, they don't provide the complete code as far as I can tell. They have a perspective:500px on their animation stage wrapper (in the demo) which makes it all work, and I don't see it mentioned anywhere in the download example code.
Even after you add it, I doubt it will work in IE, as it lacks support for transform-style:preserve-3d, as pointed out in the answers here.
I'm trying to translate an element on my webpage to the top of the page. I can get it to move x amount of pixels up, but with different screen sizes, that won't scale correctly, hence, I am looking for a more relative solution.
What I have so far is:
body {
-webkit-animation-name: raiseBody;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in;
-webkit-animation-duration: 0.7s;
}
#keyframes raiseBody {
0% {
-webkit-transform: translate(0px, 0px);
}
100% {
-webkit-transform: translate(0px, -300px);
}
but like I said before, this doesn't work on phones and such because it doesn't scale correctly. I've been stuck on this for a few hours so any and all help is appreciated!
I was looking at the webpage http://www.cuttherope.net on the current Google Chrome 38.0.x and saw that there are 4 icons in the middle of the page. When the mouse is over it, it has an icon squeezing effect: as if the icon is a pudding or jello squeezed on the side by a hand, and then bounce back to its natural size again.
I wonder how it is done: is it by HTML5 / CSS3, or how else is it done. I saw this div
<div class="game-icon resize"></div>
and if I use the developer tool to set display: none on it, then the icon will go away and have nothing showing, so this should be the div showing the effect, but if I examine the computed values, I do see an icon as a background, but all the computed values do not change when the mouse is over it or out of it. How is this done and is it part of HTML5 / CSS3's new features?
(if I disable JavaScript and reload the page, the effect still works, so apparently it is not done by JavaScript).
Yes, this is part of the CSS3 features (mainly transform )
If you want to have a similar effect without having to manually code it, have a look at this :
http://daneden.github.io/animate.css/
You can easily animate an element simply by adding two classes to it.
Found it! Yes, it's CSS3, and specifically the [-webkit-]animation: resize 0.2s linear; property. Disable that one and the effect stops.
I would guess it goes something like this:
img:hover {
-webkit-animation: squeeze 0.5s;
animation: squeeze 0.5s;
}
#-webkit-keyframes squeeze{
0% { transform: scale(1, 1); }
50% { transform: scale(1.1, 0.9); }
100% { transform: scale(1, 1); }
}
#keyframes squeeze{
0% { transform: scale(1, 1); }
50% { transform: scale(1.1, 0.9); }
100% { transform: scale(1, 1); }
}
<img src="http://placehold.it/100x100">
The CSS the other answers have pointed out
.resize:hover {
-webkit-animation: resize 0.2s linear;
animation: resize 0.2s linear;
}
References the following keyframe animation which is elsewhere in the CSS
#-webkit-keyframes resize {
0% { -webkit-transform:scale(1, 1) }
50% { -webkit-transform:scale(1.1, 0.9) }
100% { -webkit-transform:scale(1, 1) }
}
#keyframes resize {
0% { transform:scale(1, 1) }
50% { transform:scale(1.1, 0.9) }
100% { transform:scale(1, 1) }
}
The name resize is what links the two - it's not a keyword - you could call it boing and use
animation: boing 0.2s linear;
...
#keyframes boing {
Etc.
The keyframes say
at the beginning, scale to 100% x 100%
50% through the animation, scale to 110% x 90%
at the end, scale back to 100% x 100%
And the 0.2s in the animation property tells it to take 0.2 seconds to do the entire animation. The animation starts as soon as the style is applied, in this case when you hover.
Would like to know how to hide an div after a set of css3 animation. Here's my code:
#box {
position: absolute;
top: 200px;
left: 200px;
width: 200px;
height: 150px;
background-color: red;
}
#box:hover {
-webkit-animation: scaleme 1s;
}
#-webkit-keyframes scaleme {
0% {
-webkit-transform: scale(1);
opacity: 1;
}
100% {
-webkit-transform: scale(3);
opacity: 0;
display: none;
}
}
<div id='box'>
hover me
</div>
Here's the jsfiddle sample for better illustration:
http://jsfiddle.net/mochatony/Pu5Jf/18/
Any idea how to do hide the box permanently, best without javascript?
Unfortunately there is no best solution using only CSS3. Animations always return to theirs default values (see at Safari Developer Library).
But you can try to play with -webkit-animation-fill-mode property.
For example:
#box:hover{
-webkit-animation:scaleme 1s;
-webkit-animation-fill-mode: forwards;
}
It's at least not immediately return a box to display:block; state.
Using JavaScript you can do this by using webkitAnimationEnd event.
For example:
var myBox = document.getElementById('box');
myBox.addEventListener('webkitAnimationEnd',function( event ) { myBox.style.display = 'none'; }, false);
Example on jsFiddle
Change your animation definition to:
-webkit-animation:scaleme 1s forwards;
This is a value for the animation fill mode. A value of 'forwards' tells the animation to apply the property values defined in its last executing keyframe after the final iteration of the animation, until the animation style is removed.
Of course in your example the animation style will be removed when the hover is removed. At the moment I can see the need for a small piece of JavaScript to add a class which triggers the animation. Since the class would never be removed (until the page is reloaded) the div would stay hidden.
Since elements of CSS animations end in their original CSS state, make the original state hidden by scaling it to zero or removing its opacity:
div.container {
transform: scale(0);
-webkit-transform: scale(0);
}
or
div.container {
opacity: 0;
}
Once the animation is completed, the div will go back to its original CSS, which is hidden.
That can (kind of) be solved without using JavaScript. Since animations use keyframes, what you ask for is possible by setting the duration time to a way too high value, say 1000s, and letting you transition end at a low frame, for example 0.1%.
By doing this, the animation never ends and therefore stay in shape.
#box:hover {
-webkit-animation:scaleme 1000s;
}
#-webkit-keyframes scaleme {
0% { -webkit-transform: scale(1); opacity: 1; }
0.1%, 100% { -webkit-transform: scale(3); opacity: 0;display:none; }
}
1000s is not necessary in this particular example though. 10s should be enough for hover effects.
It is, however, also possible to skip the animation and use basic transitions instead.
#box2:hover {
-webkit-transition: all 1s;
-moz-transition: all 1s;
-o-transition: all 1s;
transition: all 1s;
-moz-transform: scale(3);
-webkit-transform: scale(3);
opacity: 0;
}
I forked your fiddle and altered it, adding the two for comparison: http://jsfiddle.net/madr/Ru8wu/3/
(I also added -moz- since there is no reason not to. -o- or -ms- might also be of interest).