CSS animation with delay and opacity
Asked Answered
P

7

31

I am trying to fade in an element after 2 sec using CSS animation. The code works great in new browsers, but in old browsers the element will stay hidden because of "opacity:0".

I want it to be visible in old browsers and I don't want to involve javascript. Can it be solved using CSS? Eg. some how target browsers that doesn't support animation?

CSS:

#element{
animation:1s ease 2s normal forwards 1 fadein;
-webkit-animation:1s ease 2s normal forwards 1 fadein;
opacity:0
}

@keyframes fadein{from{opacity:0}
to{opacity:1}
}

@-webkit-keyframes fadein{from{opacity:0}
to{opacity:1}
}

HTML:

<div id=element>som content</div>
Pruinose answered 24/4, 2015 at 11:24 Comment(0)
P
78

Just don't set the initial opacity on the element itself, set it within the @keyframes:

#element{
    -webkit-animation: 3s ease 0s normal forwards 1 fadein;
    animation: 3s ease 0s normal forwards 1 fadein;
}

@keyframes fadein{
    0% { opacity:0; }
    66% { opacity:0; }
    100% { opacity:1; }
}

@-webkit-keyframes fadein{
    0% { opacity:0; }
    66% { opacity:0; }
    100% { opacity:1; }
}

This technique takes the delay off of the animation, so that it starts running immediately. However, the opacity won't really change until about 66% into the animation. Because the animation runs for 3 seconds, it gives the effect of a delay for 2 seconds and fade in for 1 second.

See working example here: https://jsfiddle.net/75mhnaLt/

You might also want to look at using conditional comments for older browsers; IE8 and IE9.

Something like the following in your HTML:

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en-GB"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8 ie-7" lang="en-GB"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9 ie-8" lang="en-GB"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en-GB"> <!--<![endif]-->

You could then do something like:

.lt-ie9 #element {
    opacity: 1;
}
Protasis answered 24/4, 2015 at 11:48 Comment(2)
Remove opacity: 0 like @Michael Giovanni Pumo stated, however instead of time-stretching to merge the delay into the timeline, just apply animation-fill-mode: backwards to apply the delay to the first keyframe (aka the 'from' state). Note: If your ending keyframe does something unique within the animation, then you will want to use animation-fill-mode: both. jsfiddle.net/m3z2htLeTetragrammaton
With this approach animation easing effect won't be the same as intended, would it?Angelitaangell
S
9

I had a similar problem, where the requirement was to wait n seconds before fading in different page elements, one after another.

The key to getting this working for me, that isn't mentioned in any of the other answers, is the fact that animation can actually take a list of animations to run. It will start running them simultaneously so you need to insert delays in order to run them sequentially.

My solution was this (in SCSS, but simple enough to write as straight CSS if you need):

@mixin fade-in($waitTime) {
    animation: 
        wait #{$waitTime},
        fade-in 800ms #{$waitTime};
}

@keyframes wait {
    0% { opacity: 0; }
    100% { opacity: 0; }
}

@keyframes fade-in {
    0% { opacity: 0; }
    100% { opacity: 1; }
}

Usage:

h1 {
    @include fade-in('500ms');
}
h2 {
    @include fade-in('700ms');
}
Softboiled answered 2/1, 2020 at 20:11 Comment(0)
B
3

I'd suggest that you set the opacity of the element to 1 per default (for browsers that do not support animations). Then start the animation at 0s and use the keyframes to delay the animation.

#element{
animation:3s ease 0s normal forwards 1 fadein;
-webkit-animation:3s ease 0s normal forwards 1 fadein;
opacity:1
}

@keyframes fadein{
    0%{opacity:0}
    80%{opacity:0}
    100%{opacity:1}
}

@-webkit-keyframes fadein{
    0%{opacity:0}
    80%{opacity:0}
    100%{opacity:1}
}

http://jsfiddle.net/mg00t86v/2/

Bilbe answered 24/4, 2015 at 11:35 Comment(0)
S
1

Since all the major browsers support CSS3 animations with the notable exception of IE<10 you could use conditional comments into your HTML like so

<!DOCTYPE html>
<!--[if lte IE 9]><html class="lte-ie9"><![endif]-->
<!--[if (gt IE 9)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html><!--<![endif]-->

thus you can add a more specific rule for IE<10 using the .lte-ie9 classname in a specific selector

.lte-ie9 #element {
   opacity: 1;
   filter : alpha(opacity=100);
}

I would not move instead the opacity: 0 inside the first keyframe as a primary suggestion, since this would limit all the animations to have an animation-delay equal to 0 (or otherwise you could see a kind of fouc for the element itself)

Sanmicheli answered 24/4, 2015 at 11:32 Comment(0)
C
0

you can try this might be help you.

HTML

<div>some text</div>

CSS

div{
-webkit-animation: fadein 5s linear 1 normal forwards;
 }

@-webkit-keyframes fadein{
from{
   opacity: 0;
}
to{
    opacity: 1;
}
}
Catawba answered 24/4, 2015 at 11:31 Comment(0)
U
0

This waits 3 seconds and then slides in from left:

EVEN SHORTER:

.myclass {animation: 4s slidein;}

@keyframes slidein {
0% {opacity:0;
    transform: translateX(-100%);}
92% {opacity:0;
    transform: translateX(-100%);}
100% {opacity:1;
    transform: translateX 0;}
}
Unicorn answered 19/2, 2022 at 15:34 Comment(0)
L
0

The cleanest way is to use animation-delay css property for delay:

.delayed-fadeout {
  animation: 1s forwards fadeout;
  animation-delay: 2s;
}
@keyframes fadeout {
  0% { opacity: 1; }
  100% { opacity: 0; }
}

Beware – animation-delay should go after animation since animation shorthand overwrites it.

Leonleona answered 2/9, 2023 at 11:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.