I'm using jQuery to toggle between my light theme and dark theme:
$(".theme__switch").on("click", () => {
$("body").toggleClass("light__theme dark__theme");
});
My goal is to attach a fade-in animation to both these classes.
It works for light__theme on load, and when I toggle back from dark__theme, but when I try to add the fade-in animation to my dark__theme, the animation doesn't work for either themes
I start with: <body class="light__theme">
.light__theme {
animation: fadein 2s;
}
#keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}
which works fine, but when I try to attach the animation to my
dark__theme class like so:
.dark__theme {
--background: #121212;
--text: #f2f3f4;
background: var(--background);
// adding the animation in
animation: fadein 2s;
}
I don't get the fade-in animation, and it also removes the animation from my light theme.
The classes are being toggled correctly, I can see that when inspecting the <body> in dev tools, but I'm not sure whats causing my issue. Perhaps the way I'm calling the animation in my css?
I'd really appreciate any help on this one.. thanks for looking!
You need to add reverse to the animation for dark__theme:
.dark__theme {
--background: #121212;
--text: #f2f3f4;
background: var(--background);
// adding the animation in
animation: fadein 2s reverse;
}
Animation MDN
Related
I am trying to create a sort of loading animation, with 3 bars that are below eachother that all have seperate keyframes.
The 3 bars are div elements, located inside a parent div.
<div id="menu">
<div id="menubox1"></div>
<div id="menubox2"></div>
<div id="menubox3"></div>
</div>
The animation properties are assigned to the individual menubox ids.
#menubox1:after {
content: '';
position: absolute;
bottom: 0px;
transform: translateY(-50%);
border-top: 1px solid #FFDADA;
animation: menukeyframes1;
animation-duration: 2000ms;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
animation-play-state: inherit;
}
#keyframes menukeyframes1 {
0% { width: 100%; left:0;}
...
}
My goal is to play the animation while the cursor is hovering over the parent div.
My attempt was to play around with animation-play-state which was set to running or paused, depending if the parent div was hovered.
The problem is that the animation is immediatly paused, before the animation is complete, which looks kind of bad if it stops mid-motion.
Is there a good fix for this, preferrably without JavaScript/jQuery, and across all browsers?
As you see it can't be done with just CSS at this moment, and as good jquery answers are already referenced, it's worth to mention that it could be solved in few lines of vanillaJS:
var dur = 2000;
document.querySelectorAll('.smooth').forEach(el=>{
var t;
el.addEventListener('mouseover',_=>{t = performance.now();el.style.animationPlayState = 'running'})
el.addEventListener('mouseout',_=>window.setTimeout(()=>el.style.animationPlayState = 'paused',dur-(performance.now()-t)%dur));
})
working pen
non-es6: BABEL
You can always fade out the animated divs using transitions.
Something like this might work for you:
#menubox1 {
opacity: 0;
transition: opacity .5s linear;
}
#menu:hover {
#menubox1 {
opacity: 1;
transition: opacity .5s linear;
}
}
Ok, I have a situation where I have basically built a little notification dropdown box that happens when the user does something, at the end it transitions to a opacity: 0; state.
However, because the user may click something else that will trigger this notification box again I am trying to come up with a way to reset it back to normal without affecting any in-progress transitions and attempting to keep the animation done by CSS rather than JavaScript.
CodePen:http://codepen.io/gutterboy/pen/WoEydg
HTML:
Open Notify Window
<div id="top_notify" class="top-notify">
<div class="container-fluid">
<div class="row">
<div class="content col-xs-12">
<div class="alert" role="alert"></div>
</div>
</div>
</div>
</div>
SCSS:
body {
text-align: center;
padding-top: 150px;
}
.top-notify {
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
.content {
text-align: center;
background-color: transparent;
transform-style: preserve-3d;
}
.alert {
display: inline-block;
transform: translateY(-100%);
min-width: 250px;
max-width: 500px;
border-top-left-radius: 0;
border-top-right-radius: 0;
&.visible {
transform: translateY(0%);
transition: 0.8s 0s, opacity 1s 3.8s;
opacity: 0;
}
}
}
JS:
$('a').on('click', function(e){
e.preventDefault();
myFunc();
});
function myFunc() {
// Set file to prepare our data
var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html";
// Run request
getAjaxData(loadUrl, null, 'POST', 'html')
.done(function(response) {
var alert_el = $('#top_notify').find('.alert');
// Update msg in alert box
alert_el.text(response);
alert_el.addClass('alert-success');
// Slide in alert box
alert_el.addClass('visible');
})
.fail(function() {
alert('Problem!!');
});
// End
}
function getAjaxData(loadUrl, dataObject, action, type) {
return jQuery.ajax({
type: action,
url: loadUrl,
data: dataObject,
dataType: type
});
}
I know I can reset it back to normal by doing this in JS:
$('#top_notify').find('.alert').removeClass().addClass('alert'); // The classes it ends up with vary
...however doing this removes the classes before the transition is finished fading out the opacity and it just vanishes straight away.
I know I can do a delay in JS to counteract the CSS delay but doing it that way just doesn't seem a very good way to do it since you have the timings in 2 different places.
Is there any way I can accomplish this whilst keeping the animation done by CSS or will I have to move to using jQuery's animate so I can run the reset procedure once the animation is complete?
Ok, I came up with a simple solution after coming up with a convoluted one ha.
Simple solution I should have come up with in the first place was removing any additional added classes before the ajax call; I got too focused on doing it within the ajax block and of course that didn't work, but until I started playing around with the other solution I never tried it.
Any way, the simple solution is simply moving this code:
var alert_el = $('#top_notify').find('.alert');
...above the ajax call, rather than being inside of it.
Then adding this directly under it:
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
With the full function code being:
function myFunc() {
// Set file to prepare our data
var loadUrl = "https://crossorigin.me/http://codepen.io/gutterboy/pen/ObjExz.html";
var alert_el = $('#top_notify').find('.alert');
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
// Run request
getAjaxData(loadUrl, null, 'POST', 'html')
.done(function(response) {
// Update msg in alert box
alert_el.text(response);
alert_el.addClass('alert-success');
// Slide in alert box
alert_el.addClass('visible');
})
.fail(function() {
alert('Problem!!');
});
// End
}
CodePen: http://codepen.io/gutterboy/pen/xRXbXy
The other solution I came up with, whilst not really needed now, I thought I would post it anyway in-case it comes in handy for me (or someone) else in the future.
It doesn't remove the visible class after the animation is finished (as there is no way that I know of to alert JS when it's done) but the visible class - which I would change the name of if you use this method - doesn't add any new styles, it just runs the animation.
Here is how I did it:
The JavaScript remains the same as the solution above, it's all in the CSS.
TLDR;
Basically uses multiple CSS animations to control different states during the effect runtime; CodePen at bottom.
The changes being in the .visible class and the addition of some #keyframes.
.visible class:
&.visible {
animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s;
}
As you can see we have gotten rid of any additional styling here - this means when the animation is done, it essentially resets back to normal, which is what we want.
Now, let's break down this code:
We are running 3 different animations here and it's important to note they don't run one after the other - meaning they don't wait until one is finished until it starts the next one, hence why we needed to include delay settings.
So first up we start with the slideDown animation:
slideDown 0.8s 0s
If you are new to animations in CSS then basically what this does is sets a delay of 0s before it starts running and the animation runs for 0.8s, and this is the animation:
#keyframes slideDown {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
So, pretty simple, just slides it down with transform from -100% to 0% and this animation takes 0.8s as we set in our call to this animation.
Now, I wanted this to stay visible for 3 seconds before it started to fade away, but we have a problem; once the animation ends then it goes back to it's standard styling, which in our case means it vanishes as it goes back to transform: translateY(-100%) since we have no extra styles in the .visible class, and we can't put any extra styles in there as then we won't be able to reset it back to it's original state (style wise).
But what do we do? The fadeAway animation doesn't start for another 3 seconds and at the moment it doesn't have anything to fade away (well it does, but you can't see it as it's hidden).
The solution to that was adding another animation - which technically doesn't really animate anything, it just keeps it visible until the fadeAway animation starts.
That's where we get to:
keepThere 3s 0.8s
Now, remembering the settings of our fadeAway animation are: fadeAway 1s 3.8s this means that we have 3 seconds before this animation is going to start and hence before we can control any of the styling with it.
So that's where these parameter values comes in - we set the delay to 0.8s so the keepThere animation doesn't start until the slideDown one has finished; then we set the duration for 3s to counter for the wait time until the fadeAway animation starts, and this is the keepThere animation:
#keyframes keepThere {
0%, 100% {
transform: translateY(0%);
}
}
Since it has the same start and end styling we combine it into one selector of 0%, 100% and as you can see, this does just what it says it does, keeps the element visible for the set duration of 3s until we can control the styling with the fadeAway animation.
I guess technically you could combine this functionality into the fadeAway animation if you wanted to do the math at what % equals 3 seconds and hence know when to start fading the element away.
Lastly we have the fadeAway animation:
fadeAway 1s 3.8s
Now as we have discussed above, we already know why we have set the delay to 3.8s, the 0.8s offset to allow the slideDown animation to run and an additional 3s delay as that's how long we want the element to be visible for until it starts fading away and then of course the fade takes 1s to complete.
The animation for this is:
#keyframes fadeAway {
0%, 100% {
transform: translateY(0%);
}
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
Now, since the keepThere animation has completed, we have to make sure to keep the element visible so the fade has something visible to actually fade away, that's why we make sure to include the style transform: translateY(0%); as a value from start to finish; after that it's quite obvious what it's doing I think.
Put it all together and you get:
.top-notify {
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
.content {
text-align: center;
background-color: transparent;
transform-style: preserve-3d;
}
.alert {
display: inline-block;
transform: translateY(-100%);
min-width: 250px;
max-width: 500px;
border-top-left-radius: 0;
border-top-right-radius: 0;
&.visible {
animation: slideDown 0.8s 0s, keepThere 3s 0.8s, fadeAway 1s 3.8s;
}
}
}
#keyframes slideDown {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
#keyframes keepThere {
0%, 100% {
transform: translateY(0%);
}
}
#keyframes fadeAway {
0%, 100% {
transform: translateY(0%);
}
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
CodePen: http://codepen.io/gutterboy/pen/QGqwBg
Then of course to be able to run it again the class has to be re-added and hence that was the purpose of removing the .visible class at the start of each run (before the ajax call) and then when it gets re-added during the ajax call it runs again.
Thanks to #Nathaniel Flick for sharing the link that led me down this path to begin with :)
Well, hopefully that comes in handy for someone seeing as I am no longer going to use that option ha!
I am using the materialize framework and smoothState.js, and have noticed two glaring problems.
When I shrink down to mobile view and (And a mobile device for that matter), when clicking the hamburger icon It fires but it doesn't work as expected. e.g. clicking to different pages doesn't work.
SS appears to meddle with the image slider library too, suddenly my navigation disappears.
Smoothstate seems to work in desktop mode however I am still getting the problems with my slider for my images. And there seems to be a lag, when it fires, like it's revving up before firing.
I made a fiddle but I can't figure out how to make the separate pages link within one fiddle. Sorry. Maybe someone can show me!
As a preview, below is my css && js.
https://jsfiddle.net/718BkQns/L1rd0gLc/
css:
.m-scene .scene_element {
animation-duration: 0.25s;
transition-timing-function: ease-in;
animation-fill-mode: both;
}
.m-scene .scene_element--fadein {
animation-name: fadeIn;
}
.m-scene.is-exiting .scene_element {
animation-direction: alternate-reverse;
}
/*
* Keyframes
*/
#keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
js:
;(function ($) {
'use strict';
var $body = $('html, body'), // Define jQuery collection
content = $('#main').smoothState({
onStart : {
duration: 250,
render: function () {
content.toggleAnimationClass('is-exiting');
// Scroll user to the top
$body.animate({ 'scrollTop': 0 });
}
}
}).data('smoothState');
})(jQuery);
Thanks, in advance!
I'm building a simple navigation menu with four links. The menu has a greyscaled background image sliced into four parts that when hovered over will fade in a colored section of the background image, basically creating a saturation/desaturation effect on mouse over. The code im using works but only for one of the four slices. I need to figure out how to get each item to fade in separately. While messing with the code, ive been able to get either, one or all to fade in on hover, but can't figure out how to "break" them up.
$(document).ready(function () {
$('div.menu').hover(function() {
var fade = $('.one', this);
if (fade.is(':animated')) {
fade.stop().fadeTo(250, 1);
} else {
fade.fadeIn(250);
}
}, function () {
var fade = $('.one', this);
if (fade.is(':animated')) {
fade.stop().fadeTo(500, 0);
} else {
fade.fadeOut(500);
}
});
});
below are pics of whats happening
http://i.imgur.com/KZBlHxo.jpg
http://i.imgur.com/20iW8UM.jpg
Couldnt you do this using CSS? Here is a sample with transitions
.menu-item{
opacity:1;
transition: opacity .2s linear;
}
.menu-item:hover {
opacity:0;
}
Here is another with CSS animation
.menu-item:hover{
animation: fade;
-webkit-animation: fade;
}
#keyframes fade{
from{opacity:1;}
to {opacity:0;}
}
#-webkit-keyframes fade{
from{opacity:1;}
to {opacity:0;}
}
You can add delay parameters, timing, iteration count, etc.
http://www.w3schools.com/css/css3_animations.asp
I have an idea for my school project, and I've been searching online how to add this feature in css or java. I just want the title and whole menu to be hidden for around 5 or 6 seconds before appearing on the webpage. I was thinking of using a div to hide these, but I'm not 100% sure if that would work with a menu because of all of its content and links. Any advice or help is appreciated!
Here's a pure CSS example:
DEMO
<div class="content">
<div class="show-after-five">
<h1>Hey! I am here 5 seconds late</h1>
</div>
</div>
.show-after-five {
opacity: 0;
animation-name: fade-in;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.3s;
animation-delay: 3s;
animation-fill-mode: forwards;
-webkit-animation-name: fade-in;
-webkit-animation-iteration-count: infinte;
-webkit-animation-timing-function: ease-in;
-webkit-animation-duration: 0.5s;
-webkit-animation-delay: 5s;
-webkit-animation-fill-mode: forwards;
}
#keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-webkit-keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Let me know if you have any questions.
create a div with display:none style attribute, and put all your menu stuff in there that you want to hide:
<div id="mydiv" style="display:none">
...
</div>
then using jQuery on the bottom of your page:
<script>
setTimeout(function(){
$('#mydiv').fadeIn();
}, 5000);
</script>
This will execute the show method in 5000 milliseconds, or 5 seconds, and will have a nice fade in effect. This is all just based on what you described you wanted.
This is quite easy to do using Javascript (in particular, jQuery).
Place your menu on the DOM:
<div class="menu">Pretend this is a menu</div>
Set its display to none on page load:
.menu {
display: none;
}
Then set a timer when the document is ready to make it appear after 5 seconds:
$(document).ready(function() {
setTimeout(function (event) {
$('.menu').show();
}, 5000);
});
Demo: http://jsfiddle.net/3Grdd/
Yes, it's possible. And there are many ways to do so. Easiest would be jQuery mixed with CSS3.
CSS:
#target_ID{
display: none;
}
jQuery:
$(function() {
$("#target_id").delay(6000).show();
});
You can use the jQuery delay() function to accomplish this.
http://api.jquery.com/delay/
jQuery(document).ready(function ($) {
$('#menu').delay(500).removeClass('.hidden');
});
Instead of removeClass() you can use fadeIn() or any other jQuery transition function.
Some of the other answers suggest using display:none. I would be cautious because that will remove that content from the layout and potentially mess things up depending on how you have the site coded. If you have Jquery loaded, here is a way to do it.
CSS
.menu {opacity:0;}
.title {opacity:0;}
Javscript
setTimeout( function(){
$('.menu , .title').animate({ opacity:1 },3000);
}, 3000);
".menu" and ".title" are your containers. The first '3000' is the animation time of the fade in. The second '3000' is the delay. 3000 = 3 seconds. 5000 = 5 seconds, ect...