Fade out animation in pure CSS - css

Coming from https://stackoverflow.com/a/9334132/3779853: Let's assume a basic element that gets toggled programmatically. This could mean setting display to none/block or removing/inserting the element altogether.
$('#toggle').click(() => $('#square').toggle());
#square {
width: 50px;
height: 50px;
background: lightblue;
}
.animated {
animation: fade-in 1s;
}
#keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="toggle">toggle</button>
<div id="square" class="animated"></div>
With a simple animation, you can add a transition effect for when the element appears. How do you do the same thing for when the element disappears?
I do not want to add further classes, no :hover, and no more Javascript code. In many JS frameworks, you can show/hide elements easily: .toggle() (JQuery, as above), ng-if (AngularJS), *ngIf (Angular), conditional rendering (React), v-if (VueJS) and so on. With above solution, a simple class="animated" is enough to have it appear with custom animations. So I am looking for a pure CSS solution for fade out animation here, assuming this is a standard problem.

Here is a 100% pure css solution.
#square {
width: 50px;
height: 50px;
background: lightblue;
transition: opacity 1s ease-in-out;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition:opacity 1s ease-in-out;
}
#myBox:checked ~ .animated {
opacity: 0;
}
#myBox ~ .animated {
opacity: 1;
}
<input type="checkbox" id="myBox" style="display:none;"/>
<button id="toggle"><label for="myBox">toggle</label></button>
<div id="square" class="animated"></div>

You can use the opacity property with transition effect.
$('#toggle').click(() => $('#square').toggleClass('animated'));
#square {
width: 50px;
height: 50px;
background: lightblue;
transition: opacity 0.5s;
opacity: 1;
}
#square.animated {
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="toggle">toggle</button>
<div id="square" class="animated"></div>

Related

CSS Transition Delay When Fading-In, but No Delay when Fading Out

I am following a tutorial on how to create CSS tooltips. Everything works just fine, but there is one modification that I would like to make. I want the tool tip to show up 3 seconds after I hover over an item, but to fade out immediately when I stop hovering over the item. This is the (relevant) code I have right now:
.tooltip:hover .tooltip-text {
opacity: 0.7;
visibility: visible;
}
.tooltip-text {
...
opacity: 0;
transition: all 500ms;
transition-delay: 3s;
visibility: hidden;
...
}
This ALMOSTS works. It delays showing the tooltip for 3 seconds, like I want. However, it also delays removing the tooltip (which I do NOT want). How can I modify my code so that the tool tip fades in 3 seconds after I hover with my mouse and starts fading out immediately when I stop hovering?
Define transition properties in :hover class. Like this:
.tooltip:hover .tooltip-text {
opacity: 0.7;
visibility: visible;
transition: all 500ms;
transition-delay: 3s;
}
.tooltip-text {
opacity: 0;
visibility: hidden;
}
See working demo below. (Try hovering the red box)
.box {
width: 100px;
height: 30px;
background-color: red;
}
.tooltip {
opacity: 0;
visibility: hidden;
}
.box:hover .tooltip {
opacity: 1;
visibility: visible;
transition: all 500ms;
transition-delay: 2s;
}
<div class="box">
<div class="tooltip">
This is tooltip.
</div>
</div>

Disable a transition while an animation is running

Demo of the problem: https://jsfiddle.net/t0qsek8n/1/
<div class="test" id="test">Test text</div>
.test {
position: relative;
top: 0px;
border: 1px solid #ccc;
animation: test 5s;
transition: top 1s;
}
#keyframes test {
0% {
opacity: 0;
transition: none;
}
100% {
opacity: 1;
transition: none;
}
}
const test = document.getElementById('test');
setTimeout(() => {
test.style.top = "100px"
}, 1000);
I expect if the value of top property is changed by JS, transition transition: top 1000ms doesn't happen because of transition: none that provides #keyframes test, but actually, the transition happens.
I cannot understand why transition value from keyframes doesn't override any existing definition for transition.
let's take another example using display:
.test {
position: relative;
top: 0px;
border: 1px solid #ccc;
animation: test 5s forwards;
}
#keyframes test {
0% {
opacity: 0;
display: none;
}
100% {
opacity: 1;
display: none;
}
}
<div class="test" id="test">
Test text
</div>
We logically expect to never see the element since we set display:none and we made the animation to be forwards but display is simply ignored because it cannot be animated. Same logic with transition since it's a property that we cannot animate ref.
Basically, any property that cannot be animated will simply get ignored when used with keyframes.
Properties that aren't specified in every keyframe are interpolated if possible — properties that can't be interpolated are dropped from the animation. ref

