I have a CSS Animation for a div that slides in after a set amount of time. What I would like is for a few divs to fill the space of the animated div that slides in, which it will then push those elements down the page.
When I attempt this at first div that slides in still takes up space even when it is not visible. If I change the div to display:none the div doesn't slide in at all.
How do I have a div not take up space until it is timed to come in (using CSS for the timing.)
I am using Animate.css for the animations.
Here is what the code looks like:
<div id="main-div" class="animated fadeInDownBig"><!-- Content --></div>
<div id="div1"><!-- Content --></div>
<div id="div2"><!-- Content --></div>
<div id="div3"><!-- Content --></div>
As the code shows I would like the main div to be hidden and the other divs show at first. Then I have the following delay set:
#main-div{
-moz-animation-delay: 3.5s;
-webkit-animation-delay: 3.5s;
-o-animation-delay: 3.5s;
animation-delay: 3.5s;
}
It is at that point that I would like the main div to push the other divs down as it comes in.
How do I do this?
Note: I have considered using jQuery to do this, however I prefer using strictly CSS as it is smoother and the timing is a bit better controlled.
EDIT
I have attempted what Duopixel suggested but either I mis-understood and am not doing this correctly or it doesn't work. Here is the code:
HTML
<div id="main-div" class="animated fadeInDownBig"><!-- Content --></div>
CSS
#main-image{
height: 0;
overflow: hidden;
-moz-animation-delay: 3.5s;
-webkit-animation-delay: 3.5s;
-o-animation-delay: 3.5s;
animation-delay: 3.5s;
}
#main-image.fadeInDownBig{
height: 375px;
}
CSS (or jQuery, for that matter) can't animate between display: none; and display: block;. Worse yet: it can't animate between height: 0 and height: auto. So you need to hard code the height (if you can't hard code the values then you need to use javascript, but this is an entirely different question);
#main-image{
height: 0;
overflow: hidden;
background: red;
-prefix-animation: slide 1s ease 3.5s forwards;
}
#-prefix-keyframes slide {
from {height: 0;}
to {height: 300px;}
}
You mention that you're using Animate.css, which I'm not familiar with, so this is a vanilla CSS.
You can see a demo here: http://jsfiddle.net/duopixel/qD5XX/
There are a few answers already, but here is my solution:
I use opacity: 0 and visibility: hidden. To make sure that visibility is set before the animation, we have to set the right delays.
I use http://lesshat.com to simplify the demo, for use without this just add the browser prefixes.
(e.g. -webkit-transition-duration: 0, 200ms;)
.fadeInOut {
.transition-duration(0, 200ms);
.transition-property(visibility, opacity);
.transition-delay(0);
&.hidden {
visibility: hidden;
.opacity(0);
.transition-duration(200ms, 0);
.transition-property(opacity, visibility);
.transition-delay(0, 200ms);
}
}
So as soon as you add the class hidden to your element, it will fade out.
I had the same problem, because as soon as display: x; is in animation, it won't animate.
I ended up in creating custom keyframes, first changing the display value then the other values. May give a better solution.
Or, instead of using display: none; use position: absolute; visibility: hidden; It should work.
You can manage to have a pure CSS implementation with max-height
#main-image{
max-height: 0;
overflow: hidden;
background: red;
-prefix-animation: slide 1s ease 3.5s forwards;
}
#keyframes slide {
from {max-height: 0;}
to {max-height: 500px;}
}
You might have to also set padding, margin and border to 0, or simply padding-top, padding-bottom, margin-top and margin-bottom.
I updated the demo of Duopixel here : http://jsfiddle.net/qD5XX/231/
The following will get you to animate an element when
Giving it a Display - None
Giving it a Display - Block
CSS
.MyClass {
opacity: 0;
display:none;
transition: opacity 0.5s linear;
-webkit-transition: opacity 0.5s linear;
-moz-transition: opacity 0.5s linear;
-o-transition: opacity 0.5s linear;
-ms-transition: opacity 0.5s linear;
}
JavaScript
function GetThisHidden(){
$(".MyClass").css("opacity", "0").on('transitionend webkitTransitionEnd oTransitionEnd otransitionend', HideTheElementAfterAnimation);
}
function GetThisDisplayed(){
$(".MyClass").css("display", "block").css("opacity", "1").unbind("transitionend webkitTransitionEnd oTransitionEnd otransitionend");
}
function HideTheElementAfterAnimation(){
$(".MyClass").css("display", "none");
}
When animating height (from 0 to auto), using transform: scaleY(0); is another useful approach to hide the element, instead of display: none;:
.section {
overflow: hidden;
transition: transform 0.3s ease-out;
height: auto;
transform: scaleY(1);
transform-origin: top;
&.hidden {
transform: scaleY(0);
}
}
How do I have a div not take up space until it is timed to come in (using CSS for the timing.)
Here is my solution to the same problem.
Moreover I have an onclick on the last frame loading another slideshow, and it must not be clickable until the last frame is visible.
Basically my solution is to keep the div 1 pixel high using a scale(0.001), zooming it when I need it. If you don't like the zoom effect you can restore the opacity to 1 after zooming the slide.
#Slide_TheEnd {
-webkit-animation-delay: 240s;
animation-delay: 240s;
-moz-animation-timing-function: linear;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-moz-animation-duration: 20s;
-webkit-animation-duration: 20s;
animation-duration: 20s;
-moz-animation-name: Slide_TheEnd;
-webkit-animation-name: Slide_TheEnd;
animation-name: Slide_TheEnd;
-moz-animation-iteration-count: 1;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
-moz-animation-direction: normal;
-webkit-animation-direction: normal;
animation-direction: normal;
-moz-animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
transform: scale(0.001);
background: #cf0;
text-align: center;
font-size: 10vh;
opacity: 0;
}
#-moz-keyframes Slide_TheEnd {
0% { opacity: 0; transform: scale(0.001); }
10% { opacity: 1; transform: scale(1); }
95% { opacity: 1; transform: scale(1); }
100% { opacity: 0; transform: scale(0.001); }
}
Other keyframes are removed for the sake of bytes. Please disregard the odd coding, it is made by a php script picking values from an array and str_replacing a template: I'm too lazy to retype everything for every proprietary prefix on a 100+ divs slideshow.
I have the same problem and solved putting everything bellow a div with position:relative and added position: absolute, top:0, left:0 to every child div.
In your case it will be like:
<div id="upper" style="position: relative">
<div id="main-div" class="animated fadeInDownBig" style="position: absolute; left:0; top:0;"><!-- Content --></div>
<div id="div1" style="position: absolute; left:0; top:0;""><!-- Content --></div>
<div id="div2" style="position: absolute; left:0; top:0;""><!-- Content --></div>
<div id="div3" style="position: absolute; left:0; top:0;""><!-- Content --></div>
</div>
Related
I have some css like this
.top-over {
position: absolute;
top: 205px;
z-index: 55;
width: 100%;
min-height: 300px;
}
#keyframes slideDown {
0% {
-webkit-transform: translateY(-420px);
}
100% {
-webkit-transform: translateY(0%);
}
}
.slideDown {
-webkit-animation-name: slideDown;
animation-name: slideDown;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-timing-function: ease;
animation-timing-function: ease;
visibility: visible !important;
z-index: 50;
}
You will see that i have two classes slideDown and .top-over
.slideDown work just ok, but on .top-over it just jumps no slide effect, does anybody knows what i need to correct that this works to slideUp, thanks
Several notes:
you might want to remove the -webkit- prefixed values since they're not needed in this case. In cases where they are needed, they shouldn't be used either.
Both transform and animation are supported by every modern browser without prefixes.
use the same units across an animation - choose either px or %, not both.
you should post your html code as well. Please make it as minimal as possible and share your snippet.
<style>
.slider {
overflow-y: hidden;
max-height: 500px; /* approximate max height */
transition-property: all;
transition-duration: .5s;
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
}
.slider.closed {
max-height: 0;
}
</style>
<table class="table">
<tr>
<td>
<div class="slider">Some content here....</div>
</td>
</tr>
</table>
<%--Hope this will work.Thanks in advance--%>
<script type="text/javascript">
//You can use Predifined Function in JQuery
$(function () {
$('#trCaptcha').slideUp();
$('#trCaptcha').slideDown();
});
</script>
I am using bootstrap 3 for my web application, and I am running into and issue.
My navbar is wrapped in a container div,
my main content is wrapped in a container div adjacent to the navbar like so:
<body>
<div class="container">
//Navbar stuff
</div>
<div class="container">
//Navbar stuff
</div>
</body>
I have an animation on the body content that slides all of the content off of the screen while transitioning to a new screen. to do so I animate the left attribute to be off screen.
From what I can gather, this is causing the body width to expand beyond it's normal size, and this is causing my navbar to be affected by the position of content during the animation.
Is there a way to implement a sliding animation without increasing the width of the body, so that my navbar does not get moved during the animation?
EDIT:
To clarify how I am doing the animations, I am using CSS3 animation keyframes, and applying the class to the element I am sliding of screen. Here is the LESS that is doing this
#animation-duration: 300ms;
#animation-timing-function: ease-in-out;
#animation-fill-mode:forwards;
#animation-iteration-count: 1;
.slide-in-right{
animation-name: slideInRight;
animation-duration:#animation-duration;
animation-timing-function: #animation-timing-function;
animation-fill-mode: #animation-fill-mode;
animation-iteration-count: #animation-iteration-count;
}
.slide-out-right{
animation-name: slideInRight;
animation-duration:#animation-duration;
animation-direction: reverse;
animation-timing-function: #animation-timing-function;
animation-fill-mode: #animation-fill-mode;
animation-iteration-count: #animation-iteration-count;
}
.slide-in-left{
animation-name: slideInLeft;
animation-duration: 300ms;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-iteration-count: 1;
}
.slide-out-left{
animation-name: slideInLeft;
animation-direction: reverse;
animation-duration:#animation-duration;
animation-timing-function: #animation-timing-function;
animation-fill-mode: #animation-fill-mode;
animation-iteration-count: #animation-iteration-count;
}
#keyframes slideInRight{
0%{
position:relative;
left: 150%;
}
100%{
position:relative;
left:0%;
}
}
#keyframes slideInLeft{
0%{
position:relative;
left: -150%;
}
100%{
position:relative;
left:0%;
}
}
If you use transform: translateX(-100%); (where -100% is whatever you have to do to move it off screen), it shouldn't affect body width.
Also, using position: absolute; left: -100%; (again, -100% is whatever you have to do to move the element off screen), the body width shouldn't be affected, either.
I am afraid there are similar questions to this but I didn’t found a concrete solution, so I created a fiddle:
http://jsfiddle.net/Garavani/yrnjaf69/2/
<div class= "category_item">
<div class= "cat_button">
<span class="title_cat">TEXT</span>
</div>
</div>
CSS:
.category_item {
position: absolute;
background-color: #999;
top: 100px;
left: 50px;
width: 200px;
height: 200px;
/* seems to be overwriten by animation keyframes */
-webkit-transition: -webkit-transform 0.215s ease-in-out;
transition: transform 0.215s ease-in-out;
cursor: pointer;
}
.category_item:hover {
-webkit-animation-name: easeBack;
animation-name: easeBack;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#-webkit-keyframes easeBack {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
50% {
-webkit-transform: translateY(-50px);
transform: translateY(-50px);
}
100% {
-webkit-transform: translateY(-30px);
transform: translateY(-30px);
}
}
.cat_button {
position: absolute;
width: 200px;
height: 55px;
bottom: 0;
border: 2px solid #fff;
color: #fff;
-webkit-transition: background 0.215s ease-in-out, border 0.215s ease-in-out, color 0.215s ease-in-out;
transition: background 0.215s ease-in-out, border 0.215s ease-in-out, color 0.215s ease-in-out;
}
.category_item:hover .cat_button {
background: #fff;
border-color: #fff;
color: #511c5b;
}
In this (simplified) animation everything works fine except for when the mouse leaves the entire box. The animation starts from it original state, but abruptly.
The basic transition time (and ease) is ignored because it seems the keyframes have higher importance and overwrite it.
What I need is the keyframe animation triggering AND when the mouse leaves it should turn back to the original state smoothly.
Is there a solution for this
1) in pure CSS
2) maybe with some little javascript only?
Thanks in advance for help and ideas!
EDIT:
After implementing the solution offered kindly by Toni this is the correct fiddle:
http://jsfiddle.net/yrnjaf69/40/
Thanks again Toni!
EDIT 2:
Sadly, yet, there is one question left. The part with the keyframes is not executed on Firefox even though I added all the -moz- vendors, too, in this fiddle:
http://jsfiddle.net/dr6Ld0wL/1/
Why?
PS: As far as I tested for now it works even in Opera (Beta). Only browser resisting is Firefox
EDIT 3:
The correct (working) code is now in this fiddle:
http://jsfiddle.net/dr6Ld0wL/16/
The keyframes also need to be explicitly divided in vendor prefixes. Jesus Christ. Those prefixes…
Here is a jsfiddle that achieves this.
.demo-hover {
position: relative;
margin: 100px;
animation: complexProcessReversed 2s ease-in forwards;
width: 160px;
height: 160px;
background-color: #88d;
}
.demo-hover:hover {
animation: complexProcess 2s ease-in forwards;
width: 100px;
height: 100px;
background-color: #732;
}
#keyframes complexProcess {
/* keyframes */
}
#keyframes complexProcessReversed {
/* keyframes (opposite) */
}
The animation out is assigned in the css in the main class, then the hover state kicks in on hover and css re-applies the original class properties on unhover.
The animation does trigger backwards on page load, so you might like to think of tweaking your animation to take this into account, like this example, pinched from this answer. Alternatively, use javascript (or jquery), like this example where the animations are triggered by adding and removing classes to the target using jquery:
JavaScript
$('.demo-hover').hover(
function() {
// mouse in
$(this).removeClass('forwards--reversed').addClass('forwards');
},
function() {
// mouse out
$(this).removeClass('forwards').addClass('forwards--reversed');
}
);
CSS
.forwards {
animation: complexProcess 2s ease-in forwards;
width: 100px;
height: 100px;
background-color: #732;
}
.forwards--reversed {
animation: complexProcessReversed 2s ease-in forwards;
width: 160px;
height: 160px;
background-color: #88d;
}
Also, I'd use #keyframe or transition. Use transition if you just need a simple even change from n to m but when things are more complex, such as one thing changing evenly over 100% but another thing not starting until 50% off the animation has played, then use a #keyframe
Using both will cause confusion, especially if you're trying to animate the same properties.
Finally css vendor prefixes are required
I am trying to implement some animation onLoad without Javascript. JS is easy, CSS is ... not.
I have a div which should be on display: none; and should be display: block; after 3 secondes. Lots of resources told me animate does not work with display, but should with visibility (which I use often in my transition).
Right know I have this terrible javascript function :
<script type="text/javascript">
$(document).ready(function(){
$(".js_only").hide();
setTimeout(function () {
$(".js_only").show();
}, 3000);
});
</script>
I tried some animation in CSS but no result ... nothing seems to work.
I have few animation in my page, but just struggling with the display: none; on animation.
#-moz-keyframes showEffect {
0% { display: none; visibility: hidden; }
100% { display: block; visibility: block; }
}
#-webkit-keyframes showEffect {
0% { display: none; visibility: hidden; }
100% { display: block; visibility: block; }
}
#keyframes showEffect {
0% { display: none; visibility: hidden; }
100% { display: block; visibility: block; }
}
.css_only {
-moz-animation-name: showEffect;
-moz-animation-iteration-count: 1;
-moz-animation-timing-function: ease-in;
-moz-animation-duration: 2.3s;
-webkit-animation-name: showEffect;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in;
-webkit-animation-duration: 2.3s;
animation-name: showEffect;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 2.3s;
}
It is important as hidden, this element does not take space at all. I created a JSFiddle to make quite tests.
My main concerne is SEO ... I don't think the JS option is really nice for that which is why I would like a pure CSS alternative. Also interested to test those animations and see where are those limits (Am I seeing one right now ?). Kinda having fun on such challenge.
Thanks for reading, hope someone has an answer.
You are correct in thinking that display is not animatable. It won't work, and you shouldn't bother including it in keyframe animations.
visibility is technically animatable, but in a round about way. You need to hold the property for as long as needed, then snap to the new value. visibility doesn't tween between keyframes, it just steps harshly.
.ele {
width: 60px;
height: 60px;
background-color: #ff6699;
animation: 1s fadeIn;
animation-fill-mode: forwards;
visibility: hidden;
}
.ele:hover {
background-color: #123;
}
#keyframes fadeIn {
99% {
visibility: hidden;
}
100% {
visibility: visible;
}
}
<div class="ele"></div>
If you want to fade, you use opacity. If you include a delay, you'll need visibility as well, to stop the user from interacting with the element while it's not visible.
.ele {
width: 60px;
height: 60px;
background-color: #ff6699;
animation: 1s fadeIn;
animation-fill-mode: forwards;
visibility: hidden;
}
.ele:hover {
background-color: #123;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
visibility: visible;
opacity: 1;
}
}
<div class="ele"></div>
Both examples use animation-fill-mode, which can hold an element's visual state after an animation ends.
Use animation-delay:
div {
width: 100px;
height: 100px;
background: red;
opacity: 0;
animation: fadeIn 3s;
animation-delay: 5s;
animation-fill-mode: forwards;
}
#keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
Fiddle
You can play with delay prop of animation, just set visibility:visible after a delay, demo:
#keyframes delayedShow {
to {
visibility: visible;
}
}
.delayedShow{
visibility: hidden;
animation: 0s linear 2.3s forwards delayedShow ;
}
So, Where are you?
<div class="delayedShow">
Hey, I'm here!
</div>
Unfortunately you can't animate the display property. For a full list of what you can animate, try this CSS animation list by w3 Schools.
If you want to retain it's visual position on the page, you should try animating either it's height (which will still affect the position of other elements), or opacity (how transparent it is). You could even try animating the z-index, which is the position on the z axis (depth), by putting an element over the top of it, and then rearranging what's on top. However, I'd suggest using opacity, as it retains the vertical space where the element is.
I've updated the fiddle to show an example.
Good luck!
you can't animate every property,
here's a reference to which are the animatable properties
visibility is animatable while display isn't...
in your case you could also animate opacity or height depending of the kind of effect you want to render_
fiddle with opacity animation
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