Conditional rendering animation effect - css

I have a tab component where the user can switch between brand and model. Is it possible to add a smoothing or an effect when changing the component that is being shown? I'm finding it too dry, with no effect, when the user changes the tab.
code:
https://codesandbox.io/s/empty-darkness-bfijv?file=/src/App.js&fbclid=IwAR2diVKlb4fGrkjCmnR8Lq5IaPAB9GiiVrL5Vepz_LLNlNXAO-_gL1-NVNg

You could add a css keyframes animation to your data.
To do that, give your div that wraps your data a className. I named it className="data".
Then in your css:
.data {
animation: fadeIn 0.5s;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
https://codesandbox.io/s/interesting-pateu-bbsld?file=/src/styles.css:396-411

Related

CSS: define animations inline without a separate `keyframes` class

Generally you would define a onHover animation of a square class like this:
.square:hover {
animation-duration: 0.5s;
animation-name: square_hover;
}
#keyframes square_hover {
to {background-color: yellow;}
}
Is there a way to define it like this:
.square:hover {
animation-duration: 0.5s;
animation: {
to { background-color: yellow; }
};
}
#keyframes square_hover
?
According to MDN the correct way of declaring an animation is using this syntax:
#keyframes <keyframes-name> {
<keyframe-block-list>
}
And then call it back using animation properties:
animation-duration: time;
animation-name: animation;
Where you will is a string that will identify the animation name. And is the sequence you will follow to create the animation.
So in short, CSS has a strict syntax you have to follow. But it seems like you're trying to find a simpler way to declare/create animation on hover.
You can simply get rid of the animation and directly add the properties you want to change on hover. For instance, if you want to change the background colour of the square class you will simply start with the initial state/base styles:
.square {
background-color: black;
}
And then apply the styles you want to change:
.square:hover {
background-color: yellow;
}
And if you want smooth out the transition simply add the transition property to the base styles. And the syntax looks something like
transition: property-to-transition time ease;
A working example:
.square {
background-color: black;
transition: background-color .5s ease;
}
References:
MDN Docs #keyframes: #keyframes
MDN Docs transitions: transitions
MDN Docs animations: animations

CSS FadeIn and FadeOut trigerred by onclick with only css (100% pure) if not possible less resources as possible (no jquery, and no js to animation)

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.

How can I animate my less from "display: block" to "display: none"?

I have a less file that hide and display an element like the following:
.cmp-accordion__panel {
&--hidden {
display: none;
}
&--expanded {
display: block;
-webkit-animation: slide-down 0.5s ease-out;
-moz-animation: slide-down 0.5s ease-out;
}
}
#-webkit-keyframes slide-down {
0% {
opacity: 0;
-webkit-transform: translateY(-5%);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
}
}
#-moz-keyframes slide-down {
0% {
opacity: 0;
-moz-transform: translateY(-5%);
}
100% {
opacity: 1;
-moz-transform: translateY(0);
}
}
In my JavaScript, I toggle the class name of the element between "cmp-accordion__panel--hidden" and "cmp-accordion__panel--expanded" if the event is triggered. I use keyframe and opacity to animate the transition from "display:none" to "display:block".
However, when I go from "display:block" to "display:none" to hide the element, the effect happens INSTANTLY. What should I add to animate the hiding?
As already said, is not possible animate or transition from display:block; to display: none; but this could be simulated in another way and is not necessary to use CSS animations, simply CSS transitions (in addition, is not necessary anymore to use vendor-prefixes to declare transitions or animations).
Please, look at this working example:
HTML (I inserted a fake content to create an element with a relative big height)
<div class="cmp-accordion__panel--expanded">
b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b<br>b
</div>
LESS
[class*="cmp-accordion__panel"] {
border:solid 1px red;
overflow:hidden;
transition:opacity 0.3s ease-out, max-height 0.8s ease-out;
}
.cmp-accordion__panel {
&--hidden {
max-height:0;
opacity:0;
}
&--expanded {
opacity:1;
max-height:1000px;
}
}
Please note that, thanks to attribute partial value selector I added also some rules that apply to both *--hidden and *--expanded classes (I personally prefer a general class and an addition of a second one in some cases, instead of switching between two, but I did not want to change too much your approach).
The key rule is switching between two values of max-height property, from a 0 value to another "enough big" one. If you effectively know final height of the element you can simply use also height property, but in case of dynamic content, max-height did the trick.
Please note also the presence of overflow:hidden; applied to both classes, to simulate height changes.
Finally, animation effect relies only on a CSS transition applied to opacity and max-height properties, with different timings to enhance effect.
You cannot animate or transition from display: block; to display: none;, so you will need to remove this if you wish to animate it.
To ensure it fades and is removed you should animate the visibilty and opacity attributes.
Alternatively if you are using jQuery you can use the .fadeOut() function.
MDN - CSS Visibility
jQuery - fadeOut()

Combine multiple animations

