I'm trying to make a div repeatedly appear instantly and slowly fade-out, at arbitrary intervals.
JS used to make the div appear:
div.classList.remove('fade-out');
div.offsetWidth;
div.classList.add('fade-out');
With this CSS:
.fade-out {
animation: fadeOut 2.5s ease-out;
}
#keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }
div { opacity: 0; }
For some reason, this works as expected in desktop Chrome, Safari & Firefox, but on iOS around half of the time the animation isn't played — the div just disappears after 2.5 seconds with no progressive opacity change. This happens both on both iPhone and iPad, with both Firefox and Safari.
Stuff tried since the initial post:
Add animation: none to the element's original definition.
Set the animation property through JS instead.
Use 100% and 0% instead of to and from.
Setting the div's initial opacity to 1 instead of 0 and add animation-fill-mode: forward.
Add a short delay with setTimeOut.
Use full animation definition instead of shorthand notation.
Additional definition using -webkit-animation and #-webkit-keyframes.
Using any of the above doesn't have an effect on the animation, which still works as expected everyhere except on iOS.
(Not a real) solution
The only way I could make iOS display the animation consistently was by adding a short delay to the animation:
animation: fadeOut 2.5s ease-out 0.01s
However, since the div's "instant display then fade-out" animation can be triggered while an old animation is still running on it, the delay adds a noticeable one-frame flash which is undesirable (regardless of how low I set the delay value).
Any ideas?
Related
I'm currently building a landing page with some css animations (pretty basic fade-ins). I initially set animation-play-state: "paused" in my css file, and later on access it with jQuery while scrolling the page, to trigger the animation.
Works perfectly fine on Chrome on my Mac, but trying to run it from both Safari and Chrome on my iPhone does not seems to work.
I inspected the console logs and debugged it as far as I could think, everything seems to work but the actual animation does not run (however the animation-play-state is changing to "running".
Last thing to add, if I put the $(".row").css("animation-play-state", "running"); statement before the if statement, it does exactly what it supposed to do.
My jQuery statement is:
//the position where I want the animation to trigger
var destinations = $('#destinations').offset().top - 300;
//the event listener
if($(window).scrollTop() > destinations) {
$(".row").css("-webkit-animation-play-state", "running");
$(".row").css("animation-play-state", "running");
}
Anyone knows the problem? Thanks a lot in advance!
Niv
Faced this issue today. I've was changing animation-play-state, to create nice reveal animation.
There was also animation-fill-mode: both; defined.
I used keyframes like this
#keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
And nothing seem to help in Safari. Mine tested version is 11.1.2 (13605.3.8) (Stable at this moment) and Safari Technology Preview Release 63 (Safari 12.1, WebKit 13607.1.2.1), on Macbook as well as iPhone - result is same, no animation playing.
TL.DR. You can't simply change animation-play-state in Safari. Try to change animation-name property
I was lucky to use opacity and transform to reveal elements, so this hacky temporal animation name helped me:
#keyframes be-hidden {
from { opacity: 0; }
to { opacity: 0.0000001; }
}
#keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
div {
animation-name: be-hidden;
animation-duration: 600ms;
animation-fill-mode: both;
animation-delay: 500ms;
animation-iteration-count: 1;
}
div.revealed {
animation-name: fade;
}
Set animation-name to some temp animation, which will hide elements, then change it to other (.revealed class)
If there is another way to resolve this issue, I will be happy to see it.
Possibly related: https://stackoverflow.com/a/33272708/3278855
How can I make a simple javascript animation to scroll a div (#MyDiv) from say 300px to - 300px over 15 seconds, pause for 15 seconds, then replay, and keep doing this on an endless loop?
I tried with css using multiple methods but its just not smooth enough for my needs.
My experience is that CSS3 animations are almost always more smooth than animations done by Javascript libraries.
Here's a way to do it without any Javascript, with CSS3 animations:
#scrollingContent
{
animation: scroll 30s linear 0s infinite normal;
-webkit-animation: scroll 30s linear 0s infinite normal;
}
#keyframes scroll
{
0% { top: 300px; }
50% { top: -300px; }
100% { top: -300px; }
}
#-webkit-keyframes scroll
{
0% { top: 300px; }
50% { top: -300px; }
100% { top: -300px; }
}
Working demo: http://jsfiddle.net/nj9yfk7b/
And here's an alternative way to do it with native Javascript and CSS3 transitions:
Working demo and code: http://jsfiddle.net/yfk7330j/
In this case, the transitions are triggered by Javascript by setting and un-setting a certain class name on the element that should be scrolling.
The transition version allows for better control with Javascript, while the animation version just does it's looping thing infinitely.
I tried to keep the code clean as possible, but please let me know if it needs any clarification.
Maybe the functions ScrollBy and SetInterval can help you:
http://www.w3schools.com/jsref/met_win_scrollby.asp
http://www.w3schools.com/jsref/met_win_setinterval.asp
You can use the intervals to jump every x ms y pixels, and then wait 15 seconds after you have reached an amount of pixels.
Also, I've seen this JQuery plugin, maybe it can also help (though I haven't researched it properly though):
Scrolld.js
Rememberer that people here won't write the code for you, but will happily help you pass through specific problems.
I'm trying to replicate this effect using CSS effects or transitions.
Using animations I can animate the opacity, but only fadeIn, and the height (which should control the slide) doesn't seem to work at all :(
The closest I've got is by using javascript to set a temporary class on the element I want to animate, and on which I apply the initial opacity. But height doesn't work either. And there seems to be a slight delay on animation start.
Any other ideas?
So I ended up using the solution posted in the question Simon mentioned: With javascript I wrap the element I want to animate within a "wrapper" DIV on which I apply the animation. The wrapper will get its height changed from 0 to the height of the content DIV every time the label is clicked:
fiddle here
I know it requires some javascript, but the idea is to make the animation in CSS, and this is what it does. And if JS is disabled, the toggle will still work...
You can't currently animate on height when one of the heights involved is auto, you have to set two explicit heights. There's an extensive workaround posted as an answer to this similar question.
I made an alteration to your JS Fiddle, I beleive this is what you want; please see it here.
You need to specify a height on the div originally (0) and don't forget overflow:hidden; so that the content doesn't 'spil out' of the div. You will still need jQuery / Javascript however, to toggle a class but it means much less Javascript is required. (I toggled the class "change" which you will see on that fiddle)
input {
display:none;
}
label {
display:inline-block;
}
div {
white-space: pre;
background: #eee;
color: #333;
overflow:hidden;
height:0;
opacity:0;
-moz-transition:height 1s opacity 1s;
-webkit-transition:height 1s opacity 1s;
-o-transition:height 1s opacity 1s;
-ms-transition:height 1s opacity 1s;
transition:height 1s, opacity 1s;
}
.changed {
height:200px;
opacity: 1;
}
I added a few vendor prefixes to the transition CSS propery as I'm not sure what browser you'll be using and I'm on firefox so I need the -moz- prefix lol :)
The only problem I can see with this is that height:auto or height:100% doesn't animate, so you'll need to specify ems or px... If this is going to be a problem (like if the content will be dynamic), I would advise using jQuery for the height animation.
I have a DIV class setup as follows:
div.map_view{
height: 420px;
transition: height 2s;
-moz-transition: height 2s; /* Firefox 4 */
-webkit-transition: height 2s; /* Safari and Chrome */
-o-transition: height 2s; /* Opera */
}
The purpose is when I change the height of this DIV, it animates a scroll (up in this case). When I call this function in my script:
document.getElementById('map_view').style.height = '0px';, it just immediately disappears (doesn't animate). However, if I comment this out and call the exact same line in my JS debugger, the animation works.
Why is this? What am I missing that causes it to do nothing in my script?
I know I've cut a couple of corners with this by using jquery but here's what I got:
http://jsfiddle.net/qZ6J4/7/
Take a look at that.
I actually found a helpful tutorial here: CSS3 Transitions in JavaScript. I basically setup my two CSS3 class definitions and use jQuery's .toggleClass() function to change between the two.
I am currently writing a jQuery plugin to create / manage CSS transitions, and I found this strange behavior with transition-duration.
Apparently, while a transition is running, any changes to the duration property are ignored unless the properties being transitioned receive a different value. The duration itself does not cause the transition to change.
Following is some code which shows an example of this, and below are some links to jsFiddle to give you a better idea of the transition behavior I am trying to achieve.
/* starting transition */
.t1 {
-webkit-transition-duration: 5s;
-webkit-transition-property: width;
width: 500px;
}
/* during the above, this will do nothing */
.t2 {
-webkit-transition-duration: 200ms;
-webkit-transition-property: width;
width: 500px;
}
/* but this will override the transition as expected */
.t3 {
-webkit-transition-duration: 200ms;
-webkit-transition-property: width;
width: 501px; /* 1 pixel added */
}
jsFiddle 1 - CSS duration problem: http://jsfiddle.net/danro/Kd58j/
jsFiddle 2 - Desired effect w/ jQuery: http://jsfiddle.net/danro/xPwc4/
Any ideas on how to force the transition to accept the updated duration?
UPDATE
It looks like this behavior is defined in the spec, but I am still open to a workaround if anyone has one.
(From www.w3.org/TR/css3-transitions/#starting)
Once the transition of a property has started, it must continue running based on the original timing function, duration, and delay, even if the ‘transition-timing-function’, ‘transition-duration’, or ‘transition-delay’ property changes before the transition is complete.
I've run into the same issue when I needed to overwrite transition-duration but leaving the transition-property intact. The only simple workaround I've found so far is to actually change transition-property a little bit, i.e. instead of opacity: 0 make it opacity: 0.0001.
just tested your first link with Chrome and Safari and it works fine, just like the jQuery example :)