CSSTransition Component - html

I want to animate (fade-in) a div at or after the initial mounting of a component. After the animation is done, the div shouldn't disappear. I am trying to use CSSTransition component and looking examples on reactcommunity.org but I couldn't achieve any animation at all. I don't have any value that comes from somewhere for in, so I tried both trueand false but nothing changed.
CSS
.example-enter {
opacity: 0;
}
.example-enter-active {
opacity: 1;
transition: opacity 300ms;
}
.example-exit {
opacity: 1;
}
.example-exit-active {
opacity: 0;
transition: opacity 300ms;
}
React
<CSSTransition classNames='example' in={false} timeout={200}>
<div
className='abc'
data-description="abc">
<div className='inner'>
<div className='head'>A</div>
<div className='explanation'>A</div>
</div>
</div>
</CSSTransition>

If you want to transition on the first mount set appear to true: Transition-prop-appear
You can try this:
<CSSTransition
in={true}
timeout={1000}
classNames="fade"
appear={true}
>
<div className="box" />
</CSSTransition>
Css:
.fade-appear {
opacity: 0;
transform: scale(0.2);
}
.fade-appear-active {
opacity: 1;
transform: scale(1);
transition: all 1000ms;
}
.box {
width: 50px;
height: 50px;
background: aqua;
}
See my code detail here: https://codesandbox.io/s/csstransition-component-okpue

Another easy way is to use CSS animations. no need to set extra class for your element.
Just use it in your desired element's CSS code :
Thanks to animate.css plugin for CSS, take a look at it:
https://daneden.github.io/animate.css/
the example:
#-webkit-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.elem {
padding: 40px 30px;
background: #aaa;
animation: fadeIn 2s;
}
<div class="elem">
Hello, this is a text
</div>

Related

Is there a way to fade two div elements into one another in CSS?

If I have two div elements that contain some text and I want them into one another such that as one disappears the other appears and it then repeats how do i go about doing this? I'm not sure where to where to start.
<div id="body">
<div>My great adventure</div>
<div>Travel, adventure, leisure</div>
</div>
Using CSS animations we can achieve this pretty simply.
We will create 2 animations. One that causes the text to fade in initially, and one to cause the text to fade out initially. We will set these animations to loop forever.
You can fine tune the timings and opacity levels to your needs.
.fade {
position: absolute;
}
#start {
opacity: 1;
animation-name: fadeStart;
animation-duration: 4s;
animation-iteration-count: infinite;
}
#end {
opacity: 0;
animation-name: fadeEnd;
animation-duration: 4s;
animation-iteration-count: infinite;
}
#keyframes fadeStart {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes fadeEnd {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<div id="container">
<div class="fade" id="start">My great adventure</div>
<div class="fade" id="end">Travel, adventure, leisure</div>
</div>
If you are just talking about non-animated, static elements visually fading into one another, you can use a linear-gradient for the background of ::before and ::after pseudo-elements.
Below is a pure CSS example making use of CSS variables for consistent colors and sizing. The ::before and ::after pseudo-elements fade from the background color to transparent. You can increase the multiplier in margin on the #body > div to decrease the amount of overlap.
body {
--div-bg: orange;
--fade-height: 3rem;
background: white;
}
#body>div {
position: relative;
color: black;
background: var(--div-bg);
padding: 1rem;
margin: calc(var(--fade-height) * 1) 0 0;
}
#body>div::before,
#body>div::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: var(--fade-height);
}
#body>div::after {
bottom: calc(var(--fade-height) * -1);
background: linear-gradient(to bottom, var(--div-bg), transparent);
}
#body>div::before {
top: calc(var(--fade-height) * -1);
background: linear-gradient(to top, var(--div-bg), transparent);
}
<div id="body">
<div>My great adventure</div>
<div style="--div-bg: #33F;">Travel, adventure, leisure</div>
</div>

Delay the toggleClass action