:hover rotation CSS keep position on uncover

I am rotating an object with CSS upon hovering, and would like for it to remain in it's new position as you unhover it. I have searched around, but the only thing I could find is css :hover rotate element and keep the new position, which seems to go above and beyond.
Is this effect possible to achieve purely with CSS? I want the icon to remain at the 180 position once you stop hovering.
I used this code:
i.fa.fa-globe:hover {
color: #e9204f;
transition: 0.9s;
transform: rotatey(180deg);
}
Also it's a font-awesome icon if this makes any difference.
Edit - The easy CSS solution for everyone else who needs it (taken from the comments):
.lovernehovermarket i.fa.fa-rocket {
transform: rotate(0deg);
transition: transform 999s;
}
I had a circular icon that I wanted to rotate on every hover, not just the first, and not rotate when un-hovered.
Original
I saw this problem when I had CSS that looked like this
.icon {
transition: transform 0.5s;
}
.icon:hover {
transform: rotate(90deg);
}
Solution
The simple solution was to put the transition inside the :hover psuedo class
.icon:hover {
transition: transform 0.5s;
transform: rotate(90deg);
}
Boom, done!
This works because I was originally setting the transition to be 0.5s by default. In this case, that means both forward and backward. By putting the transition property inside the hover, I have a 0.5s transition when hover is activated, but a 0s transition (the default) when the icon is un-hovered. Having a 0s hover means it just instantly snaps back to position, invisibly to the viewer.
I you want a pure CSS solution, you can set a transtion time to go back to the base state quite high.
It's not for ever, but it's pretty close for most users:
.test {
display: inline-block;
margin: 10px;
background-color: tomato;
transform: rotate(0deg);
transition: transform 999s 999s;
}
.test:hover {
transform: rotate(90deg);
transition: transform 0.5s;
}
<div class="test">TEST</div>
You also need an initial transform state in the regular CSS of your element, so that it can transform between two defined states:
.rotate {
width: 20px;
height: 100px;
background: blue;
transition: 0.9s;
transform: rotate(0deg);
}
.rotate:hover {
transform: rotate(180deg);
}
body {
padding: 100px;
}
<div class="rotate"></div>
If you want to maintain the rotated state, you may have to use a little JQuery to check when the transition ends and change the class so it doesn't revert back to its original state on blur.
This way the div is rotated once and then its class is changed to maintain the rotated state.
$('.rotate').hover(function () {
$(this).addClass("animate");
$(this).one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',
function(e) {
$(this).removeClass('rotate').addClass('rotated');
});
});
.rotate {
width: 100px;
height: 100px;
background: gold;
transition-property: transform;
transition-duration: 1.5s;
transition-timing-function: linear;
}
.animate {
animation: rotate 1s linear;
transform: rotate(180deg);
animation-play-state: running;
}
.rotated
{
width: 100px;
height: 100px;
background: gold;
transform: rotate(180deg);
}
body {
padding: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rotate">some text</div>
Use an animation, and apply it using JS event listener, when the element is hovered (mouseover event). When the element is hovered for the 1st time, remove the event listener:
var rect = document.querySelector('.rectangle')
function rotate() {
this.classList.add('rotate');
rect.removeEventListener('mouseover', rotate);
}
rect.addEventListener('mouseover', rotate);
.rectangle {
width: 100px;
height: 100px;
background: gold;
}
.rotate {
animation: rotate 0.5s linear;
}
#keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg);
}
}
body {
padding: 30px;
}
<div class="rectangle"></div>
What worked for me was to put the transform not on hover but on the main css.
not:
#gear {
width: 3vh;
height: auto;
cursor: pointer;
&:hover {
transform: rotate(45deg);
transition: transform 200ms;
}
}
but
#gear {
width: 3vh;
height: auto;
cursor: pointer;
transition: transform 200ms;
&:hover {
transform: rotate(45deg);
}
}

Mouse hover delay, to show a child div