I'm trying to combine several parts of animation together by clicking a button. Here's an example:
.element {
background-color: black;
display: block;
width: 160px;
height: 160px;
border-radius: 80%;
}
.one {
animation: one 1.5s ease 1 forwards;
}
.two {
animation: two 1s forwards;
}
#keyframes one {
from {
transform: scale(0.25);
opacity: 0;
}
25% {
opacity: 0.5;
}
to {
transform: scale(1);
opacity: 0.5;
}
}
#keyframes two {
from {
opacity: 0.5;
}
to {
opacity: 0;
}
}
I'm trying to combine these two animation: one and two. My way of doing this was to use JS: classList.add('.two') when I clicked the button. But the problem was: at the moment I added the class, the element changed to its default opacity which was 1.
To solve this, I added a new class contained styles which were actually clones of final styles of the first animation. And after the second part was finished, I had to remove the class list to prepared for the first animation to be played.
So my question is, is there a better way of doing this?
Here is a CodePen Demo
I just realised a problem with this: If I start the second animation before the first one was finished, there would be a discontinuity (the circle would just turns to a larger one all of a sudden).
The demo can be found from the above link, thanks!
Can I combine these two animations?
I assume by combine you mean producing forward (on click of add animation) and reverse (on click of remove animation) animations using the same keyframe rules. It's possible to achieve but for that both the forward and reverse animations should be exactly the same (but in opposite directions). When it is same, we can use animation-direction: reverse to achieve reverse effect with same keyframes.
Here, the forward animation has a transform change whereas the reverse doesn't and hence adding animation-direction: reverse would not produce the same effect as the original snippet. Moreover, coding it is not as easy as just adding a property also, a lot of work is needed like mentioned here.
What is the reason for the other two issues?
The reason for both the issues (that is, the element getting opacity: 1 immediately when the remove button is clicked and element getting full size when remove button is clicked while forward animation is still happening) are the same. When you remove the animation on an element (by removing the class) it immediately snaps to the size specified outside of the animation.
For the first case, the size is the one that is mentioned under .element (as .one is removed) and its opacity is default 1 because there is no opacity setting in it. For the second case, when the .one is removed and .two is added, the animation is removed and so the element's size is as specified in .element and the opacity is as specified in .two (because that is later in CSS file).
So what else is the alternate?
When both forward and reverse effects are required and the animation doesn't have any intermediate states (that is, there is only a start state and an end state) then it is better to use transitions instead of animations. The reason is because transitions automatically produce the reverse effect on removal of the class (unlike animations where the reverse animation needs to be written as a separate keyframe and added to the element).
Below is a sample snippet showing how you can achieve a similar effect using just one class without the need for writing keyframes.
var theBut = document.getElementById('butt');
var theBut2 = document.getElementById('butt2');
theBut.addEventListener('click', function a() {
document.querySelector('.element').classList.add('one');
});
theBut2.addEventListener('click', function b() {
document.querySelector('.element').classList.remove('one');
});
.element {
background-color: #d91e57;
display: block;
width: 160px;
height: 160px;
border-radius: 90%;
transform: scale(0.25);
opacity: 0;
transition: opacity 2s, transform .1s 2s;
}
.one {
transform: scale(1);
opacity: 0.5;
transition: all 2s;
}
<div class="element">
</div>
<button id="butt">add animation</button>
<button id='butt2'>remove animation</button>

CSS3 - Rotate Clockwise than Counter Clockwise

I have an HTML element defined like this:
<div id="myElement" class="rotated">></div>
<button onClick="toggle('myElement');">Toggle</button>
function toggle(eid) {
var el = document.getElementById(eid);
if (el) {
el.className += el.className ? 'rotate-clockwise' : 'rotate-counter-clockwise';
}
}
I then have my CSS defined like this:
.rotated {
transform: rotate(90deg);
}
#keyframes rotateClockwise { from { ? } to { ? } }
.rotate-clockwise {
animation rotateClockwise 0.1s linear;
}
#keyframes rotateCounterClockwise { from { ? } to { ? } }
.rotate-counter-clockwise {
animation rotateCounterClockwise 0.1s linear;
}
I'm not sure what to add for the from and to values of my keyframes. The fact that my element starts rotated by 90 degrees kind of throws me off. Am I on the correct track or way off?
Thanks!
Your element starts rotated because it has the .rotated class, which tells it to be rotated by 90deg.
I modified your example a little to make it more idiomatic.
var button = document.querySelector('button')
var el = document.querySelector('#myElement')
function toggle(event) {
el.classList.toggle('rotate-clockwise')
}
button.addEventListener('click', toggle, false)
.my-element {
display: inline-block;
transition: transform 0.1s linear;
}
.rotate-clockwise {
transform: rotate(90deg);
}
<div id="myElement" class="my-element">></div>
<button>Toggle</button>
In the javascript we first get our button and element so we can operate on it later (we use querySelector which is more modern and lets you use CSS selectors). Then we define your event handler, which simply toggles the rotate-clockwise CSS class on and off. Lastly we attach our toggle function as a click event handler to the button.
In CSS we tell my-element to be inline-block as to not stretch over the entire width of the window. Also, every change to transform should use a linear transition of 0.1s. Every time .rotate-clockwise gets added or removed the element rotates.
Hopefully this does what you want and helps you understand the problem better.

Resources