Elements with Animation Delay Briefly Appear Before Fading in Using Purely CSS3 Keyframes (No Js)

Elements with animation delay briefly appear before fading in using purely CSS3 Keyframes (no JS)

While the option suggested by Vito is not wrong, it is better to actually achieve this using properties or settings that are specifically designed for this purpose.

The element is visible at start because during the animation's delay period, the properties specified in the @keyframe rules will not have any effect on the element. The element would continue to be in the state that is mentioned outside of the @keyframes. Here there is no opacity specified outside of the @keyframe rules and so the default value of 1 is used and the element becomes visible.

Below is what the CSS specs for Animations say about this:

Furthermore, typically an animation does not affect the computed value before the animation delay has expired or after the end of the animation, but may do so depending on the animation-fill-mode property.

Once the animation starts (that is, the delay expires), the element will get the properties specified with in the @keyframes rules applied to it (depending on the animation's progress from 0 - 100). So, its first invisible then becomes visible as it slides in.

The way to force the browser to apply the properties specified within the @keyframes rules during the delay period is to use animation-fill-mode as backwards. But in your case, the animation fill mode is already set as forwards and hence you should change it to both. A value of both means that it will respect the specifications of both forwards (that is, hold the state as at last keyframe once the animation is completed) and also of backwards (that is, hold the state as at its first keyframe when it's in the delay period).

Below is an extract from the MDN page on animation-fill-mode property:

backwards

The animation will apply the values defined in the first relevant keyframe as soon as it is applied to the target, and retain this during the animation-delay period. The first relevant keyframe depends on the value of animation-direction:

both

The animation will follow the rules for both forwards and backwards, thus extending the animation properties in both directions.

In short, the below is what you need to do. Note, the change that I've made at the end of animation property's value. I've left out the other properties for brevity, they are present in the demo.

.header-banner h2 {
/* other props removed for brevity */
animation: slide-in 1s 0.2s both;
}

.header-banner a {
animation: slide-in 1s 0.4s both;
}

@charset "UTF-8";
/* CSS Document */

/***************************************************************
GENERAL
***************************************************************/
* { font-family: 'Varela', sans-serif;}
body { padding: 0; margin: 0; background-color: rgb(90, 120, 240);}
a { text-decoration: none; color: inherit; font-size: inherit;}

/***************************************************************
HEADER
***************************************************************/

/***************************** BANNER*****************************/
.header-banner { display: flex; flex-direction: column; justify-content: space-between; align-items: center; margin-top: 30px; height: 250px; -webkit-animation: slide-in 1s; -moz-animation: slide-in 1s; -o-animation: slide-in 1s; animation: slide-in 1s;}
.header-banner h1,.header-banner h2,.header-banner a { font-family: 'Varela', sans-serif; color: white; text-align: center; padding: 0 40px; margin: 10px 0;}
.header-banner h2,.header-banner a { font-weight: normal;}
.header-banner h1 { font-size: 3em; -webkit-animation: slide-in 1s; -moz-animation: slide-in 1s; -o-animation: slide-in 1s; animation: slide-in 1s;}
.header-banner h2 { font-size: 1.5em; -webkit-animation: slide-in 1s 0.2s both; -moz-animation: slide-in 1s 0.2s both; -o-animation: slide-in 1s 0.2s both; animation: slide-in 1s 0.2s both;}
.header-banner a { font-size: 1.1em; font-weight: bolder; padding: 15px 40px; border-radius: 5px; letter-spacing: 0.05em; background-color: rgb(0, 221, 221); box-shadow: 0 4px 6px rgba(50, 50, 93, .11), 0 1px 3px rgba(0, 0, 0, .08); transition: 0.3s ease-in-out; margin-top: 60px; -webkit-animation: slide-in 1s 0.4s both; -moz-animation: slide-in 1s 0.4s both; -o-animation: slide-in 1s 0.4s both; animation: slide-in 1s 0.4s both;}
.header-banner a:hover { transition: 0.3s ease-in-out; box-shadow: 0 6px 10px rgba(50, 50, 93, .16), 0 2px 10px rgba(0, 0, 0, .1); transform: translateY(-2px);}

/***************************************************************
KEYFRAMES
***************************************************************/
@-o-keyframes slide-in { 0% { transform: translateY(40px); opacity: 0; } 100% { transform: translateY(0px); opacity: 1; }}
@-moz-keyframes slide-in { 0% { transform: translateY(40px); opacity: 0; } 100% { transform: translateY(0px); opacity: 1; }}
@-webkit-keyframes slide-in { 0% { transform: translateY(40px); opacity: 0; } 100% { transform: translateY(0px); opacity: 1; }}
@keyframes slide-in { 0% { transform: translateY(40px); opacity: 0; } 100% { transform: translateY(0px); opacity: 1; }}
<!doctype html><link href="https://fonts.googleapis.com/css?family=Varela" rel="stylesheet"
<header> <div class="header-banner"> <h1><h1> element (no delay)</h1> <h2>I'm an <h2> element with 0.2s of delay</h2> <a href="about.html">I'm an <a> element with 0.4s of delay</a> </div> </header>

Animation delay on page load

We need to give the .image class opacity: 0 so it loads hidden. Then, delay the animation:

animation: fadeinLoad 1s 5s forwards;

The second time of 5s specifies a wait to activate time of 5 seconds. The forwards property pauses the animation at 100%.

The shorthand above is the same as this:

animation-name: fadeinLoad; 
animation-duration: 1s;
animation-delay: 5s;
animation-fill-mode: forwards;

Read more on CSS animation over on the MDN.

Example

Count to five :)

.image {
animation: fadeinLoad 1s 5s forwards;
opacity: 0;
}

@keyframes fadeinLoad {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<h1>Count to 5!</h1>

<img class="image" src="https://i.stack.imgur.com/od9bJ.png" />

How to prevent a CSS keyframe animation from running on page load?

Solution 1 - Add down animation on first hover

Probably the best option is to not put the down animation on until the user has hovered over the container for the first time.

This involves listening to the mouseover event then adding a class with the animation at that point, and removing the event listener. The main (potential) downside of this is it relies on Javascript.

;(function(){    var c = document.getElementById('container');    function addAnim() {        c.classList.add('animated')        // remove the listener, no longer needed        c.removeEventListener('mouseover', addAnim);    };
// listen to mouseover for the container c.addEventListener('mouseover', addAnim);})();
#container {    position:relative;    width:100px;    height:100px;    border-style:inset;}#content {    position:absolute;    top:100px;    width:100%;    height:100%;    background-color:lightgreen;    opacity:0;}
/* This gets added on first mouseover */#container.animated #content { -webkit-animation:animDown 1s ease;}
#container:hover #content { -webkit-animation:animUp 1s ease; animation-fill-mode:forwards; -webkit-animation-fill-mode:forwards;}
@-webkit-keyframes animUp { 0% { -webkit-transform:translateY(0); opacity:0; } 100% { -webkit-transform:translateY(-100%); opacity:1; }}@-webkit-keyframes animDown { 0% { -webkit-transform:translateY(-100%); opacity:1; } 100% { -webkit-transform:translateY(0); opacity:0; }}
<div id="container">    <div id="content"></div></div>

amination with opacity problam

You can add the following under your declarations:

.defult-text { 

opacity: 0; /* applies for the time before the animation starts */
animation-fill-mode: forwards; /* keeps the state after the animation has finsished */
}

Please see: Maintaining the final state at end of a CSS3 animation

CSS slide page up animation- element briefly shows before the animation

Solution:

The correct solution to this issue is to set animation-fill-mode as backwards (or use the shorthand like below):

animation: slide-up .6s cubic-bezier(0.4, 0, 0.2, 1) 500ms backwards;

Reasoning:

When delay is added to any animation, its execution is put on hold till that time has elapsed and during this time, the element holds whatever position was assigned to it initially. For it to start at the translated position, you either have to manually add the setting to the element (or) tell the UA to do it for you.

When we set the animation-fill-mode as backwards, the UA automatically sets the property value defined for the first frame of the animation's first iteration as the properties during the delay period and thus it will start at the translated position for your case.

Here's what the W3C Spec says about animation-fill-mode: backwards

During the period defined by animation-delay, the animation will apply the property values defined in the keyframe that will start the first iteration of the animation. These are either the values of the from keyframe (when animation-direction is normal or alternate) or those of the to keyframe (when animation-direction is reverse or alternate-reverse).

Alternate Solution:

You can of-course solve this by adding a transform: translateY(100%) to the element originally also but that makes less sense when there is a specific property to achieve it.

(I assume that the element did not have transform: translateY(100%) initially in your code.)

Why using opacity may not always be acceptable solution?

Solution by using opacity (as you have done in your own answer) is not wrong but you would notice that the opacity also gets animated from 0 to 1 over the course of the animation which means that the content slowly fades into view as opposed to just a slide up action. While, this can also be fixed by adding extra keyframes in between, those are just work-arounds for something that could have been achieved by using a single property.

Sample for all solutions:

In the below snippet, I have added samples for the version with the problem and all possible fixes.

.slide-up-now {  animation: slide-up .6s cubic-bezier(0.4, 0, 0.2, 1) 500ms;}.slide-up-now-fixed { /* preferred method */  animation: slide-up .6s cubic-bezier(0.4, 0, 0.2, 1) 500ms backwards;}.slide-up-now-fixed-initial-prop {  transform: translateY(100%);  animation: slide-up .6s cubic-bezier(0.4, 0, 0.2, 1) 500ms forwards;}.slide-up-now-opacity {  opacity: 0;  animation: slide-up-opacity .6s cubic-bezier(0.4, 0, 0.2, 1) 500ms forwards;}
@keyframes slide-up { 0% { transform: translateY(100%); } 100% { transform: translateY(0); }}
@keyframes slide-up-opacity { 0% { transform: translateY(100%); opacity: 0; } 100% { transform: translateY(0); opacity: 1; }}
/* Just for demo */
div{ display: inline-block; height: 100px; margin: 10px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script><div class='slide-up-now'>Slide Up Now</div><div class='slide-up-now-fixed'>Fixed by Fill Mode</div><div class='slide-up-now-fixed-initial-prop'>Fixed by Initial Setting</div><div class='slide-up-now-opacity'>Fixed by Opacity</div>

Animate block back and forth within div continuously with CSS3 keyframes

CSS Solution

you can play around the left position when the animation is at 50% like so :

because when you put it left: 100% it depend on the left corner of the span this is why it will go out the container div

@-webkit-keyframes backandforth {0%{left:0;} 50%{left:58%;} 100%{left:0;}}

Live Demo

I hope this fits your needs

JavaScript solution

var thisis = document.getElementById("wrapper");
var tyty = document.getElementById("move");
var witth = tyty.offsetWidth;

thisis.style.paddingRight = witth +"px";

Live Demo

with this JS whatever you change the text it will still in the container div

CSS Keyframe animation: Hiding element before animation starts

You are close. An easy way is to just add animation-fill-mode: forwards; which will persist the last keyframe and in this case keep the div visible.

Here's an updated version of your Fiddle where the animation starts after 4s (as you specified) and keeps the div visible instead of jumping back to it's original state (opacity: 0;).

Hope that helps!



Related Topics



Leave a reply



Submit