I have a tab and once I click it the tab fades in. The content gets loaded in with AJAX. After the animation is done I want to load in the content. Right now the content is loading in immediately when I click the button. I tried toggleClass with delay but it didn't work.
How can I delay the content from being loaded in?
This is the HTML :
$("#button-1").on("click", function() {
$(".hidden-content-1", 2000).toggleClass("show-hidden-content", 2000);
$(".main-page-content-1", 2000).toggleClass("hide-shown-content", 2000);
})
#modal-1 {
width: 33.33%;
height: 100vh;
background-color: green;
left: 0;
top: 0;
}
.modals {
transition-timing-function: ease-out;
transition-duration: 1000ms;
position: absolute;
}
.active {
width: 100vw !important;
height: 100vh !important;
}
.show-hidden-content {
display: block !important;
}
.hidden-content-1 {
display: none;
}
.hide-shown-content {
display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="modal-1" class="modals">
<div class="hidden-content-1">
<h1> TEST </h1>
</div>
<div class="main-page-content-1">
<h1>TEST </h1>
</div>
<a id="button-1" href="template-parts/panel1.php"><input onclick="change1()" type="button" value="See More" id="button-text-1"></input>
</a>
</div>
It seems you are looking something like:
$('#button-1').on('click', function () {
setTimeout(() => {
$('.hidden-content-1').toggleClass('show-hidden-content');
$('.main-page-content-1').toggleClass('hide-shown-content');
}, 2000);
});
You might want to use animation-delay
#target {
animation: fade-in 250ms ease-out 1s 1 normal both running;
}
#keyframes fade-in {
0% {
opacity:0;
} 100% {
opacity:1;
}
}

How to fade html element out and the fade new element in it's place

I have a number of questions:
<div id='q1'>question...</div>
<div id='q2'>question...</div>
<div id='q3'>question...</div>
etc...
Only one question div should be visible at any time.
I want each question to fade out and the new question fade in exactly where the previous question was.
I am using this CSS for the fade transitions:
.fade-out {
opacity: 0;
animation-name: fadeOutOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-out;
animation-duration: 1s;
}
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 2s;
transition-delay: 4s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes fadeOutOpacity {
0% {
opacity:1;
}
100% {
opacity:0;
}
}
But when the second question has the fade-in css class applied, it makes the first question jump up before it's faded out.
Ideally, I'd like the first question to fade out and the become display: none;
But I am struggling to get it to work.
Questions
How can I get the first question to 'fade-out' and the second 'fade-in' in it's place?
N.B I'd rather a pure CSS solution than a Jquery solution if possible...
Like in most pure CSS solutions you might want to utilize input elements. Here I am using radio types with labels inside to reach the next question.
As you are only changing opacity you might want to use a transition instead of an animation. I am using the shorthand here which can be expanded like this:
transition: property-name duration easing delay;
Here is a working example:
/* wrapper to hold absolute positioned children */
.wrapper {
position: relative;
}
/* hide actual radio buttons */
.wrapper input {
display: none
}
.question {
/* float above each other */
position: absolute;
/* transparency by default */
opacity: 0;
/* fade out without delay */
transition: opacity 1s ease-out;
}
input:checked + .question {
/* always put current question first */
z-index: 1;
/* fade in with delay */
opacity: 1;
transition: opacity 2s ease-in 1s;
}
<div class="wrapper">
<input id="question-1" type="radio" name="question" checked>
<div class="question">
<p>Question 1</p>
<label for="question-2">next</label>
</div>
<input id="question-2" type="radio" name="question">
<div class="question">
<p>Question 2</p>
<label for="question-3">next</label>
</div>
<input id="question-3" type="radio" name="question">
<div class="question">
<p>Question 3</p>
<label for="question-1">start over</label>
</div>
</div>
You can do it easily without needing an animation Instead you only need transition.
Run this code snippet example:
function doNext() {
let el = document.querySelector('.questions [showing]');
el.removeAttribute('showing');
let temp = el.nextElementSibling;
if (temp === null) {
temp = el.parentElement.firstElementChild;
}
temp.setAttribute('showing', '');
}
const btn = document.querySelector('#next');
btn.addEventListener('click', doNext);
.questions {
height: 60px;
position: relative;
}
.fader {
left: 0;
opacity: 0;
position: absolute;
top: 0;
transition: all 1s ease;
}
.fader[showing] {
opacity: 1;
transition: all 1s ease 0.75s;
}
<div class="questions">
<div id='q1' class="fader" showing>question...1</div>
<div id='q2' class="fader">question...2</div>
<div id='q3' class="fader">question...3</div>
<div id='q4' class="fader">question...4</div>
</div>
<button id="next">Next</button>
When the attribute showing is removed then the opacity of the question goes from 1 to 0 over 1 seconds. When the attribute showing is added then the element waits for 0.75 seconds and then changes opacity from 0 to 1 over 1 seconds.
The JavaScript I have added simple allows the changing of which element has the attribute showing. Your code would need to do something similar to change which question is showing.
I set the position of each question to absolute with top set to 0 so that all questions show in the same place. BUT doing this requires that you know that maximum size of your questions so the container can be set to the correct height.
Try this sample:
.fade-out {
opacity: 0;
animation-name: fadeOutOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-out;
animation-duration: 2s;
height: 0;
width: 0;
}
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 4s;
animation-delay: 0s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes fadeOutOpacity {
0% {
opacity: 1;
height: auto;
width: auto;
}
100% {
opacity: 0;
}
}
<div id='q1' class="fade-out">question...1</div>
<div id='q2' class="fade-in">question...2</div>

