CSS transition property not functioning as expected
I am trying to add different transitions for the different properties, but the transition seems to not be working, as I expected.
Here is my CSS code
* {
transition: all .5s ease-in-out;
transition: opacity 80ms linear;
transition: background .2s ease-out;
}
I am probably doing something really obvious wrong, but if you can help, I do appreciate it. Thanks in advance!
Declaring the same CSS property multiple times will result in previous declarations being overwritten, and only the last being kept. (Assuming they have identical specificity).
You can comma-separate transitions like so:
transition: all .5s ease-in-out, opacity 80ms linear, background .2s ease-out;
Demonstration:
* {
transition: all .5s ease-in-out, opacity 2s linear, background 4s ease-out;
}
div {
padding: 100px;
background-color: red;
color: white;
opacity: 0.4;
}
div:hover {
font-size: 20px;
opacity: 1;
background-color: blue;
}
<div>hover this</div>
Transition must happen when we move from one value to another upon a event.
Here the visibility setting on an element:
.two {
background-color: #9fa8da;
position: absolute;
visibility: hidden;
transition: visibility 3ms ease-in;
}
Upon a button click, visibility is set to 'visible'
.two-show {
visibility: visible;
}
However there is no animation effect.
Plnkr here:
http://plnkr.co/edit/4Fhb1Uj744BRwCDhebOP?p=info
Try adding this to .two{}:
-webkit-transition: visibility 30ms ease-in, -webkit-transform 3s;
-moz-transition: visibility 30ms ease-in;
-o-transition: visibility 30ms ease-in;
I wonder if 3ms is to fast?
You can achieve the very same effect you want using the opacity property. Updated your plunker using this new approach. I also increased the transition time for the effect to be noticeable.
.two {
background-color: #9fa8da;
position: absolute;
opacity: 0;
transition: opacity 3s ease-in;
}
.two-show {
opacity: 1;
}
I'm kind of new at haml/css and i wanted to know if it was possible to do the following:
having an image with a font awesome icon over it. Then, on the hover effect, change the image and show, instead of the icon, some text.
The image could be consider as a background image, but i couldn't figure out the rest.
haml:
.feature
#dot
%i.fa.fa-list-ul
css:
#dot{
display: inline-block;
background-image: url(../assets/blue.png);
width: 29%;
height: 102px;
}
#dot:hover{
background: url(../assets/hover.png);
}
this just resolves the part of hover effect, but it's not showing my icon. I didn't even start with the text on the hover
Well.. i fixed it doing the following (in case somebody else is interested)
this is my haml:
.dot
%i.fa.fa-list-ul
.read_more Text on hover
this is my css:
.dot{
display: inline-block;
background-image: url(../assets/blue.png);
width: 29%;
height: 102px;
-moz-transition: all 1s; /* For Safari 3.1 to 6.0 */
-webkit-transition: all 1s;
transition: all 1s;
}
.dot i{
opacity: 1;
-moz-transition: all 1s; /* For Safari 3.1 to 6.0 */
-webkit-transition: all 1s;
transition: all 1s;
}
.dot .read_more{
opacity: 0;
-moz-transition: all 1s; /* For Safari 3.1 to 6.0 */
-webkit-transition: all 1s;
transition: all 1s;
}
.dot:hover{
background: url(../assets/hover.png);
-webkit-transition: all 1s; /* For Safari 3.1 to 6.0 */
-moz-transition: all 1s;
transition: all 1s;
cursor: pointer;
}
.dot:hover i{
opacity: 0;
-moz-transition: all 1s; /* For Safari 3.1 to 6.0 */
-webkit-transition: all 1s;
transition: all 1s;
}
.dot:hover .read_more{
opacity: 1;
-moz-transition: all 1s; /* For Safari 3.1 to 6.0 */
-webkit-transition: all 1s;
transition: all 1s;
}
the -moz and -webkit is used in order to be supported on all browsers.
the transition: all 1s, says the transition's effect should apply to all the elements and the time set it how long it will take to make the transition.
The opacity is just used as the visibility: hidden/visible, but in order to work with the transition attribute, one must change it to opacity.
I'm having a issue with the background-image transition using CSS3. The problem is that it occasionally flickers the first time you roll over it. If you roll-over it the second time it's no problem makes a smooth fade-in/fade-out from one to the other.
I've searched google about this issue found a bunch of people having the same problem. But they resolved the issue by using 1 background image and then using background-position to hide it till you roll over it.
I can't do that with mine because I need the smooth fade-in/fade-out animation from 1 image to the other (it's 2 images of the same button with different colors and thingies.) If I use background-position it'll come from underneath the button on it's place. I need a fade-in fade-out animation.
So I'm guessing this issue happens because of the image not being loaded that, and that it needs a fraction of a second to load.
Here's the code:
.btn-denken{
background:url(../images/btn-denken.png);
width:219px;
height:40px;
float:left;
-webkit-transition: all 0.3s ease-in-out 0s;
-moz-transition: all 0.3s ease-in-out 0s;
-ms-transition: all 0.3s ease-in-out 0s;
-o-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
.btn-denken:hover{
background:url(../images/btn-denken-hover.png);
}
Help is very much appriciated! Thank you!
The trick is to make sure that the images you want to do transition on are already loaded by CSS, that's why putting them in the document as dummy's and loading them through CSS is the solution.
In the example below I have 4 images (0.jpg - 3.jpg), and if I would now set the class '.landing-1' on my document (html), the images transition properly.
In my CSS:
body {
-webkit-transition: background 1s;
background: url(0.jpg) no-repeat center center / cover fixed;
}
.dummy-image {
position: absolute;
left: -100%; /* to hide the dummy */
}
Simple javascript to cache the images:
var images = [],
load = function() {
$('head').append('<style>html.landing-'.concat(this.index, ' body.landing, .dummy-image-', this.index, ' { background: url(', this.src, ') no-repeat center center / cover fixed; }</style>'));
$('body').append('<div class="dummy-image dummy-image-'.concat(this.index, '">'));
};
for(var i=0; i<4; i++) {
var image = document.createElement('img');
image.src = i + '.jpg');
image.index = i;
image.onload = load;
images.push(image);
}
Perhaps you can use two separate containers in the same area using absolute positioning and z-index. Set the two different background images one per container, and then when you hover just make the opacity of the top container to be fully transparent.
I had the same problem: I wanted to use transitioning to fade between images. Using a 2-in-1 image (or a sprite) and using css to change it's position on hover doesn't work because you end up seeing the image scrolling side-side or up-down.
(FYI, you're correct - the blink occurs because it takes a moment to load your image but the transition has already begun from the moment you hover. After you've hovered once, the image has loaded so it won't happen again until you reload the page.)
Here is a purely HTML and CSS solution:
Create a containing div
Place an anchor tag and image tag within this container
Set a background image on the anchor tag (this should be the image you want displayed on page-load)
The image tag should be the image you want to display on hover and needs a z-index applied to bring it behind your anchor tag
After much experimentation, I arrived at the following solution:
(Demo here: http://jsfiddle.net/jmtFK/)
HTML:
<div class="button" id="specific">
<img>
</div>
CSS:
.button {
position: relative;
}
.button a {
display: block;
width: px;
height: px;
background: url() no-repeat;
-webkit-opacity: 1;
-moz-opacity: 1;
opacity: 1;
-webkit-transition: opacity 0.2s ease;
-moz-transition: opacity 0.2s ease;
-ms-transition: opacity 0.2s ease;
-o-transition: opacity 0.2s ease;
transition: opacity 0.2s ease;
}
.button a:hover {
-webkit-opacity: 0;
-moz-opacity: 0;
opacity: 0;
-webkit-transition: opacity 0.3s ease;
-moz-transition: opacity 0.3s ease;
-ms-transition: opacity 0.3s ease;
-o-transition: opacity 0.3s ease;
transition: opacity 0.3s ease;
}
.button img {
position: absolute;
top: 0px;
left: 0px;
z-index: -1;
-webkit-opacity: 0;
-moz-opacity: 0;
opacity: 0;
-webkit-transition: opacity 0.3s ease;
-moz-transition: opacity 0.3s ease;
-ms-transition: opacity 0.3s ease;
-o-transition: opacity 0.3s ease;
transition: opacity 0.3s ease;
}
.button a:hover + img {
-webkit-opacity: 1;
-moz-opacity: 1;
opacity: 1;
-webkit-transition: opacity 0.3s ease;
-moz-transition: opacity 0.3s ease;
-ms-transition: opacity 0.3s ease;
-o-transition: opacity 0.3s ease;
transition: opacity 0.3s ease;
}
I initially didn't have my z-indexed image set to transparent and found that the edges of it appeared around the outside of the link image. This was ugly so I applied opacity: 0.
I also added CSS transitions for "hover in" and "hover out". (Basically, the transition settings applied to a certain CSS state dictate how it transitions to that state. eg the transition settings applied to .button a take effect when button a:hover is no longer applicable.
I hope that helps.
I can't seem to find the correct syntax for the CSS transition shorthand with multiple properties. This doesn't do anything:
.element {
-webkit-transition: height .5s, opacity .5s .5s;
-moz-transition: height .5s, opacity .5s .5s;
-ms-transition: height .5s, opacity .5s .5s;
transition: height .5s, opacity .5s .5s;
height: 0;
opacity: 0;
overflow: 0;
}
.element.show {
height: 200px;
opacity: 1;
}
I add the show class with javascript. The element becomes higher and visible, it just doesn't transition. Testing in latest Chrome, FF and Safari.
What am I doing wrong?
EDIT: Just to be clear, I'm looking for the shorthand version to scale my CSS down. It's bloated enough with all the vendor prefixes. Also expanded the example code.
Syntax:
transition: <property> || <duration> || <timing-function> || <delay> [, ...];
Note that the duration must come before the delay, if the latter is specified.
Individual transitions combined in shorthand declarations:
-webkit-transition: height 0.3s ease-out, opacity 0.3s ease 0.5s;
-moz-transition: height 0.3s ease-out, opacity 0.3s ease 0.5s;
-o-transition: height 0.3s ease-out, opacity 0.3s ease 0.5s;
transition: height 0.3s ease-out, opacity 0.3s ease 0.5s;
Or just transition them all:
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
Here is a straightforward example. Here is another one with the delay property.
Edit: previously listed here were the compatibilities and known issues regarding transition. Removed for readability.
Bottom-line: just use it. The nature of this property is non-breaking for all applications and compatibility is now well above 94% globally.
If you still want to be sure, refer to http://caniuse.com/css-transitions
If you have several specific properties that you want to transition in the same way (because you also have some properties you specifically don't want to transition, say opacity), another option is to do something like this (prefixes omitted for brevity):
.myclass {
transition: all 200ms ease;
transition-property: box-shadow, height, width, background, font-size;
}
The second declaration overrides the all in the shorthand declaration above it and makes for (occasionally) more concise code.
/* prefixes omitted for brevity */
.box {
height: 100px;
width: 100px;
background: red;
box-shadow: red 0 0 5px 1px;
transition: all 500ms ease;
/*note: not transitioning width */
transition-property: height, background, box-shadow;
}
.box:hover {
height: 50px;
width: 50px;
box-shadow: blue 0 0 10px 3px;
background: blue;
}
<p>Hover box for demo</p>
<div class="box"></div>
Demo
I made it work with this:
.element {
transition: height 3s ease-out, width 5s ease-in;
}
One important thing to note is that the CSS transition property itself is a shorthand - as mentioned in the MDN Web Docs :
The transition CSS property is a shorthand property for transition-property, transition-duration, transition-timing-function, and transition-delay.
The ideal use of this shorthand is to combine the various Constituent properties of a single transition. If this is used to combine multiple transitions, it will start to get clunky.
So when you have more than 2 transitions on the same element which different constituent properties, it becomes easier to write them individually instead of using the transition shorthand. For example:
This is the shorthand version(Option 1) of multiple transitions on one element:
transition: transform 0.5s ease-in-out, box-shadow 0.2s ease-out, filter 0.1s ease-out, color 0.25s ease-in 0.2s;
As you can see, this gets clunky and a little bit harder to visualize.
The same CSS can be applied like this(Option 2):
transition-property: transform, box-shadow, filter, color;
transition-duration: 0.5s, 0.2s, 0.2s, 0.25s;
transition-timing-function: ease-in-out, ease-out, ease-out, ease-in;
transition-delay: 0s, 0s, 0s, 0.2s
Of course, ultimately it all just comes down to your preference of typing and maintaining your source code. But I personally prefer the 2nd option.
TIP:
Additional benefit of using this is, if one of the Constituent properties is same for all transitions, you don't need to mention it multiple times. For example, in the above example, if the transition-duration was the same(0.5s) for all, you write it like this:
transition-property: transform, box-shadow, filter, color;
transition-duration: 0.5s;
transition-timing-function: ease-in-out, ease-out, ease-out, ease-in;
transition-delay: 0s, 0s, 0s, 0.2s
By having the .5s delay on transitioning the opacity property, the element will be completely transparent (and thus invisible) the whole time its height is transitioning. So the only thing you will actually see is the opacity changing. So you will get the same effect as leaving the height property out of the transition :
"transition: opacity .5s .5s;"
Is that what you're wanting? If not, and you're wanting to see the height transition, you can't have an opacity of zero during the whole time that it's transitioning.
This helped me understand / streamline, only what I needed to animate:
// SCSS - Multiple Animation: Properties | durations | etc.
// on hover, animate div (width/opacity) - from: {0px, 0} to: {100vw, 1}
.base {
max-width: 0vw;
opacity: 0;
transition-property: max-width, opacity; // relative order
transition-duration: 2s, 4s; // effects relatively ordered animation properties
transition-delay: 6s; // effects delay of all animation properties
animation-timing-function: ease;
&:hover {
max-width: 100vw;
opacity: 1;
transition-duration: 5s; // effects duration of all aniomation properties
transition-delay: 2s, 7s; // effects relatively ordered animation properties
}
}
~ This applies for all transition properties (duration, transition-timing-function, etc.) within the '.base' class
I think that this should work:
.element {
-webkit-transition: all .3s;
-moz-transition: all .3s;
-o-transition: all .3s;
transition: all .3s;
}