CSS transition to fade in image isn't working - css

Please can you help troubleshoot the transition in this CSS? My browser can see the code in the inspector but no transition is taking place. I have tried operating the transition on different properties including width and position but nothing works.
#header-image {
position: absolute;
top: 30px;
right: 30px;
background: transparent;
width: 250px;
margin-left: 10px;
opacity: 1;
transition: opacity 2s linear 1s;
}
I know I'm probably being thick so apologies in advance.

In order for the transition to work.. the property value should change. only then it will trigger the transition.
i.e) lets say #header-image initially has opacity: 0; width: 50px;.
but when you hover it you want to increase the opacity and width opacity: 1; width: 250px;
so your css will look like..
#header-image {
position: absolute;
top: 30px;
left: 30px;
background: blue;
width: 100px;
height: 100px;
margin-left: 10px;
animation: fadeIn 2s linear;
}
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div id="header-image"></div>
Then your transition will work. So basically transition will work only when there is a change in the value. But in your case you are setting the opacity:1 initially by default.
If you want to add this effect on page load then you have to use css animation or javascript. Below I have given an example snippet on how it can be achieved using css animation.
However if you are planning to use many animations then I recommend to use some popular libraries like Animista, Animate.css, wow.js

Related

Animating an Element so it changes from display:none with CSS

I have a menu system where that when a ‘menu’ button is clicked some simple javascript allows a mobile menu to be shown as a drop-down.
I would like to have it so this menu transitions / animates in, but the display: none property seems to not be animatable with CSS animations. I don’t really want to just use opacity: 0 because the mobile menu will then be in the document flow, and on desktop devices I don’t wish this to be the case.
Is there any CSS solution to this? When I use the Greensock animation library, it allows you to animate or change the ‘display’ property. I can’t seem to get this to work with CSS animations though?
I’ve created a simple pen where I’ve just used a single div that animates (to keep it simple I haven't included any JS click events etc with this).
As you can see I’ve commented out the display: none on both the CSS for the id#bluebox and on the #keyframes animation. If you un-comment these you can see the problem that is created.
https://codepen.io/emilychews/pen/xPWddZ
CSS
#bluebox {
margin-left: 0px;
margin-top: 0px;
width: 100px;
height: 100px;
background: blue;
animation: appear 1s ease-in forwards;
opacity: 0;
/* display: none; */
}
#keyframes appear {
0% {/*display: none;*/ opacity: 0}
1% {display: block; opacity: 0.1;}
100% {opacity: 1;}
}
HTML
<div id="bluebox"></div>
I solved this by adding a transform: scaleY(0) to the element, and then animated this with the element on opacity: 0 for the first 1% of the animation, so you couldn't see the element 'scale up' so to speak. I used scale instead of width and height because width and height properties don't animate very well in terms of achieving the 60fps smoothness.
CSS
#bluebox {
margin-left: 0px;
margin-top: 0px;
width: 100px;
height: 100px;
background: blue;
animation: appear 1s ease-in forwards;
opacity: 0;
transform: scaleY(0);
}
#keyframes appear {
0% {opacity: 0;}
1% {opacity: 0; transform: scaleY(1)}
100% {opacity: 1; transform: scaleY(1)}
}
In this case, since you're attempting to animate the element, I would say you should probably use width and height to your advantage instead.
Something like this could act as a substitute for display none. (Codepen)
#bluebox {
width: 0px;
height: 0px;
}
#keyframes appear {
0% {
width: 0px;
height: 0px;
}
100% {
width: 100px;
height: 100px;
}
}
The width or height could also be replaced with your end width/height to allow for a more natural animation, depending on your goal. I can update the Codepen to include an example of what I mean if you'd like.
Let me know if this is what you were aiming for!
Edit: Fixed the Codepen link

is the #keyframes animation needs external library

