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

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()

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

Is there a way to granulary control the animation properties on a CSS element?

I have this code:
transition: all 0.35s;
transition-delay: 0.25s;
transition-timing-function: cubic-bezier(.79,0,.46,1);
But it turned out to be problematic if I add more properties that I wanna animate, so I'm looking to do something like:
transition: transform 0.35s/*duration*/ 0.25s /*delay*/ cubic-bezier(.79,0,.46,1),
opacity 0.25s/*duration*/ 1s /*delay*/ ease-in ;
I looked at the short-hand properties but can't quite find the right combo.
Yes, what you want is a css animation not a css transition. Transitions are for creating a smooth transition from one state to another while animations allow you to define more complex behavior by changing css properties.
It would look something like this:
element {
animation-name: yourAnimationName;
animation-timing-function: cubic-bezier(.79,0,.46,1);
animation-delay: 0.25s;
}
#keyframes yourAnimationName {
// here you define which css properties to animate
}
You can either define the keyframes using from and to:
#keyframes yourAnimationName {
from { background-color: red; }
to { background-color: yellow; }
}
or you can define multiple keyframes using percentages (at what percentage of the entire animation):
#keyframes example {
0% {background-color: red;}
25% {background-color: yellow;}
50% {background-color: blue;}
100% {background-color: green;}
}
You also probably wont need your cubic-bezier timing function if you use keyframes as percentages.
I recommend reading a bit about css animations HERE.

CSS: How to create this kind of Fade In Down animation

How to create this kind of css animation where element fades in from the bottom but appears like clipped with overflow:
http://fr.creasenso.com/ (see the breadcrumb text)
I've tried all the basics but not going anywhere with translateY. Do I need to go to libraries or is it achievable with css only?
The wording of your question could use some improvement. But besides that, I think this is what you are looking for:
https://jsfiddle.net/5ws33c8s/
You need a parent element which has a overflow: hidden. Followed by the childs which are moved out using translate: translateY().
I then used css keyframes to move it back in:
animation: fadeInText 300ms 0ms forwards;
#keyframes fadeInText {
from {
transform: translateY(30px);
opacity: 0;
} to {
transform: translateY(0);
opacity: 1;
}
}
This animation is set up as follows; fadeInText is the keyframes name, 300ms is the duration of the animation, 0ms is the delay of said animation and forwards remembers the final state of the animation, and leaves the element as such. Without it, the element would jump back to its original values.
I then used a delay on each child element.
span:nth-child(2) {
animation-delay: 150ms;
}

How do you make transparent elements non-interactable?

I'm showing and hiding elements with a fade in / fade out effect.
CSS
.element {
opacity: 1.0;
transition: opacity 0.3s linear;
}
.element.hidden {
opacity: 0.0;
}
JS
// hide
$('someElement').addClassName('hidden');
// show
$('someElement').removeClassName('hidden');
The problem with this is that an invisible element still occupies space. If the user tries to click something beneath it, this invisible element intercepts the click and the user gets confused. Is there a CSS property that will make the element non-interactable? I'm aware there are some hacks like setting top:-999em in the .hidden class, but I'm asking if you know any elegant solutions.
You will need to transition visibility as well:
.element {
opacity: 1.0;
visibility: visible;
transition: opacity 0.3s linear, visibility 0.3s linear;
}
.element.hidden {
opacity: 0.0;
visibility: hidden;
}
An element with visibility: hidden can be clicked through; i.e. it won't intercept the click.
If you need the element to disappear altogether rather than continue to occupy space, you need to use display: none instead, but that is not an animatable property so you'll see the element disappear abruptly rather than fade out.

How to keep css animation effect?

I have some slide animation in css. There is any chance to keep this effect?
#arch{
margin-top:5%;
width:222px;
height:222px;
background-image:url(img/arch.jpg);
box-shadow:0px 0px 3px #000000;
}
#arch:hover{
-webkit-animation:przesuniecie 1s 1 alternate;
}
#-webkit-keyframes przesuniecie
{
from {width:222px;}
to {width:0px;}
}
I'm guessing you mean to have to the element slide away on hover, and slide out when the mouse leaves? I suggest putting the :hover on the parent element:
*:hover > #arch{
-webkit-animation:przesuniecie 1s 1 alternate;
}
#-webkit-keyframes przesuniecie
{
from {width:222px;}
to {width:0px;}
}
Depending on what the parent element is, you may need to wrap the #arch element in a <div>.
Also, you may need to use CSS transitions instead of CSS animations, so that the animation doesn't abruptly end on mouseout:
#arch{
-webkit-transition:width 1s;
width: 220px;
}
*:hover > #arch{
width: 0;
}
(Don't forget to include the other variations of the property for the other browsers)
Remove the :hover event and let it sit.

Resources