Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jerky CSS3 transition in Firefox

I am trying to do a simple image fade on rollover - works fine and smooth in Chrome, but Firefox is a bit jumpy. I've tried doing the backface-visibility trick on the container, but still no luck.

Anyone have any ideas?

JSFiddle

HTML

<div class="link-box large">
    <div class="image">

        <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRStwH3maKRqLU8lLOo1XbO6uZIKHRyf2PGv66H6ol5mB0kS_0r" alt="">
    </div>
</div>

CSS

.link-box .image img { transition: all .2s ease-out; width:200px; }
.link-box.large { position: relative;}
.link-box.large:hover .image img { opacity: .65; }
like image 634
wickywills Avatar asked Jun 19 '14 14:06

wickywills


2 Answers

My best guess is that setting the width of the image to 200px and leaving the height unspecified is causing the browser to calculate the height of the image. If the height calculates to a nice whole number it isn't an issue. If the height calculates to a decimal it may be the cause of the problem.

In this case the natural dimensions of the image are 275px by 183px.

By changing the width of the image to 200px you are shrinking the image to 72.727272...% of its natural size.

275/200 = 0.727272... Or if you prefer fractions: 275(8/11) = 200

Now running the same equation on the height yields:

183(8/11) = 133.090909...

It looks like, under the normal run of things, the partial pixels are cropped, but during the transition the partial pixels aren't being cropped, and the image is warped slightly to show the partial pixels within the same height.

Cropped down to 133px:
enter image description here
Not cropped and slightly warped:
enter image description here


Now that we have a good hypothesis on what's causing the problem, on to the solutions:

You can hard code the height of the image:

Working Example

.link-box .image img {
    transition: all .2s ease-out;
    width:200px;
    height: 133px; /* manually set the height */
}

Or if you would rather not hard code the height, you can also fix the issue with an anti-alias hack, just add a box-shadow.

Working Example

.link-box.large:hover .image img {
    opacity: .65;
    box-shadow: 0 0 0 #000; /* add a non-visible box-shadow */
}

Or if you're concerned about the cross-browser compatibility of using a box-shadow, you can also use a transparent border:

Working Example

.link-box .image img {
    transition: all .2s ease-out;
    width:200px;
    border: 1px solid transparent; /* add transparent border */
}
like image 193
apaul Avatar answered Oct 05 '22 04:10

apaul


Works good on my Firefox.

Anyway you can try to add some special attributes that will prepare the browser for the transition and actually render the element with possible transformation in mind.

Such an attribute is transform: translate3d(0,0,0);

Like this :

.link-box .image img { 
    transition: all .2s ease-out; 
    width:200px; 
    transform: translate3d(0,0,0); 
}
.link-box.large { position: relative;}
.link-box.large:hover .image img { opacity: .65; }
like image 22
drinchev Avatar answered Oct 05 '22 03:10

drinchev