Is this a bug? On safari and chrome -webkit-animation-name doesn't seem to override properly. The following CSS should cause a ghastly flashing effect on the h1 tag called title but the animation fails to run;
#-webkit-keyframes flash2 {
0% { background-color: red; }
100% { background-color: blue; }
}
#-ms-keyframes flash2 {
0% { background-color: red; }
100% { background-color: blue; }
}
h1 {
/* this breaks the animation on chrome,safari */
-webkit-animation-name: none;
-ms-animation-name: none;
}
h1#title {
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-name: flash2;
-ms-animation-duration: 2s;
-ms-animation-iteration-count: infinite;
-ms-animation-name: flash2;
}
http://jsfiddle.net/DQ96d/5/
Is this a bug?
Either way, I wanted to document what I've discovered since it cost me a lot of time to resolve. The main reason I couldn't see this at first was because the inspector in chrome (F12) indicated that the css selectors had properly prioritised and -webkit-animation-name was indeed showing flash2. HOWEVER - the animation fails to run.
Hopefully this may help someone else. The workaround would seem to be that you can't have that property in more than one CSS selector. Curiously, if you list it twice in one rule it doesn't break.
Instead of 'none' try giving the h1 a dummy name, like:
-webkit-animation-name: test;
Seems to work ok like this.
Related
I am facing a challenge to make a dynamic 'hinting' system. I would like to make an element blink using only CSS. Not sure if it even possible. Normally you should define the begin and end color of your animation (update: This is not true.), but because I would like to let it work on multiple background colours this isn't an option.
I have tried a number of options and Google queries (inherit, currentColor etc.) but all it does is go from white/transparent to #ef9633.
Anyone got some options I could try?
Code:
#keyframes nk-hint {
0% { background-color: #XXX; }
50% { background-color: #ef9633; }
100% { background-color: #XXX; }
}
#-webkit-keyframes nk-hint {
0% { background-color: #XXX; }
50% { background-color: #ef9633; }
100% { background-color: #XXX; }
}
Thanks allot already!
The answer was simpler than I thought. You can just remove the 0% and 100% and it works fine on all major browser. Still need to test this on iOS and IE.
It's safe to say you don't need to set a begin and/or end colour.
#keyframes nk-hint {
50% { background-color: #ef9633; }
}
#-webkit-keyframes nk-hint {
50% { background-color: #ef9633; }
}
animation-fill-mode can do what you want, unless you need to support IE < 9. http://www.w3schools.com/cssref/css3_pr_animation-fill-mode.asp
If you need IE 9 support, then I believe you're stuck with Javascript for the animation unfortunately.
Ok then, you could make the changes as shown below.
.your-selector {
background-color: red;
-webkit-animation: nk-hint 3s; /* Chrome, Safari, Opera */
-webkit-animation-iteration-count: 1; /* Chrome, Safari, Opera */
-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
animation: nk-hint 3s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
#-webkit-keyframes nk-hint {
0% {background-color: #XXX;}
50% {background-color: #ef9633;}
100% {background-color: #XXX;}
}
#keyframes nk-hint {
0% {background-color: #XXX;}
50% {background-color: #ef9633;}
100% {background-color: #XXX;}
}
The keyframes will remain the same.
Goal:
Achieve animation that
apply initial style
on adding some class it plays forwards and keeps resulting styles
on removing trigger class it plays backwards and returns to initial state
What i got:
#keyframes translate {
0% {
transform: translate3d(-100%,0,0);
}
100% {
transform: translate3d(0,0,0);
}
}
.element {
animation-direction: reverse;
animation-duration: 0.35s;
animation-fill-mode: both;
animation-name: translate;
animation-play-state: running;
animation-timing-function: ease-in-out;
}
.element.is-animated {
animation-direction: normal;
}
Result:
It works as described above, (keeps style as required) except the lack of smooth animation. Just switches styles instantly. I guess there are some rules overlapping.
Does anybody made the same? I haven't find any proper tutorial for this particular issue
If you are going to switch between only this two transform properties. Use transition instead of animation.
.element {
transition:transform .2s ease;
width:30px;
height:30px;
border:1px solid red;
transform: translate3d(0,0,0);
}
.element.is-animated {
transform: translate3d(-100%,0,0);
}
Precisely you should add remove the class is-animated, whenever you want the transition to take place
I'm trying to delay the trigger of a CSS animation (not slow down the animation itself, but delay it a few seconds before starting). And the image should not display before the animation runs. I looked through the other questions, and they don't seem to address this.
MY FIDDLE: http://jsfiddle.net/omarel/guh5f8bs/
CSS
.slideRight{
animation-name: slideRight;
-webkit-animation-name: slideRight;
animation-duration: 1s;
-webkit-animation-duration: 1s;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
visibility: visible !important;
}
#keyframes slideRight {
0% {
transform: translateX(-150%);
}
100% {
transform: translateX(0%);
}
}
#-webkit-keyframes slideRight {
0% {
-webkit-transform: translateX(-150%);
}
100% {
-webkit-transform: translateX(0%);
}
}
HTML
<div class="slideRight">
HI
</div>
Side note: Also is there a way to get it to work with an <a> tag? Animations don't seem to play nice with this:
<a class="slideRight">
HI
</a>
Delaying the start of the animation is very simple. Simply add the animation-delay property to your code:
.slideRight{
animation-name: slideRight;
animation-duration: 1s;
animation-timing-function: ease-in-out;
visibility: visible !important;
/* New code here: */
animation-delay: 1s;
}
It's important to note that animation-delay only delays the start of the animation from the beginning. If you have a repeating animation, it won't add the delay to the same spot of each loop; only to the very beginning. There's currently no CSS property capable of that kind of looped delay.
All major browsers currently support animation-delay without the need for vendor prefixes.
As for your second question regarding the <a> element: Yes, it can work. The reason it's not working for you now is because <a> elements are inline elements. In order to make it work like you're expecting, add display: inline-block; to the .slideRight{} selector. Ultimately this is what your code will look like:
.slideRight{
animation-name: slideRight;
animation-duration: 1s;
animation-timing-function: ease-in-out;
visibility: visible !important;
/* New code here: */
animation-delay: 1s;
display: inline-block;
}
#keyframes slideRight {
0% {
transform: translateX(-150%);
}
100% {
transform: translateX(0%);
}
}
<a class="slideRight">HI</a>
JSFiddle Example
Add a settimeout function
Hi there, you could add an event listen that get when you mouseover the certain element and then calls the function after 1 second.
$('slideRight').on('mouseover',function(){
window.setTimeout(function(){
$this.addClass('onesecond');
}, 1000); //<-- Delay in milliseconds
});
div {
-webkit-animation-delay: 2s; /* Safari 4.0 - 8.0 */
animation-delay: 2s;
}
Source:
https://www.w3schools.com/cssref/css3_pr_animation-delay.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay
Should style changes specified on a pseudo state such as :hover work after a CSS animation has completed running on the element?
EDIT: Perhaps more pertinently, I should ask: why does applying 'forwards' on an animation prevent a more specific style change from overriding?
EDIT 2: Turns out that this is actually a cross browser issue. E.g. Chrome (I was running Version 38.0.2125.111) behaves incorrectly but Firefox handles it as per the specs.
Long story short: According to the specs (as quoted by chrona below) adding !important to the override should render the style. However, at present, only Firefox handles this correctly.
Here is a reduction:
#keyframes go {
0% {
background: green;
}
100% {
background: pink;
}
}
#-webkit-keyframes go {
0% {
background: green;
}
100% {
background: pink;
}
}
.box {
animation: go 3s forwards;
-webkit-animation: go 3s forwards;
}
.box:hover {
background: orange!important;
cursor: pointer;
}
<div class="box">Hover states don't work after animation</div>
I am unable to find information relating to this, nothing in the spec either: http://www.w3.org/TR/css3-animations/
Anybody know if a) this should be possible? b) how to make hover states work on an element once the animation ends?
a)
About why does it happen, I can't state for sure. But it obviously is related to the animation-fill-mode property that you're setting to be forwards. That, by definition, sets the visual style of the element to be the last keyframe of the animation:
forwards
After the animation ends (as determined by its animation-iteration-count), the animation will apply the property values for the time the animation ended.
MDN's definition is a bit more clear:
forwards
The target will retain the computed values set by the last keyframe encountered during execution. The last keyframe encountered depends on the value of animation-direction and animation-iteration-count:
But I don't know why does it not allow the :hover state to override the styles.
b)
Now, about how to make it work, you could remove the forwards property from the animation. In this case, you'd need to reverse the animation, so the original state of the element (when the animation ends, and removes the visual effect), is the color that you want it to be fixed:
#keyframes go {
0% {
background: pink;
}
100% {
background: green;
}
}
#-webkit-keyframes go {
0% {
background: pink;
}
100% {
background: green;
}
}
.box {
animation: go 2s;
-webkit-animation: go 2s;
-webkit-animation-direction: reverse;
animation-direction: reverse;
background: pink;
}
.box:hover {
background: orange;
cursor: pointer;
}
<div class="box">Hover states don't work after animation</div>
Quoted from the CSS Animations Working Draft
CSS Animations affect computed property values. During the execution of an animation, the computed value for a property is controlled by the animation. This overrides the value specified in the normal styling system. Animations override all normal rules, but are overriden by !important rules.
and a bit further down (Animation Duration):
[…] and an animation that fills forwards will retain the value specified at the 100% keyframe, even if the animation was instantaneous. Also, animation events are still fired.
As you are animating the background it cannot be overriden by default (except for !important rules). If you don't want to use !important you should go by LcSalazar's answer. (Currently only Firefox reacts as described in the specs [6th Nov 2014])
#keyframes go {
0% {
background: green;
}
100% {
background: pink;
}
}
#-webkit-keyframes go {
0% {
background: green;
}
100% {
background: pink;
}
}
.box {
animation: go 3s forwards;
-webkit-animation: go 3s forwards;
}
.box:hover {
background: orange !important;
cursor: pointer;
}
<div class="box">Hover states don't work after animation</div>
Actually I don't really understand your question, may be you need the effects like this? http://jsfiddle.net/abruzzi/5td8w6jx/
#keyframes go {
0% {
background: green;
}
100% {
background: pink;
}
}
#-webkit-keyframes go {
0% {
background: green;
}
100% {
background: pink;
}
}
.box {
animation: go 3s forwards;
-webkit-animation: go 3s forwards;
}
.box:hover {
-webkit-animation: none;
background: orange;
cursor: pointer;
}
However, with these codes, when you mouseout the text, the animation will be replay.
http://jsfiddle.net/nicktheandroid/vX7CV/10/
This is a simple example, but for what I need this for, transition will not work, animation needs to be used.
When hovering the element, the animation smoothly animates the element, when hovering off of the element it snaps back to it's original settings without smoothly animating back.
Is there a way to cause it to animate back to it's settings instead of snapping back like it is?
Animate needs to be used for the :hover event, but when hovering off the element, I could use transition, if this would work, I can't get it to work though.
I have tested you version in Google Chrome and it worked fine for me.
Also added in the Firefox compatibility and that also worked fine for me.
Here is what I have now:
HTML:
<ul>
</li>test</li>
</ul>
CSS:
ul {
background-color:black;
color:white;
width: 100px;
height:100px;
}
#-moz-keyframes flow-down {
0% {
padding-bottom: 0%;
}
100% {
padding-bottom: 30%;
}
}
#-webkit-keyframes flow-down {
0% {
padding-bottom: 0%;
}
100% {
padding-bottom: 30%;
}
}
ul:hover {
-moz-animation-name: flow-down;
-moz-animation-duration: 0.5s;
-moz-animation-timing-function: ease-in-out;
-moz-animation-fill-mode:forwards;
-webkit-animation-name: flow-down;
-webkit-animation-duration: 0.5s;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-fill-mode:forwards;
}
And here is the JSFiddle version just incase:
http://jsfiddle.net/NQ5xk/1/
Hope this helps.
Regards
in firefox, if you have change 'position' or 'z-index' attr during the animation, animation will not run