CSS animation out after animation in - html

i have set animation in property on HTML element when it is displayed, i want same animation on reverse, when button is clicked it should hide with same animation.
how can i achieve that.
"Animation in" which is working:
.modal{
animation: myAnim 1s ease 0s 1 normal forwards;
}
#keyframes myAnim {
0% {
opacity: 0;
transform: translateX(-50px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
HTML:
<div id="myModal" class="modal fixed hidden z-1 w-full h-full bg-red-100 h-screen ">
<button id="myBtn" class=" p-2 bg-yellow-400 rounded m-4 absolute right-0 text-xs font-bold ">
HIDE/SHOW..
</button>
i am showing/hidding modal using JS. how can i hide modal with same animation.

Create two classes, one for making the modal appear and another for making it disappear,
Class for appearing
.modal-appr{
animation: appr 1s ease 0s 1 normal forwards;
}
#keyframes appr {
0% {
opacity: 0;
transform: translateX(-50px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
Class to make the modal disappear
.modal-disappr{
animation: disappr 1s ease 0s 1 normal forwards;
}
#keyframes disappr {
0% {
opacity: 1;
transform: translateX(0);
}
100% {
opacity: 0;
transform: translateX(-50px);
}
}
now just use Javascript to add this classes to the modal's classlist when the button toggles
const btn = document.querySelector('mybtn');
const modal = document.querySelector('#myModal');
btn.addEventListener ('click', function toggleClass () {
if(modal.classList.contains('appr')) {
modal.classList.add('disappr');
modal.classList.remove('appr');
} else {
modal.classList.add('appr');
modal.classList.remove('disappr');
}
})

You can achieve this by using toggle class and transition instead.
let btn = document.getElementById('model_btn');
let model = document.getElementById('model');
btn.addEventListener('click', function(){
model.classList.toggle('show');
})
/* Styling the markup */
#model{
width: 200px;
height: 100px;
background-color: yellow;
padding: 20px;
margin-bottom: 20px;
}
#model_btn{
border: none;
background-color: green;
padding: 10px;
color: white;
cursor: pointer;
}
/* Showing and hiding animation with transition */
#model{
position: relative;
visibility: none;
opacity: 0;
top: 0;
left: 0;
transform: translateX(-50px);
transition: all 1s ease;
}
#model.show{
visibility: visible;
opacity: 1;
transform: translateX(0px);
}
<div id="model">
Content
</div>
<button id="model_btn">Show/Hide Model</button>
Animation / Key-frame approach.
let btn = document.getElementById('model_btn');
let model = document.getElementById('model');
btn.addEventListener('click', function(){
model.classList.toggle('show');
})
/* Styling the markup */
#model{
width: 200px;
height: 100px;
background-color: yellow;
padding: 20px;
margin-bottom: 20px;
visibility: none;
opacity: 0;
transform: translateX(-50px);
}
#model_btn{
border: none;
background-color: green;
padding: 10px;
color: white;
cursor: pointer;
}
.show{
animation: myAnim 1s ease 0s 1 normal forwards;
}
#keyframes myAnim {
0% {
visibility: none;
opacity: 0;
transform: translateX(-50px);
}
100% {
visibility: visible;
opacity: 1;
transform: translateX(0);
}
}
<div id="model">
Content
</div>
<button id="model_btn">Show/Hide Model</button>

Related

Show Css animation when hover over mouse

