I was trying to make a 100% pure css animation, fadein and fadeout when i click on hamburguer menu to reveal the sidebar, (the backdrop should showing opacity like 500 miliseconds) (like jquery fadein) and when i click inside the sidebar to close the menu (the backdrop should hidde the opacity in 2 seconds) (like jquery fadeout)
You can see the version of jquery code here: https://cdpn.io/gilperon/fullpage/ZErBzvY
This is a very simple code, to open menu i put the event on hamburguer icon onclick=' $('#menu-backdrop').fadeIn(500);' and close to close, i put onclick=' $('#menu-backdrop').fadeout(2000);'
If it is not possible to make 100% css pure the animation, since it should be activated by onclick, maybe use just the javascript pure to onclick to add class, and the animation by done via css
I have a lot of ways using height:0 and key frames, but it was not possible to make the animation fadeout, fadein it works.
I make a code that workds to fadein, but to fadeout not working:
Another options are welcome, maybe using visibility, or other ways to show and hidden the animation, display:none usually not works with css animation
#menu-backdrop {
display: none;
animation:fadeOut 5s linear;
}
#menu-backdrop.exibir {
display: block;
animation:fadeIn 0.5s linear;
}
#keyframes fadeIn {
0% {
opacity:0
}
100% {
opacity:1;
}
}
#keyframes fadeOut {
0% {
opacity:1
}
100% {
opacity:0;
}
}
If anyone can post a work solution should be great, thank you very much guys.
Okay what you need is a transition, and you need to move away from your display property as it will break your animations and transitions since you cannot animate or transition that property in CSS.
A quick example:
const button = document.querySelector( 'button' );
const nav = document.querySelector( 'nav' );
button.addEventListener( 'click', event => {
event.preventDefault();
nav.classList.toggle( 'active' );
});
nav {
position: fixed;
right: 0;
top: 0;
width: 50%;
height: 100%;
background: red;
transition: opacity .4s;
/* This should be set to 0, but to make the point
* of pointer-events clear, I will set it to slightly
* higher so you can see there's no interaction
* with the nav. */
opacity: .1;
pointer-events: none;
}
nav:hover {
/* If you can interact with the navigation,
* you will see it change color. */
background: blue;
}
nav.active {
opacity: 1;
pointer-events: all;
}
nav + button:before {
content: 'Open ';
}
nav.active + button:before {
content: 'Close ';
}
<nav></nav>
<button>Nav</button>
The above shows you that by combining pointer-events: none with opacity you can effectively hide your menu. I added the :hover state for the <nav> to show that you cannot click the <nav> when it is open, and you should therefor consider this element invisible to the user.
I'm trying to create a 100% width and 100vh height div which would slide from out of the screen from above to down of page. At the 70% of animation I would like to make it at the bottom then at 90% move it 30px up and on 100% make it at the bottom again so it would look like it slide from up then bounce at the bottom.
I want this happen after clicking some DOM element in a grand grandchild so basically, I'll use eventBus and my "sliding div" will be in root component (app.vue) and in the child I'll emit:
showObserved() {
eventBus.$emit('showObserved');
}
here I'm emitting my custom event and then I'm watching this event in root component and changing boolean variable:
eventBus.$on('showObserved', async() => {
this.showObserved = true;
});
eventBus.$on('hideObserved', async() => {
this.showObserved = false;
});
and basing on this boolean I'm displaying my sliding div using v-if directive:
<transition name="slide-up" mode="out-in">
<observed-offer v-if="showObserved"></observed-offer>
</transition>
and here finally I use transition vue built-in component in order to make it sliding and this are my styles which should make effect that I explained in first parahraph:
/* slide from up to down */
.slide-up-leave-active {
animation: slide-out-up .4s linear;
}
.slide-up-enter-active {
animation: slide-in-up .4s linear forwards;
}
.slide-up-in-leave-active {
animation: slide-out-up .4s linear;
}
.slide-up-leave {
opacity: 1;
transform: translateY(-100%);
}
#keyframes slide-out-up {
0% {
transform: translateY(0);
}
70% {
transform: translateY(0);
}
90% {
transform: translateY(10%);
}
100% {
transform: translateY(0);
}
}
#keyframes slide-in-up {
0% {
transform: translateY(-100%);
}
70% {
transform: translateY(0);
}
90% {
transform: translateY(10%);
}
100% {
transform: translateY(0);
}
}
and this are style's of my sliding div:
.observed {
width: 100%;
height: 100vh;
z-index: 999999999;
overflow: hidden;
background-color: white;
}
But this doesn't work behavior is that it instantly makes entire page white and slide only content of div. I'm pretty sure that I just made wrong CSS styles I tried various other styles and it didn't work. Also maybe it has also something to do with height: 100vh.
I add demo repository. In this demo sliding in is almost working but slide out doesn't work at all. Installation of this project is simple just clone it then cd path/to/project then npm install && npm run dev or something similiar depending on OS.
In demo it's also not hovering entire page but it leave space for button as you'll see if you clone it.
Well actually I handle to fix transitions in demo repo now the only issue is that it doesn't veil/cover entire page but it leave space for root content. Pull repo again to see that.
Issue was that I was using bad transition styles and that I didn't have fixed position with top: 0 left: 0 on my panel component. After fixing that it's working correctly as you can inspect in demo repository.
Sorry for wasting time for issue that I fixed myself but it was much harder to troubleshoot in origin big project. When I created this demo repo it became so easy.
We are implementing a wishlist functionality on a site we are developing, and when the user clicks on an icon to add the current item to a wishlist, it fires an ajax request.
Now while that ajax request is doing it's business, we add a loading class to the icon, so it scales bigger and smaller slightly. My issue, is once the ajax request has finished loading, we then remove that class, but the animation abruptly stops rather than scaling back down to it's initial size.
How can we make the animation finish, rather than just suddenly stopping?
Below is my CSS:
/**
* Keyframes
*/
#keyframes breathe {
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
/**
* Icon
*/
.wishlist-icn {
transition: all .3s ease;
}
.wishlist-icn--isAdded {
fill: #4B3814;
}
.wishlist-icn--isLoading {
animation: breathe 2s ease-in-out 0s infinite normal both;
}
tl;dr: Try applying animation-fill-mode: forwards
The normal behavior after CSS animation is done is that it resets the styles to the initial state. The way I see the process here is that when you remove the --isLoading class the animation stops and reverts the styles to the original state. Only after then the transitions starts to work and has nothing to do since the styles already are reset. animation-fill-mode: forwards in .wishlist-icn would prevent the animation from resetting, thus the transition would be able to operate gradually. To be sure you can add transform: scale(1) to .wishlist-icn or to :not(.wishlist-icn--isLoading) so that the transition knew what to head for. Not that I have tested it in this particular case, but it's worth trying ;P
$('.start-animation').on('click', function() {
$('.wishlist-icn').addClass('wishlist-icn--isLoading');
});
$('.stop-animation').on('click', function() {
$(".wishlist-icn").bind("mozAnimationIteration animationiteration webkitAnimationIteration", function() {
$(this).removeClass("wishlist-icn--isLoading");
});
});
/**
* Keyframes
*/
#keyframes breathe {
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
/**
* Icon
*/
.wishlist-icn {
position: relative;
display: inline;
transition: all 2s ease;
font-size: 5em;
}
.wishlist-icn--isAdded {
fill: #4B3814;
}
.wishlist-icn--isLoading {
animation: breathe 2s ease-in-out 0s infinite normal both;
animation-fill-mode: forward;
}
.wishlist-icn--isLoaded {
transform: scale(1);
}
}
<link href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="wishlist-icn"> <i class="ion-heart"></i>
</div>
<button class="start-animation">start animation</button>
<button class="stop-animation">stop animation</button>
you would probably have to use javascript to listen for the animation iteration to end then remove the class.
$(".wishlist-icn").bind( "mozAnimationIteration animationiteration webkitAnimationIteration" , function() {
$(this).removeClass("wishlist-icn--isLoading");
});
I am following this tutorial on how to animate to different views of my app. The animation works fine, but in the demo they do not have a Navbar.
I want to have a Navbar not animate for my app and just animate the ng-view. Right now the Navbar moves out of place and looks glitchy. I thought it was a Z-index problem, but that does not seem to fix it at all.
How can I keep the Navbar from moving when the ng-view is animated?
Index Html
<div data-ng-controller="HeaderCtrl">
<div class="top-header" data-ng-include="templateUrl"></div>
</div>
<div class="page [[ pageClass ]]" ng-view></div>
CSS
/* Page Animations */
/* slide in from the bottom */
#keyframes slideOutUp {
to { transform: translateY(-100%); }
}
/* slide in from the right */
#keyframes slideInDown {
from { transform:translateY(-100%); }
to { transform: translateY(0); }
}
/* slide in from the bottom */
#keyframes slideInUp {
from { transform:translateY(100%); }
to { transform: translateY(0); }
}
.ng-enter {
animation: slideInDown .3s both ease-in;
z-index: 7777;
}
.ng-leave {
animation: slideOutUp .3s both ease-in;
z-index: 8888;
}
.top-header {
z-index: 9999;
}
Header Javascript
app.controller('HeaderCtrl', function($scope, $location) {
$scope.pageClass = 'top-header';
$scope.$on('$locationChangeSuccess', function(event, newurl, prevurl) {
$scope.templateUrl = $location.path()==='/signin' ? 'pages/SigninHeader.html' : 'pages/NormalHeader.html' ;
}); });
The solution is simple. You must move the header outside of the container that is animated or alternatively move the animation to the container that you want to animate. The full HTML source code would be helpful.
Is it possible to use CSS3 transition animation on page load without using Javascript?
This is kind of what I want, but on page load:
image-slider.html
What I found so far
CSS3 transition-delay, a way to delay effects on elements. Only works on hover.
CSS3 Keyframe, works on load but are extremly slow. Not useful because of that.
CSS3 transition is fast enough but don't animate on page load.
You can run a CSS animation on page load without using any JavaScript; you just have to use CSS3 Keyframes.
Let's Look at an Example...
Here's a demonstration of a navigation menu sliding into place using CSS3 only:
#keyframes slideInFromLeft {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0);
}
}
header {
/* This section calls the slideInFromLeft animation we defined above */
animation: 1s ease-out 0s 1 slideInFromLeft;
background: #333;
padding: 30px;
}
/* Added for aesthetics */ body {margin: 0;font-family: "Segoe UI", Arial, Helvetica, Sans Serif;} a {text-decoration: none; display: inline-block; margin-right: 10px; color:#fff;}
<header>
Home
About
Products
Contact
</header>
Break it down...
The important parts here are the keyframe animation which we call slideInFromLeft...
#keyframes slideInFromLeft {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0);
}
}
...which basically says "at the start, the header will be off the left hand edge of the screen by its full width and at the end will be in place".
The second part is calling that slideInFromLeft animation:
animation: 1s ease-out 0s 1 slideInFromLeft;
Above is the shorthand version but here is the verbose version for clarity:
animation-duration: 1s; /* the duration of the animation */
animation-timing-function: ease-out; /* how the animation will behave */
animation-delay: 0s; /* how long to delay the animation from starting */
animation-iteration-count: 1; /* how many times the animation will play */
animation-name: slideInFromLeft; /* the name of the animation we defined above */
You can do all sorts of interesting things, like sliding in content, or drawing attention to areas.
Here's what W3C has to say.
Very little Javascript is necessary:
window.onload = function() {
document.body.className += " loaded";
}
Now the CSS:
.fadein {
opacity: 0;
-moz-transition: opacity 1.5s;
-webkit-transition: opacity 1.5s;
-o-transition: opacity 1.5s;
transition: opacity 1.5s;
}
body.loaded .fadein {
opacity: 1;
}
I know the question said "without Javascript", but I think it's worth pointing out that there is an easy solution involving one line of Javascript.
It could even be inline Javascript, something like that:
<body onload="document.body.className += ' loaded';" class="fadein">
That's all the JavaScript that's needed.
I think I have found a sort of work around for the OP question - instead of a transition beginning 'on.load' of the page - I found that using an animation for an opacity fade in had the same effect, (I was looking for the same thing as OP).
So I wanted to have the body text fade in from white(same as site background) to black text colour on page load - and I've only been coding since Monday so I was looking for an 'on.load' style thing code, but don't know JS yet - so here is my code that worked well for me.
#main p {
animation: fadein 2s;
}
#keyframes fadein {
from { opacity: 0}
to { opacity: 1}
}
And for whatever reason, this doesn't work for .class only #id's(at least not on mine)
Hope this helps - as I know this site helps me a lot!
CSS only with a delay of 3s
a few points to take here:
multiple animations in one call
we create a wait animation that just delays the actual one (the second one in our case).
Code:
header {
animation: 3s ease-out 0s 1 wait, 0.21s ease-out 3s 1 slideInFromBottom;
}
#keyframes wait {
from { transform: translateY(20px); }
to { transform: translateY(20px); }
}
#keyframes slideInFromBottom {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
Well, this is a tricky one.
The answer is "not really".
CSS isn't a functional layer. It doesn't have any awareness of what happens or when. It's used simply to add a presentational layer to different "flags" (classes, ids, states).
By default, CSS/DOM does not provide any kind of "on load" state for CSS to use. If you wanted/were able to use JavaScript, you'd allocate a class to body or something to activate some CSS.
That being said, you can create a hack for that. I'll give an example here, but it may or may not be applicable to your situation.
We're operating on the assumption that "close" is "good enough":
<html>
<head>
<!-- Reference your CSS here... -->
</head>
<body>
<!-- A whole bunch of HTML here... -->
<div class="onLoad">OMG, I've loaded !</div>
</body>
</html>
Here's an excerpt of our CSS stylesheet:
.onLoad
{
-webkit-animation:bounceIn 2s;
}
We're also on the assumption that modern browsers render progressively, so our last element will render last, and so this CSS will be activated last.
add this to your css for fade in animation
body{animation: 2s ease-out 0s 1 FadeIn;}
#keyframes FadeIn {
0% {
opacity:0;
}
100% {
opacity:1;
}
}
increase the ease-out time if you want it to load slower
Even simplier solution (still with [one line inline] javascript):
Use this as the body tag:
Note that body. or this. did not work for me. Only the long ; querySelector allow the use of classList.remove (Linux Chromium)
<body class="onload" onload="document.querySelector('body').classList.remove('onload')">
and add this line on top of your other css rules.
body.onload *{ transform: none !important; }
Take note that this can apply to opacity (as requested by OP [other posters] ) simply by using opacity as a transition trigger instead. (might even work on any other css ruling in the same fashion and you can use multiple class for explicity delay between triggering)
The logic is the same. Enforce no transform (with :none !importanton all child element of body.onloadand once the document is loaded remove the class to trigger all transition on all elements as specified in your css.
FIRST ANSWER BELOW (SEE EDIT ABOVE FOR SHORTER ANSWER)
Here is a reverse solution:
Make your html layout and set the css accordingly to your final result (with all the transformation you want).
Set the transition property to your liking
add a class (eg: waitload) to the elements you want to transform AFTER load. The CSS keyword !important is the key word here.
Once the document is loaded, use JS to remove the class from the elements to to start transformation (and remove the transition: none override).
Works with multiple transition on multiple elements. Did not try cross-browser compatibility.
div {
width: fit-content;
}
#rotated {
transform: rotate(-50deg)/* any other transformation */
;
transition: 6s;
}
#translated {
transform: translate(90px)/* any other transformation */
;
transition: 6s;
}
.waitload {
transform: none !important;
}
<div id='rotated' class='waitload'>
rotate after load
</div>
<div id='translated' class='waitload'>
trasnlate after load
</div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', init);
function init() {
[...document.querySelectorAll('.waitload')]
.map(e => e.classList.remove('waitload'));
}
</script>
Similar to #Rolf's solution, but skip reference to external functions or playing with class. If opacity is to remain fixed to 1 once loaded, simply use inline script to directly change opacity via style. For example
<body class="fadein" onload="this.style.opacity=1">
where CSS sytle "fadein" is defined per #Rolf,defining transition and setting opacity to initial state (i.e. 0)
the only catch is that this does not work with SPAN or DIV elements, since they do not have working onload event
start it with hover of body than It will start when the mouse first moves on the screen, which is mostly within a second after arrival, the problem here is that it will reverse when out of the screen.
html:hover #animateelementid, body:hover #animateelementid {rotate ....}
thats the best thing I can think of: http://jsfiddle.net/faVLX/
fullscreen: http://jsfiddle.net/faVLX/embedded/result/
Edit see comments below:
This will not work on any touchscreen device because there is no hover, so the user won't see the content unless they tap it. – Rich Bradshaw
Ok I have managed to achieve an animation when the page loads using only css transitions (sort of!):
I have created 2 css style sheets:
the first is how I want the html styled before the animation...
and the second is how I want the page to look after the animation has been carried out.
I don't fully understand how I have accomplished this but it only works when the two css files (both in the head of my document) are separated by some javascript as follows.
I have tested this with Firefox, safari and opera. Sometimes the animation works, sometimes it skips straight to the second css file and sometimes the page appears to be loading but nothing is displayed (perhaps it is just me?)
<link media="screen,projection" type="text/css" href="first-css-file.css" rel="stylesheet" />
<script language="javascript" type="text/javascript" src="../js/jQuery JavaScript Library v1.3.2.js"></script>
<script type='text/javascript'>
$(document).ready(function(){
// iOS Hover Event Class Fix
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) ||
(navigator.userAgent.match(/iPad/i))) {
$(".container .menu-text").click(function(){ // Update class to point at the head of the list
});
}
});
</script>
<link media="screen,projection" type="text/css" href="second-css-file.css" rel="stylesheet" />
Here is a link to my work-in-progress website: http://www.hankins-design.co.uk/beta2/test/index.html
Maybe I'm wrong but I thought browsers that do not support css transitions should not have any issues as they should skip straight to the second css file without delay or duration.
I am interested to know views on how search engine friendly this method is. With my black hat on I suppose I could fill a page with keywords and apply a 9999s delay on its opacity.
I would be interested to know how search engines deal with the transition-delay attribute and whether, using the method above, they would even see the links and information on the page.
More importantly I would really like to know why this is not consistent each time the page loads and how I can rectify this!
I hope this can generate some views and opinions if nothing else!
If anyone else had problems doing two transitions at once, here's what I did. I needed text to come from top to bottom on page load.
HTML
<body class="existing-class-name" onload="document.body.classList.add('loaded')">
HTML
<div class="image-wrapper">
<img src="db-image.jpg" alt="db-image-name">
<span class="text-over-image">DB text</span>
</div>
CSS
.text-over-image {
position: absolute;
background-color: rgba(110, 186, 115, 0.8);
color: #eee;
left: 0;
width: 100%;
padding: 10px;
opacity: 0;
bottom: 100%;
-webkit-transition: opacity 2s, bottom 2s;
-moz-transition: opacity 2s, bottom 2s;
-o-transition: opacity 2s, bottom 2s;
transition: opacity 2s, bottom 2s;
}
body.loaded .text-over-image {
bottom: 0;
opacity: 1;
}
Don't know why I kept trying to use 2 transition declarations in 1 selector and (not really) thinking it would use both.
You could use custom css classes (className) instead of the css tag too.
No need for an external package.
import React, { useState, useEffect } from 'react';
import { css } from '#emotion/css'
const Hello = (props) => {
const [loaded, setLoaded] = useState(false);
useEffect(() => {
// For load
setTimeout(function () {
setLoaded(true);
}, 50); // Browser needs some time to change to unload state/style
// For unload
return () => {
setLoaded(false);
};
}, [props.someTrigger]); // Set your trigger
return (
<div
css={[
css`
opacity: 0;
transition: opacity 0s;
`,
loaded &&
css`
transition: opacity 2s;
opacity: 1;
`,
]}
>
hello
</div>
);
};
Not really, as CSS is applied as soon as possible, but the elements might not be drawn yet. You could guess a delay of 1 or 2 seconds, but this won't look right for most people, depending on the speed of their internet.
In addition, if you want to fade something in for instance, it would require CSS that hides the content to be delivered. If the user doesn't have CSS3 transitions then they would never see it.
I'd recommend using jQuery (for ease of use + you may wish to add animation for other UAs) and some JS like this:
$(document).ready(function() {
$('#id_to_fade_in')
.css({"opacity":0}) // Set to 0 as soon as possible – may result in flicker, but it's not hidden for users with no JS (Googlebot for instance!)
.delay(200) // Wait for a bit so the user notices it fade in
.css({"opacity":1}); // Fade it back in. Swap css for animate in legacy browsers if required.
});
Along with the transitions added in the CSS. This has the advantage of easily allowing the use of animate instead of the second CSS in legacy browsers if required.