Search code examples
csswebkittransformscale

CSS: Problems when using object-fit and transform together on webkit


I'm trying to use both the css property object-fit: cover on an img element to have my image filling its containing div and transform: scale(xx) to have the image zooming out on hover.

Here is a sample fiddle: https://jsfiddle.net/96kbuncq/
Edit: sample with real images: https://jsfiddle.net/96kbuncq/3/

HTML:

<div>
   <div class="category">
      <img src="http://placehold.it/1200x950&text=1200x950+-+Category+1+-" />
   </div>
   <div class="category">
      <img src="http://placehold.it/1200x950&text=1200x950+-+Category+2+-" />
   </div>
   <div class="category">
      <img src="http://placehold.it/1200x950&text=1200x950+-+Category+3+-" />
   </div>
</div>

CSS:

.....

div.category img {
  display: block;
  height: 100%;
  width: 100%;
  object-fit: cover;
  object-position: center;
}

/* Transformations */

div.category img {
  transition: transform 0.35s;
  transform: /*translateZ(0)*/ scale(1.12);
}

div.category:hover img {
  transform: /*translateZ(0)*/ scale(1);
}

This is working fine in Firefox but in Chrome and Opera I have the following problems:

  • When hovering the first div, the two others are also affected (and when hovering the second one, the third one is also affected),
  • When hovering a div, the image inside is first entirely displayed (we can see the whole image stretched to fit inside the div) before being correctly zoomed out and "covering" the div.

I don't know how to solve those problems.

About the first problem (affected siblings), I've found other answers saying to use translateZ(0) but when I add this the object-fit: cover is not working anymore (the whole image is stretched to fit inside the div).

Any ideas how to make this work in Chrome ? (Both the object-fit and transform are working as expected when used without the other.)


Solution

  • After testing it seems that backface-visibility, translateZ, and translate3d which are required to prevent the transform flicker, break object-fit and background-size. If your goal is to center the image then you can use position: absolute and translate like in the example below.

    div.category {
        width: 80%;
        height: 150px;
        margin: 20px;
        position: relative;
        overflow: hidden;
    }
    img {
        display: block;
        width: 100%;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%) scale(1.12); /* order is important here*/
        backface-visibility: hidden;
        transition: transform 0.35s;
    }
    div.category:hover img {
        transform: translate(-50%, -50%) scale(1);
    }
    <div>
        <div class="category">
            <img src="http://www.4freephotos.com/images/batch/Elephant-dusting674.jpg" />
        </div>
        <div class="category">
            <img src="http://www.4freephotos.com/images/batch/Bananas-and-kiwi-221.jpg" />
        </div>
        <div class="category">
            <img src="http://placehold.it/1200x950&text=1200x950+-+Category+3+-" />
        </div>
    </div>

    http://jsfiddle.net/moogs/r1s1rtLk/4/