Changing css property from js breaks css animation - javascript

I have a button with hover effect on it (color changes).
button {
width: 180px;
height: 80px;
background-color: #A0522D;
}
button:hover {
background-color: #CD853F;
}
Then, from js I want to change background-color, for example when the button chosen is correct one. That is what I came up with:
buttons[i].style.backgroundColor = "#A0522D";
I also have transition property for animation:
button {
transition: background 0.5s ease, color 0.2s ease;
}
It appears that whenever I change background-color for the first time, it completely removes hover animation. That is not the case when I change font color, not background color, though.
Do you have any idea how to have both hover animation and js animation changing bgcolor working at the same time? Or could it be that my approach to animate buttons is not right?

This has to do with the specificity of your CSS rules. Rules set on the element (by setting the style property, for instance) will have higher specificity than those you declare in a CSS file/style block (unless you use !important).
The better approach would be to use classes to set the background property and to change those on the element instead of setting the style directly:
buttons[i].className = "myClass";
This StackOverflow answer has a great description of how to set CSS classes in javascript. You can read more details about CSS specificity in this article.

You could change the class with javascript.
$('#yourElem').click(function(){
$(this).toggleClass('on')
})
and then manage all your transitions with css
#yourElem { background-color:red; transition: background-color 500ms ease; }
#yourElem.on { background-color:blue; }
This will transition the two on click.
Then so long as you dont out specify the hover element with the new transition you can do both.
#yourElem { color:black; background-color:red; transition: background-color 500ms ease, color 500ms ease; }
#yourElem:hover { color:pink; }
#yourElem.on {color:white; background-color:blue; }

you can use jquery to change the css which might help ?
using on hover and the jquery colour library https://github.com/jquery/jquery-color
$('node').animate({ backgroundColor: "#f6f6f6" }, 'fast');

Related

Animate Javascript classList.toggle

I recently started to learn CSS and HTML and found this tutorial for a responsive navbar.
They show the mobile version of the navbar with the javascript function classList.toggle. Is there any way to animate this and add a transition?
function myFunction() {
document.getElementsByClassName("topnav")[0].classList.toggle("responsive");}
You can't animate the class attribute, but you can animate CSS properties.
You should have an initial CSS definition for your .topnav class, like this one:
.topnav {
background-color: black; /* Set an initial background */
transition: background-color 200ms; /* Tell browser to use a transition when background-color changed */
}
Thanks to this code, anytime the background-color of your .topnav element will change, a transition will occur.
You can for example add this CSS:
.topnav.responsive {
background-color: blue;
}
And this will work with your JS code.
Of course, my examples are basic and will just add a transition for the background-color, but it should help you about your problem :)

Keep a CSS property until the transition of the other ends