Modifying the jm spinner dot to make it same size without the bounce

I'm using the jm spinner plugin on my site, but I want to change the bouncing dots from changing size (bouncing) when they show. They display as a 'bounce' that makes them look like they are growing in size. I just want them to stay the same size, but I've been playing with the .css file and the debugger and I can't figure out to make any changes!
Here is a code pen
On the site it says I can modify/style the spinner like
.spinner {
}
but I'm not sure what to put here.
It seems like I don't want the 'sk-bouncedelay' but not sure
Something like this? If so, you can forget about the plugin.
.spinner>div {
width: 13px;
height: 13px;
background-color: blue;
border-radius: 50%;
display: inline-block;
opacity: 0;
animation: showhide 1.4s infinite;
}
.spinner .dot1 {
animation-delay: -0.32s;
}
.spinner .dot2 {
animation-delay: -0.16s;
}
#keyframes showhide {
0%,
100% {
opacity: 0;
}
80% {
opacity: 1;
}
}
<div class="spinner">
<div class="dot1"></div>
<div class="dot2"></div>
<div class="dot3"></div>
</div>

Remove/Hide div from DOM after animation completes using CSS?

I have an animation where a div slides out the view, however when the animation is completed, the div just returns to its origin position in the view. How do I totally remove the div or hide it after the animation ends using just CSS?
Here is the markup:
<div class="container">
<div class="slide-box" id="slide-box""></div>
</div>
and the css:
.slide-box {
position: relative;
width: 100px;
height: 100px;
background-image: url(../pics/red.png);
background-position: center;
background-size: cover;
background-repeat: no-repeat;
animation: slide 5s linear 1;
}
#keyframes slide {
0% {
left: 0;
}
20% {
left: 20%;
}
40% {
left: 40%;
}
60% {
left: 60%;
}
80% {
left: 80%;
}
100% {
left: 100%;
overflow: hidden;
visibility: hidden;
}
}
I don't want it to fade out over the duration of the animation, i just want it to disappear once it hits 100% in the keyframe. Thanks ahead of time!
Use the animation-fill-mode option. Set it to forwards and the animation ends at it's final state and stay like that.
Altered based upon comments Set opacity fade to just last 1% of animation... simplified keyframes. Added a jquery option to literally remove the div from the DOM. CSS alone won't alter the markup, where jQuery will.
Although you can't animate the display property. If you want the div totally gone, after the opacity fades to zero, you can then add the display property to remove the div. If you don't wait for opacity to end, the div will just vanish without any transition.
/*
This jquery is added to really remove
the div. But it'll essentially be
VISUALLY gone at the end of the
animation. You can not use, or
delete the jquery, and you really
won't see any difference unless
you inspect the DOM after the animation.
This function is bound to animation
and will fire when animation ends.
No need to "guess" at timeout settings.
This REMOVES the div opposed to merely
setting it's style to display: none;
*/
$('.slide-box').bind('animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd', function(e) { $(this).remove(); });
.slide-box {
display: block;
position: relative;
left: 0%;
opacity: 1;
width: 100px;
height: 100px;
background: #a00;
animation: slide 1s 1 linear forwards;
/*
animation-name: slide;
animation-duration: 1s;
animation-iteration-count: 1;
animation-timing-function: linear;
animation-fill-mode: forwards;
*/
}
#keyframes slide {
0% {
left: 0%;
opacity: 1;
}
99% {
left: 99%;
opacity: 1;
}
100% {
left: 100%;
opacity: 0;
display: none;
}
}
#-webkit-keyframes slide {
0% {
left: 0%;
opacity: 1;
}
99% {
left: 99%;
opacity: 1;
}
100% {
left: 100%;
opacity: 0;
display: none;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="slide-box" id="slide-box"></div>
</div>
animation: slide 5s linear forwards;
at 100%
opacity: 0;
display: none;
Try this.
Working fiddle: https://jsfiddle.net/jbtfdjyy/1/
UPDATE: JS mani
var slideBox = document.getElementById('slide-box');
setTimeout(function(){
slideBox.style.display = 'none';
}, 5000);
Try this. https://jsfiddle.net/jbtfdjyy/2/
Add something at 99% or so to your keyframes, and set opacity to 1 in that. If you have opacity: 1 at the start, then it will stay that way until 99%. Only at 100% will it change.
It's not technically fired at 100%. If you want that, I'd recommend using some JavaScript here, but this will at least give the illusion you want.
#keyframes slide {
0% {
left: 0;
}
20% {
left: 20%;
}
40% {
left: 40%;
}
60% {
left: 60%;
}
80% {
left: 80%;
}
99% {
opacity: 1;
}
100% {
left: 100%;
overflow: hidden;
opacity: 0;
display: none;
visibility: hidden;
}
}
UPDATE:
As per your request, here is a JavaScript version. Keep in mind, there are endless ways to accomplish such a task. I am using vanilla JS (no jQuery, etc.), and using ES6 syntax.
What we do here is set a timeout, and at the end of that timeout I broadcast an event animation_end. That event listener will handle the end of the animation (in this case, it adds a class which will handle the fading out). This is much more granular than you need it to be, you could simply do the adding of the class within the setTimeout, but I think it is slightly better this way as you can abstract you can do other things with events such as animation start, etc.
Here is the fiddle: https://jsfiddle.net/vmyzyd6p/
HTML:
<div class="container">
<div class="slide-box" id="slide-box""></div>
</div>
CSS:
.slide-box {
position: relative;
width: 100px;
height: 100px;
background-color: blue;
animation: slide 3s linear 1;
-webkit-transition: opacity 2s ease-in-out;
-moz-transition: opacity 2s ease-in-out;
transition: opacity 2s ease-in-out;
}
.animationEnd {
opacity: 0;
}
#keyframes slide {
0% {
left: 0;
}
20% {
left: 20%;
}
40% {
left: 40%;
}
60% {
left: 60%;
}
80% {
left: 80%;
}
100% {
left: 100%;
}
}
JavaScript:
// Create a function that handles the `animation_end` event
const animationEnd = () => {
// Grab the slidebox element
let slideBox = document.getElementById('slide-box');
// Get the class of the slidebox element
let slideClass = slideBox.getAttribute('class');
// Add the animation end class appended to the previous class
slideBox.setAttribute('class', slideClass + ' animationEnd');
};
// Create the animation end event
let animationEndEvent = new Event('animation_end');
// Cross browser implementation of adding the event listener
if (document.addEventListener) {
document.addEventListener('animation_end', animationEnd, false);
} else {
document.attachEvent('animation_end', animationEnd);
}
// Set the timeout with the same duration as the animation.
setTimeout(() => {
// Broadcast the animation end event
document.dispatchEvent(animationEndEvent);
}, 3000);