I'm new on css animation and I'm interested to know more about #keyframe animations.
When we use #keyframe, do I need to load an external library file for that?.
I did not get the expected result when i put it alone without adding an external library?
No external library is required for keyframes to work.
Below is the example of creating a marquee effect using pure CSS. Check the code snippet, it uses keyframes.
.marquee-parent {
position: relative;
width: 100%;
overflow: hidden;
height: 30px;
}
.marquee-child {
display: block;
width: 147px;
/* width of your text div */
height: 30px;
/* height of your text div */
position: absolute;
animation: marquee 5s linear infinite;
/* change 5s value to your desired speed */
}
.marquee-child:hover {
animation-play-state: paused;
cursor: pointer;
}
#keyframes marquee {
0% {
left: 100%;
}
100% {
left: -147px
/* same as your text width */
}
}
<div class="marquee-parent">
<div class="marquee-child">
Hover on me to stop
</div>
</div>
.

CSS Transition after animation ends

I have a css transition that moves an element on hover and an animation that rotates the element on hover too. There's a delay on the animation equal to the transition duration so that after it's transitioned to it's correct position, the animation starts. And it works nice, however, when we mouse off, the animation stops but it doesn't transition back down.
Is it possible to get it to transition back after we mouse off and the animation ends?
You can see an example here: http://codepen.io/jhealey5/pen/zvXBxM
Simplified code here:
div {
width: 200px;
height: 200px;
margin: 40px auto;
background-color: #b00;
position: relative;
&:hover {
span {
transform: translateY(-60px);
animation-name: rotate;
animation-duration: 1s;
animation-delay: .5s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
}
}
span {
position: absolute;
width: 20px;
height: 20px;
background-color: #fff;
bottom: 10px;
left: 0;
right: 0;
margin: auto;
transition: .5s;
}
#keyframes rotate {
from {
transform: translateY(-60px) rotate(0);
}
to {
transform: translateY(-60px) rotate(-90deg);
}
}
I have forked your project and adapted it so it works. You can find it here.
What I have changed is the following:
I give the white square a start position of top: 150px and let it, on hover of div, get a top: 0. The span gets a transition: top .5s and with that it goes to top: 0; on hover and back to top: 150px; when the mouse leaves.
I have removed the translateY(-60px); from the animation, because that would move it even more up when the animation would start.
Here's your new CSS:
div {
width: 200px;
height: 200px;
margin: 40px auto;
background-color: #b00;
position: relative;
&:hover {
span {
top: 0px;
animation: rotate 1s infinite .5s alternate;
animation-direction: alternate;
}
}
}
span {
position: absolute;
width: 20px;
height: 20px;
background-color: #fff;
bottom: 10px;
left: 0;
right: 0;
top: 150px;
margin: auto;
transition: top .5s;
}
#keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(-90deg);
}
}
Edit: The problem is that an animation is time-based and not action-based, which means that as soon as you trigger an animation, a timer starts running and it will run through all the keyframes until the set time has passed. Hover-in and hover-out have no effect, except that the timer can be stopped prematurely, but the animation will not continue (or reversed, which you wanted) after that. transition is action-based, which means it gets triggered every time an action (for example :hover) is happening. On :hover, this means it takes .5s to go to top:0 and when the hover ends, it takes .5s to got to top:150px.
I hope the above addition makes sense :)
As you can see, I also cleaned up a bit in your animation-name: etc., since it can be combined into one line.
As Harry pointed out, the problem is that you are animating/transitioning the same property, in this case transform. It looks like the current versions of Chrome/FF will allow the animation to take control of the property, thereby breaking the transition. It seems like the only way to work around this is to transition/animation a different property. Since you need to continue rotating the element, you could translate/position the element by changing the bottom property instead. I know that doesn't produce the exact same results, but nonetheless, it does move the element (just not relative to the parent element).
Updated Example
div:hover span {
bottom: 80px;
}
As an alternative, you could also wrap the span element, and then translate that element instead.
In the example below, the .wrapper element is transitioned to translateY(-60px) on hover, and then the child span element is rotated and maintains the animation.
Example Here
div {
width: 200px;
height: 200px;
margin: 40px auto;
background-color: #b00;
position: relative;
}
div:hover .wrapper {
transform: translateY(-60px);
}
div:hover .wrapper span {
animation-name: rotate;
animation-duration: 1s;
animation-delay: .5s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.wrapper {
display: inline-block;
transition: .5s;
position: absolute;
bottom: 10px;
left: 0;
right: 0;
text-align: center;
}
.wrapper span {
display: inline-block;
width: 20px;
height: 20px;
background-color: #fff;
}
#keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(-90deg);
}
}
<div>
<span class="wrapper">
<span></span>
</span>
</div>