I want to show an animation of drawing an angled and straight line and to show my text from left to right when hovering over a button and I am fairly new at this. also is there a way for my text to stay and not go away after animation finishes?
Here is my code, the code is a combination of other answers from stack overflow.
.skew {
position: relative;
margin: 100px;
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(-45deg);
animation: draw 0.5s linear;
animation-fill-mode: forwards;
}
.line {
position: absolute;
left: 100%;
top: 0;
content: '';
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(45deg);
animation: drawLine 0.7s linear;
animation-delay: 0.5s;
animation-fill-mode: forwards;
}
.showText {
animation: showText 2s;
position: relative;
top: -17px;
left: 15px;
opacity: 0;
}
#keyframes showText {
0% {
opacity: 0;
transform: translateX(-20px);
}
50% {
opacity: 0;
}
100% {
opacity: 1;
transform: translateX(0);
}
}
#keyframes draw {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
#keyframes drawLine {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
<div>
<button class="menubtn">hover over me</button>
</div>
<div class="skew">
<div class="line">
<div class="showText">menu item</div>
</div>
</div>
You need to add/toggle a class on the div.skew element with Javascript, and define animation rules on that class or children of elements with that class, like so:
var button = document.querySelector("button.menubtn"); //Select the button
var skewElement = document.querySelector("div.skew"); //Select the 'skew' element
button.onmouseover = function(){
skewElement.classList.toggle("startAnimation");
}
.skew {
position: relative;
margin: 100px;
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(-45deg);
}
.skew.startAnimation {
animation: draw 0.5s linear;
animation-fill-mode: forwards;
}
.line {
position: absolute;
left: 100%;
top: 0;
content: '';
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(45deg);
}
.startAnimation .line {
animation: drawLine 0.7s linear;
animation-delay: 0.5s;
animation-fill-mode: forwards;
}
.showText {
opacity: 0;
position: relative;
top: -17px;
left: 15px;
}
.startAnimation .showText {
animation: showText 2s;
animation-fill-mode: forwards;
}
#keyframes showText {
0% {
opacity: 0;
transform: translateX(-20px);
}
50% {
opacity: 0;
}
100% {
opacity: 1;
transform: translateX(0);
}
}
#keyframes draw {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
#keyframes drawLine {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
<div>
<button class="menubtn">hover over me</button>
</div>
<div class="skew">
<div class="line">
<div class="showText">menu item</div>
</div>
</div>
In order to have the text visible even after animation's end, you have to specify animation-fill-mode: forwards on .showText, like I have done in the snippet above.
To get the animation done on hovering, first we have to create an event for hovering for that particular element using javascript
Then call a function when that event is triggered , for you it will be displaying some animations
Just for simplicity , i just made a parent div for your entire animation elements , and not displaying initially
Later on hovering , we change the css display property of that parent element to block which will display all of your animated elements
Also to make sure your text stays after animation , there is an animation property called forwards which will keep your final animation state for the later time
var hvrbtn=document.getElementById("hvrbtn");
hvrbtn.onmouseover=()=>{
var anim=document.getElementById("anim");
anim.style.display="block";
};
.animated{
display:none;
}
.skew {
position: relative;
margin: 100px;
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(-45deg);
animation: draw 0.5s linear;
animation-fill-mode: forwards;
}
.line {
position: absolute;
left: 100%;
top: 0;
content: '';
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(45deg);
animation: drawLine 0.7s linear;
animation-delay: 0.5s;
animation-fill-mode: forwards;
}
.showText {
animation: showText 2s forwards;
position: relative;
top: -17px;
left: 15px;
opacity: 0;
}
#keyframes showText {
0% {
opacity: 0;
transform: translateX(-20px);
}
50% {
opacity: 0;
}
100% {
opacity: 1;
transform: translateX(0);
}
}
#keyframes draw {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
#keyframes drawLine {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
<div>
<button class="menubtn" id="hvrbtn">hover over me</button>
</div>
<div class="animated" id="anim">
<div class="skew">
<div class="line">
<div class="showText">menu item</div>
</div>
</div>
<div>

CSS animation effect on hovered image is not working

