0

I want to make an image that's wrapped in an a tag darken on hover. To do this I simply made the wrapping a tag's background black and applied:

a:hover > img {
  opacity: .8;
  -webkit-transition: opacity .2s ease-out;
  transition: opacity .2s ease-out;
}

to the image.

This works, but I get a weird 'jumpy' issue when image element containers have float: left; or display: inline-block; applied. This only occurs on some images.

You can see this happening here when you hover over the middle image: https://jsfiddle.net/4566a85t/

Would anyone know how I could prevent this?

My code is:

HTML

<div class="wrapper">
    <a href="#">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTojc9ycyhwL6TnP_lEhQrTXy8Cjrs738WeDmnDOmIXGmR20NEJTw">
    </a>
</div>
<div class="wrapper">
    <a href="#">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTojc9ycyhwL6TnP_lEhQrTXy8Cjrs738WeDmnDOmIXGmR20NEJTw">
    </a>
</div>
<div class="wrapper">
    <a href="#">
      <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTojc9ycyhwL6TnP_lEhQrTXy8Cjrs738WeDmnDOmIXGmR20NEJTw">
    </a>
</div>

CSS

.wrapper {
  width: 25%;
  float: left;
}

a {
  background: black;
  display: block;
}

img {
  width: 100%;
  margin: 0;
}

a:hover > img {
  opacity: .8;
   -webkit-transition: opacity .2s ease-out;
    transition: opacity .2s ease-out;
}

EDIT:

I tried using -webkit-filter: brightness(70%); with no black background, but had the same issue. Seems to be the transition that's the problem.

MeltingDog
  • 14,310
  • 43
  • 165
  • 295

3 Answers3

0

I think you need to reset the browser default css first and add in -webkit-backface-visibility: hidden to image as suggested in the comments

*{
   margin: 0;
   padding: 0;
}

img{
   -webkit-backface-visibility: hidden;
}

Source:

image moves on hover - chrome opacity issue

Example:

* {
  margin: 0;
  padding: 0;
}

.wrapper {
  width: 25%;
  display: inline-block;
}

a {
  background: black;
  display: block;
}

img {
  -webkit-backface-visibility: hidden;
  width: 100%;
  margin: 0;
}

a>img {
  opacity: 1;
}

a:hover>img {
  opacity: .8;
  -webkit-transition: opacity .2s ease-out;
  transition: opacity .2s ease-out;
}
<div class="wrapper">
  <a href="#"><img src="https://i.pinimg.com/736x/e5/0d/17/e50d177765012ab2e70f8bccb5dc884a--pug-puppies-pug-dogs.jpg"></a>
</div>
<div class="wrapper">
  <a href="#"><img src="https://i.pinimg.com/736x/e5/0d/17/e50d177765012ab2e70f8bccb5dc884a--pug-puppies-pug-dogs.jpg"></a>
</div>
<div class="wrapper">
  <a href="#"><img src="https://i.pinimg.com/736x/e5/0d/17/e50d177765012ab2e70f8bccb5dc884a--pug-puppies-pug-dogs.jpg"></a>
</div>
Vincent1989
  • 1,593
  • 2
  • 13
  • 25
0

EDIT: below will only work for Webkit browsers

OK got it!

I used -webkit-filter: brightness(); and set the initial img to -webkit-filter: brightness(100%);

My new code:

a > img {
  -webkit-filter: brightness(100%);
}

a:hover > img {
   -webkit-filter: brightness(70%);
   -webkit-transition: all 1s ease;
   -moz-transition: all 1s ease;
   -o-transition: all 1s ease;
   -ms-transition: all 1s ease;
   transition: all 1s ease;
}

Update fiddle: https://jsfiddle.net/4566a85t/2/

MeltingDog
  • 14,310
  • 43
  • 165
  • 295
0

My theory is that when it starts to animate CSS doesn't know the right size that's why it's like adjusting during the first frames.

But if you will set a fixed width of the wrapper. e.g.

.wrapper {
  display: inline-block;
  width:100px;
}

Cheers!

babidi
  • 506
  • 5
  • 6