Animate :target element on target event in CSS3

I am building a lightbox based on the CSS3 selector :target which selects an element based on the hash in the url. I want to animate the target element on the :target event, but this doesn't seem to work.
Let's say we have a div #banana which is shown when a link to #banana is pressed.
#banana {display: none;}
#banana:target {display: block;}
This works fine. But when trying to animate the element, that doesn't work. See this fiddle.
div#banana {
display: none;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
opacity: 0;
transition: opacity 5s linear 1s;
}
div#banana:target {
display: block;
opacity: 1;
}
The element won't fade in. It is as if the browser skips the animation and immediately triggers the end result.
The problem is that you are changing the display property. The display property can't be transitioned since you can't really animate an element turning from nothing into a block.
The display property can be left out altogether. You will however need to give your element visibility: hidden so that it will not prevent the link from being clicked, then transition it to visibility: visible:
div#banana {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
opacity: 0;
transition: opacity 5s linear 1s;
visibility: hidden;
}
div#banana:target {
opacity: 1;
visibility: visible;
}
Updated fiddle
It's not possible to animate display property. There is simply no gradual stages between none and block.
In your case you can "hide" element by using huge negative top position and revert it back to 0 on target event. Actual transition will be handled by changing opacity.
div#banana {
position: fixed;
left: 0;
top: -1000px;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
opacity: 0;
transition: opacity 1s linear;
}
div#banana:target {
top: 0;
opacity: 1;
}
<div id="banana">
close
</div>
Do you want a banana? Click me!

Does Webkit CSS-Animate pseudo-elements?

I'm working on a new overlay screen technique for a site that I'm working on. I want to leverage animation to CSS because it is easier, and faster than JavaScript animations. I'm doing something simple, but I'm having trouble with webkit-based browsers like Chrome and Safari.
This is the code I'm using:
body:after {
content: '';
width: 100%;
height: 100%;
background-color: #000;
position: fixed;
top: 0;
left: 0;
z-index: -1;
transition-duration: .5s;
-webkit-transition-duration: .5s;
opacity: 0;
}
body.dimmed:after {
z-index: 9999;
opacity: .7;
}
AS you can see, it uses the after pseudo-element, and based on the body class it animates it to a show it or hide it. It works well on Firefox, but not on Chrome or safari. On these browsers the animation does not happen, and the change is instantaneous, which is not what I want. If you apply the same CSS to the body, rather than the pseudo-element, the animation happens:
body {
content: '';
width: 100%;
height: 100%;
background-color: #000;
position: fixed;
top: 0;
left: 0;
z-index: -1;
transition-duration: .5s;
-webkit-transition-duration: .5s;
opacity: 0;
}
body.dimmed {
z-index: 9999;
opacity: .7;
}
This makes me think that transitions do not apply to pseudo-elements on Chrome. Should this be reported as a bug?
It's a known bug, known for years already:
https://bugs.webkit.org/show_bug.cgi?id=23209
http://code.google.com/p/chromium/issues/detail?id=54699
BTW, at the moment you could try to use this technique: http://kizu.ru/en/pseudos/ — by triggering the transition on the element itself and then inheriting the value to the pseudo-element. That won't work for every property (for opacity for example), but you could weork around with that using some imagination.

Resources