Using CSS transitions, I'd like to add a delay on hover, of 0.5s, in the class "activator".
After these 0.5s, it should change "content-l1" class from display:none to display:block
I've tried with this code, but doesn't work at all.
.content-l1 {
transition: 0s display;
}
.activator:hover>.content-l1 {
display: block;
transition-delay: 0.5s;
}
<div class="activator">
<div class="content-l1"> // initially: display:none whatever content here
</div>
</div>
display do not animation for transition. u can use opacity
.content-l1 {
transition: 0s;
opacity: 0;
}
.activator:hover>.content-l1 {
opacity: 1;
transition-delay: 0.5s;
}
<div class="activator">
fjhfjh
<div class="content-l1">
afsfas
</div>
</div>
but the block 'content-l1' takes place. we need use position
.activator {
position: relative;
}
.content-l1 {
position: absolute;
background-color: white;
padding: .4em;
border: 1px solid black;
transition: 0s;
opacity: 0;
}
.activator:hover>.content-l1 {
opacity: 1;
transition-delay: 0.5s;
}
<div class="activator">
fjhfjh
<div class="content-l1">
afsfas
</div>
</div>
qwewertrtw

Stop animation and start transition on hover

I have a link that's running an infinite animation with the background color. I want to stop the animation and transition into a different background color on hover.
.startlink{
background-color:#206a9e;
color:#fff;
border-radius:15px;
font-family: 'Myriad Pro';
-webkit-animation:changeColor 3.4s infinite;
-webkit-transition:all 0.2s ease-in;
}
.startlink:hover{
-webkit-animation-play-state: paused;
background-color: #014a2a;
}
#-webkit-keyframes changeColor
{
0% {background:#206a9e;}
50% {background:#012c4a;}
100% {background:#206a9e;}
}
Why is this code not working? And is there an alternate way to get this done? (preferably without Javascript).
Try -webkit-animation: 0;. Demo here. 0 is the default value for animation or what you must set to disable any existing CSS3 animations.
-webkit-animation-play-state: paused
and
-webkit-animation-play-state: running
Found another way round to achieve this.
Write another animation keyframe sequence and call it on your hover.
.startlink{
background-color:#206a9e;
color:#fff;
border-radius:15px;
font-family: 'Myriad Pro';
-webkit-animation:changeColor 3.4s infinite;
-webkit-transition:all 0.2s ease-in;
}
.startlink:hover{
-webkit-animation:hoverColor infinite;
}
#-webkit-keyframes changeColor
{
0% {background:#206a9e;}
50% {background:#012c4a;}
100% {background:#206a9e;}
}
#-webkit-keyframes hoverColor
{
background: #014a2a;
}
I was trying to achieve the same kind of thing and after trying to dynamically change keyframes and all, I found a weird solution by using basic css, see fiddle here. It is not very elegant but does exactly what I (and you, I hope) want.
#menu, #yellow{
position: fixed;
top: 2.5vw;
right: 2.5%;
height: 25px;
width: 25px;
border-radius: 30px;
}
#menu{
animation: blink 2s infinite;
transition: 1s;
}
#keyframes blink{
0% { background-color: grey; }
50% { background-color: black; }
100% { background-color: grey; }
}
#yellow{
background-color: rgba(255, 0, 0, 0);
transition: 1s;
}
#disque:hover #yellow{
pointer-events: none;
background-color: rgba(255, 0, 0, 1);
}
#disque:hover #menu{
opacity: 0;
}
<div id="disque">
<div id="menu"></div>
<div id="yellow"></div>
</div>
I have the same issue and the solution I found is the following.
Create the animation you want and for the element you and to each assign each one a different class.
Then use .mouseover() or .mouseenter() jQuery events toggle between the classes you assigned to each animation.
It is similar to what you use for a burger menu, just with a different handler.
For those who are interested by animation slide with stop between 2 images
var NumImg = 1; //Img Number to show
var MaxImg = 3; //How many Img in directory ( named 1.jpg,2.jpg ...)
function AnimFond() {
NumImg = NumImg> MaxImg ? 1 : NumImg +=1;
var MyImage = "http://startinbio.com/Lib/Images/Fond/" + NumImg + ".jpg";
$("#ImgFond1").attr("src", MyImage);
$("#ImgFond2").fadeOut(3000, function() {
$("#ImgFond2").attr("src", MyImage);
$("#ImgFond2").fadeIn(1);
});
}
setInterval("AnimFond()", 10000); //delay between 2 img
#AnimFond {
position: fixed;
height: 100%;
width: 100%;
margin: 0 0 0 -8;
}
#AnimFond img {
position: absolute;
left: 0;
height: 100%;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div id="AnimFond">
<img id="ImgFond1" src="http://startinbio.com/Lib/Images/Fond/1.jpg" />
<img id="ImgFond2" src="http://startinbio.com/Lib/Images/Fond/1.jpg" />
</div>

Resources