I use the after pseudo-element to simulate a gradient transition, but my gradients can be different, so I created a class for each one of them and applied them with JS when I needed them. Of course in the general ::after I specify transition: opacity 1s; and in each one of the gradient classes I have a background and opacity: 1;. Now I stumbled upon a problem, I need to reverse the transition, but that wasn't so easy, because (since I use JS), I am removing the class, which means that the opacity transition will of course still run, but the background gets deleted immediately. How can I keep the background until the opacity transition ends?
JSFiddle: http://jsfiddle.net/5c7xfwLw/
I updated your fiddle:
http://jsfiddle.net/5c7xfwLw/1/
Because you are fading out you don't need to remove the background, like this you can do simply the opacity animation.
.green:after {
background: -webkit-linear-gradient(#53FF40, transparent 50%);
}
.fade-after::after {
opacity: 1;
}

Why do jQuery's .fadeOut() and .fadeIn() stop working when a transition is applied in CSS

When I apply a transition on an element with CSS, jQuery's .fadeOut() and .fadeIn() stop working.
I have a Solution for this but, why does this happen?
Why do .fadeOut() and .fadeIn() work like .hide() ?
Where have the effects gone while there is a css transition being applied?
When I have to apply any jQuery animation, I always remove the transition and then apply jQuery animation and then add the transition back!
Is there any other trick to do this? Or is this the only way?
cloned.css('transition', 'none');
cloned.fadeOut();
setTimeout(function(){
cloned.css('transition', 'all 500ms cubic-bezier(0.5, 0.1, 0.7, 1.5)');
});
fadeOut and fadeIn will work with transitions, so long as you are not setting the transition to effect changes in opacity.
Working Example
$('.div1').click(function () {
if ($('.div2').is(':visible')) {
$('.div2').fadeOut(3000);
$('.div2').css('height', '0px');
} else {
$('.div2').fadeIn(3000);
$('.div2').css('height', '400px');
}
});
.div1 {
height:20px;
width: 200px;
background: blue;
}
.div2 {
display:none;
height:100px;
width: 200px;
background: red;
transition: background-color 3s, height 3s;
}
Here's why this works:
The .fadeOut() method animates the opacity of the matched elements.
Once the opacity reaches 0, the display style property is set to none,
so the element no longer affects the layout of the page.
From the API Documentation
So, basically both fadeOut and fadeIn animate the opacity of the element, if you set transition: all or transition: opacity you're trying to run two different animations on the same property at the same time.
To work around this you can simply specify which properties you want the css transition to apply to.
Rather than using this:
.some_element {
transition: all 1s;
}
Use this:
.some_element {
transition: height 1s, background-color 1s, some_other_property 2s;
}
JQuery .fadeOut()/.fadeIn() will not work with Transition. Because CSS Transition equivalent to them. As they are equivalent, always the last option will be in action. If you want both try CSS animation property. This could help you-
http://jsfiddle.net/webdevron/9a79L/
Again if you want to use a jQuery function then write as bellow:
cloned.css('transition', 'none');
cloned.fadeOut( "slow", function() {
// Animation complete.
});

Javascript / CSS - fading in an image which doesn't appear?

When my webpage loads, I want there to be links. Once all the links are clicked, I want an image to fade in on the bottom of the page (the image says 'complete' which basically means the user has completed clicking all the links). I first hide the image when the webpage loads, like so;
<html>
<body>
<!-- links which need to be clicked go here -->
<img id='complete' src='../images/complete.png' alt='' />
</body>
</html>
<style>
#complete {
visibility: hidden;
}
</style>
<script>
// once all links are clicked
$('#complete').fadeIn();
</script>
With this code, #complete does not fade in (probably because visiblity is set to hidden). I tried making visiblity set to visible right before the fade in command but that still didn't make it fade in. I also tried making the css
#complete {
filter: alpha(opacity = 0);
}
and the script
$('#complete').fadeTo('slow', '100');
and that doesn't work, #complete just appears really fast rather than fading in slowly.
I am using IE8 with CSS, any idea on how to fix this?
on css
#complete {
display: none;
}
and on javascript
$('#complete').fadeIn();
And try to use latest jquery
<body>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
</body>
See it on action: http://jsfiddle.net/KUqJL/ your problem is what I said about css
#complete {
visibility: hidden;
} replace with: display:none
Change your css to:
#complete {
display:none;
}
and if you'd like to use .fadeTo(), the second parameter must be an integer between 0 and 1.
$('#complete').fadeTo("slow", 1);
"slow" could also be replaced with a millisecond value such as 3000 (3 seconds), for an even slower fade.
$('#complete').fadeTo(3000, 1);
Here is a fiddle that may help.
visibility cannot be animated. Something is either visible or hidden, there are no middle stages.
But you can achieve this effect by using opacity instead of visibility, since visible elements have an opacity between 0 and 1.
#complete {
visibility: visible; /* this is the default so this line is not required */
opacity: 0;
}
And use the .animate() method.
$('#complete').animate({
opacity: 1.0
}, 'slow');
jQuery has methods like .fadeIn() .fadeTo() and .fadeOut() which animates opacity with the addition of setting the display property to none on 0 opacity and vica-versa when animating.
Since display: none not only makes elements invisible, but collapses them (width and height are 0 and the element is not part of the layout), I think the opacity property is more suitable for you.
This can also be done with CSS transitions:
#complete {
opacity: 0;
-moz-transition: opacity 0.8s linear;
-o-transition: opacity 0.8s linear;
-webkit-transition: opacity 0.8s linear;
transition: opacity 0.8s linear;
}
#complete.fadedIn {
opacity: 1;
}
And the JavaScript than changes to:
$('#complete').addClass('fadedIn');

Slide + fade effect using CSS transitions

I'm trying to replicate this effect using CSS effects or transitions.
Using animations I can animate the opacity, but only fadeIn, and the height (which should control the slide) doesn't seem to work at all :(
The closest I've got is by using javascript to set a temporary class on the element I want to animate, and on which I apply the initial opacity. But height doesn't work either. And there seems to be a slight delay on animation start.
Any other ideas?
So I ended up using the solution posted in the question Simon mentioned: With javascript I wrap the element I want to animate within a "wrapper" DIV on which I apply the animation. The wrapper will get its height changed from 0 to the height of the content DIV every time the label is clicked:
fiddle here
I know it requires some javascript, but the idea is to make the animation in CSS, and this is what it does. And if JS is disabled, the toggle will still work...
You can't currently animate on height when one of the heights involved is auto, you have to set two explicit heights. There's an extensive workaround posted as an answer to this similar question.
I made an alteration to your JS Fiddle, I beleive this is what you want; please see it here.
You need to specify a height on the div originally (0) and don't forget overflow:hidden; so that the content doesn't 'spil out' of the div. You will still need jQuery / Javascript however, to toggle a class but it means much less Javascript is required. (I toggled the class "change" which you will see on that fiddle)
input {
display:none;
}
label {
display:inline-block;
}
div {
white-space: pre;
background: #eee;
color: #333;
overflow:hidden;
height:0;
opacity:0;
-moz-transition:height 1s opacity 1s;
-webkit-transition:height 1s opacity 1s;
-o-transition:height 1s opacity 1s;
-ms-transition:height 1s opacity 1s;
transition:height 1s, opacity 1s;
}
.changed {
height:200px;
opacity: 1;
}
I added a few vendor prefixes to the transition CSS propery as I'm not sure what browser you'll be using and I'm on firefox so I need the -moz- prefix lol :)
The only problem I can see with this is that height:auto or height:100% doesn't animate, so you'll need to specify ems or px... If this is going to be a problem (like if the content will be dynamic), I would advise using jQuery for the height animation.

Categories