I’ve created an animation effect in CSS and it works fine on texts. I want to use it on a PNG image I have used as an icon, as well, but it doesn’t work.
.logo-box {
position: absolute;
top: 40px;
left: 40px;
}
.logo {
height: 35px;
}
.logo:hover {
animation: moveInRight 1.5s ease-out;
}
#keyframes moveInRight {
0% {
opacity: 0;
transform: translateX(100px);
}
80% {
transform: translateX(-10px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
<div class="logo-box">
<img class="logo" src="img/logo-white.png">
</div>
Instead of selecting the hovered .logo itself (which moves its position), target the wrapper that doesn’t move (.logo-box), then target the .logo for animation. Instead of
.logo:hover {
animation: moveInRight 1.5s ease-out;
}
use
.logo-box:hover .logo {
animation: moveInRight 1.5s ease-out;
}
Example:
.logo-box {
position: absolute;
top: 40px;
left: 40px;
}
.logo {
height: 35px;
}
.logo-box:hover .logo {
animation: moveInRight 1.5s ease-out;
}
#keyframes moveInRight {
0% {
opacity: 0;
transform: translateX(100px);
}
80% {
transform: translateX(-10px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
<div class="logo-box">
<img class="logo" src="img/logo-white.png">
</div>
You have to make the logo box bigger, in HTML you have to do that in body and check your image pawn / your css left
.logo-box {
position: absolute;
top: 40px;
left: 40px;
}
.logo {
height: 35px;
}
.logo:hover {
animation: moveInRight 1.5s ease-out;
}
#keyframes moveInRight {
0% {
opacity: 0;
transform: translateX(100px);
}
80% {
transform: translateX(-10px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
<div class="logo-box">
<img class="logo" src="img/logo-white.png">
</div>

How to create an animation from left to right or making a fade Angular 4

I want when the component is open to make an animation or to make a fade.
This is the code
This is the HTML
<div *ngIf="showMePartially" class="container">
<div class="body-container">
</div>
</div>
This is the CSS
.container {
position: fixed;
z-index: 1;
padding-top: 100px;
transition: opacity 0.5s ease-in;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
transition: 3s;
}
.body-container {
width: calc(100% - 73em);
position: relative;
left: 70em;
top: 7.5em;
background: white;
height: calc(100% - 18em);
border-radius: 4px;
padding-left: 11px;
transition: opacity 0.5s ease-in;
animation-direction: normal;
}
You can use css animation:
.body-container {
/* above styles */
animation: animation-name .3s ease-out forwards;
}
#keyframes animation-name {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
You can make your own animation inside of keyframes. This should work, because *ngIf will either remove element from dom, if condition is false, or append it into dom(this is when animation should work).
EDIT
For left to right animation you can do like:
#keyframes animation-name {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(0%);
}
}

Fixing animation loop in CSS loader

I have a loader animation in CSS. It rotates 4 divs in a circular fashion. The issue I'm having is that the 4th div (red) is shown initially with no fade in disrupting the flow of the animation (you may have to refresh to see).
What would be the best way to fix this so that the animation's loop is improved?
The Code (https://jsfiddle.net/bduaxvmp/):
.loader {
position: relative;
height: 50px;
width: 50%;
left: 45.5%
}
.loader .bullet {
position: absolute;
padding: 5px;
background: green;
animation: animIn 1s ease-in-out 0s infinite;
}
.loader .bullet:nth-child(1) {
animation-delay: 0.0s;
}
.loader .bullet:nth-child(2) {
animation-delay: 0.15s;
}
.loader .bullet:nth-child(3) {
animation-delay: 0.3s;
}
.loader .bullet:nth-child(4) {
animation-delay: 0.45s;
background: red;
}
#-webkit-keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
<div class="loader">
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
</div>
Solution:
Set the animation-fill-mode as backwards for the animation. Using this option for the fill mode will make the elements take the state as at the 0% frame during the animation-delay period and hence all the elements will be transparent and in their translated position till the animation actually kicks in.
.loader .bullet {
position: absolute;
padding: 5px;
background: green;
animation: animIn 1s ease-in-out 0s infinite backwards;
}
.loader {
position: relative;
height: 50px;
width: 50%;
left: 45.5%
}
.loader .bullet {
position: absolute;
padding: 5px;
background: green;
animation: animIn 1s ease-in-out 0s infinite backwards;
}
.loader .bullet:nth-child(1) {
animation-delay: 0.0s;
}
.loader .bullet:nth-child(2) {
animation-delay: 0.15s;
}
.loader .bullet:nth-child(3) {
animation-delay: 0.3s;
}
.loader .bullet:nth-child(4) {
animation-delay: 0.45s;
background: red;
}
#-webkit-keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
#keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
<div class="loader">
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
</div>
Alternately, you could set the same properties as the 0% frame to the element's default state also and avoid setting animation-fill-mode to backwards but I feel that it is a repetition that could be avoided for this case.
Reason:
The issue I'm having is that the 4th div (red) is shown initially with no fade
Note that the problem is not just the 4th div. Actually the problem is for all the div elements that have the animation delay. Visually only 4th div exhibits the problem because all are absolutely positioned and the 4th div appears on top of the rest due to it being later in the DOM.
If you set a different background color and a higher z-index to the 3rd or 2nd div, you'd see that the same problem happens for them also.
.loader {
position: relative;
height: 50px;
width: 50%;
left: 45.5%
}
.loader .bullet {
position: absolute;
padding: 5px;
background: green;
animation: animIn 1s ease-in-out 1s infinite;
}
.loader .bullet:nth-child(1) {
animation-delay: 0.0s;
}
.loader .bullet:nth-child(2) {
animation-delay: 0.15s;
/*background: blue;
z-index: 4 */
}
.loader .bullet:nth-child(3) {
animation-delay: 0.3s;
background: yellow;
z-index: 2;
}
.loader .bullet:nth-child(4) {
animation-delay: 0.45s;
/*background: red;*/
}
#-webkit-keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
#keyframes animIn {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
<div class="loader">
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
</div>
The reason this problem happens is because of the way in which animations work. Any animation will continue to hold its default state (specified outside of the animation) till the time the delay timer expires. Setting animation-fill-mode as backwards makes the animation take the state as at first applicable frame even during the delay period and thus avoids the issue.
From MDN:
backwards
The animation will apply the values defined in the first relevant keyframe as soon as it is applied to the target, and retain this during the animation-delay period.

CSS Animation not working properly in wow js

I have integrated the wow.js for my project and i have encountered a problem with animation.
The animation class which i used to animate the div is working only if i paste the css class from animate.css into my page as embedded style sheet and also the div is showing even if i give a delay in data-wow-delay="5s"and animation works properly after 5 sec. Plz help me if anyone knows why this is happening.
Here is my code..
HTML :
<div class="cssAnimation hidediv">
<div class="dial1 wow slideInLeft " data-wow-duration="2s" data-wow-delay="5s">
Anmation goes here 1
</div>
</div>
CSS :
<style type="text/css">
.dial1{
width:200px;
height: 100px;
display: block;
position: absolute;
background: #000;
color:#fff;
padding: 10px;
right: 0;
z-index: 9999;
}
.dial2{
width:200px;
height: 100px;
display: block;
position: absolute;
background: #000;
color:#fff;
padding: 10px;
right: 210px;
}
.hidediv{
-webkit-animation: hide 2s forwards;
-webkit-animation-iteration-count: 1;
-webkit-animation-delay: 5s;
animation: hide 2s forwards;
animation-iteration-count: 1;
animation-delay: 5s;
}
#-webkit-keyframes hide {
0% {
opacity: 1;
}
100% {
opacity: 0;
visibility:hidden;
display: none;
}
}
#keyframes hide {
0% {
opacity: 1;
}
100% {
opacity: 0;
visibility:hidden;
display: none;
}
}
.cssAnimation{
width:600px;
height: 300px;
position: absolute;
/* display: none; */
z-index: 9999;
}
#-webkit-keyframes slideInLeft {
0% {
opacity: 0;
-webkit-transform: translateX(-2000px);
transform: translateX(-2000px);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
#keyframes slideInLeft {
0% {
opacity: 0;
-webkit-transform: translateX(-2000px);
-ms-transform: translateX(-2000px);
transform: translateX(-2000px);
}
100% {
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
}
.slideInLeft {
-webkit-animation-name: slideInLeft;
animation-name: slideInLeft;
}
</style>
Your css needs to include the .animated class from animate.css, as that's what will be added by Wow.js (unless you specify another selector) when the element is in view, triggering your animations.