Keep a CSS property until the transition of the other ends - javascript

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;
}

Related

Intense GPU usage for animations playing over blurred background

Considering this paragraph from calibreapp.com:
Browsers make optimizations by creating separate layers for elements
with CSS transitions or animations on Position, Scale, Rotation and
Opacity. When you have an animated element on its own layer, moving it
around doesn’t affect the positions of surrounding elements, the only
thing that moves is that layer. This way the browser avoids repaints
and does only compositing.
Now imagine we want to blur the whole background, the blur animation starts progresses and finally it finishes, ok?
Now on this blurred background we want to add a simple scale animation like this: (note that this is a separate div with no connection with background we already blurred)
.beaton {
animation: beatonAnime .5s infinite alternate;
}
#keyframes beatonAnime {
0% { transform: scale(1); }
100% { transform: scale(0.96); }
}
The confusing issue is:
Without that blurred background I get 1-2% GPU usage.
With that blurred background (which is not animating now and has finished seconds ago) I get 68% GPU usage!!!
As the paragraph said we should not see any difference between theses two as the blurred animation of background is not running when we add the scaling animation and they are in separate layers.
Here is the link to live example: (Note the GPU not CPU usage)
https://langfox.ir/test/beat/index.html
By the way this is the blur animation on the background:
.overlay {
animation: overlayShow 0.25s ease-in-out;
animation-fill-mode: forwards;
}
#keyframes overlayShow {
from {
backdrop-filter: blur(0);
background-color: rgba(35, 33, 36, 0);
}
to {
backdrop-filter: blur(80px);
background-color: rgba(35, 33, 36, 0.7);
}
}
Is there any solution for this?
NOTE: There is no such issue when I use filter: blur(80px) instead of backdrop-filter: blur(80px);. So what's wrong with backdrop-filter?
i get the same problem when play an animation above a blurred overlay.My final solution is to get a static blur image,it's formate cant be .png and shoule be .jpg.Then i set the overlay css property as 'background-image:url('../xxx.jpg)'.Since the background of the overlay is static,it wont take a lot gpu resource.Its a silly solution.

Disable JQuery automatic animation

Sometimes when using JQuery to set the css attribute of an element such as "height", "max-height", it automatically binds animation to the change. Sometimes it is awesome, but it is not always necessary. Is there a way to disable this kind of animation?
Actually what is the exact situation that causes JQuery to automatically bind animations? because I don't always see this kind of behavior. I am not using JQuery-UI.
Perhaps the element you are changing the height of has a css transition property that is responsibe for the animation.
$(function() {
$('.myClass').css('width', '100px');
});
.myClass {
height: 50px;
width: 300px;
background-color: red;
}
.transition {
transition: width 3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
with transition
<div class="myClass transition">
</div>
without transition
<div class="myClass">
</div>
Borrowing from What is the cleanest way to disable CSS transition effects temporarily?
You can then create a class that will override the transition property and toggle that class
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
-ms-transition: none !important;
transition: none !important;
}
Note
If you go this route, you may run into the issue of needing to reflow the css
From What is the cleanest way to disable CSS transition effects temporarily? once again:
There are various ways to do this - see here for some. The closest
thing there is to a 'standard' way of doing this is to read the
offsetHeight property of the element.
One solution that actually works, then, is
$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS
changes $someElement.removeClass('notransition'); // Re-enable
transitions
You can use jQuery.fx.off parameter to define if animation should be used. Read about it here
Also you can modify css values directly without modifying function like
$("#id").css('height', '100px');
instead of
$("#id").height(100);

jQuery resizing menu bar on scroll with changing image

http://www.webdesignerdepot.com/2013/03/how-to-create-a-resizing-menu-bar/ is a fairly simple and typical, easy to use resizing menu bar. The image scales down as well, but how can I make the image swap completely with a transition? This (JS/jQuery swap image on scroll event) is a very simple solution to swap the image, yes, but fade in/out transitions seem much harder to put in place when scrolling down and back up.
You can use css transitions to transition the opacity with classes.
.visible {
transition: .3s opacity;
opacity: 1;
}
.hidden {
opacity: 0;
}
just have the first image as .visible and the second image as .visible.hidden
Then as the menu transitions swap the classes so the first image has .visible.hidden and the second image has only .visible
You can tweak the timings to create a nice looking crossfade.

Changing css property from js breaks css animation

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');

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