Why does my transform: translateY flicker in Chrome?
Asked Answered
T

1

11

I have a simple multi-column layout; I'm trying to lift an element on :hover using translateY.

It causes flickering (tested on Chrome 57). How do I fix this?

"use strict";

$(function () {
  var $target = $('.wall');

  function getImageUrl(id) {
    var width = 500;
    var height = 250 + Math.floor(Math.random() * 150);
    return "https://unsplash.it/" + width + "/" + height + "?image=" + id;
  }

  function addElement(element) {
    var $template = $target.find('.template').clone().appendTo($target).removeClass("template");

    $template.find("a").attr("href", element.post_url);

    $template.find("img").attr("src", getImageUrl(element.id));

    $template.find("figcaption").text(element.author);

    $template.removeClass("hide");
  }

  $.getJSON("https://unsplash.it/list", function (data) {
    var images = 12;
    var elements = [];

    function getRandomImage() {
      var id = Math.floor(Math.random() * data.length);
      return data.splice(id, 1)[0];
    }

    while (images > elements.length) {if (window.CP.shouldStopExecution(1)){break;}
      elements.push(getRandomImage());
    }
window.CP.exitedLoop(1);


    elements.forEach(function (element) {
      addElement(element);
    });
  });
});
.wall {
  -webkit-column-count: 3;
     -moz-column-count: 3;
          column-count: 3;
  padding-top: 0.5rem;
}
.wall * {
  -webkit-column-break-inside: avoid;
     page-break-inside: avoid;
          break-inside: avoid;
}
.wall .brick {
  display: block;
  padding-bottom: 1rem;
}
.wall .brick a {
  display: inline-block;
  color: inherit;
  -webkit-transition: -webkit-transform 333ms ease;
  transition: -webkit-transform 333ms ease;
  transition: transform 333ms ease;
  transition: transform 333ms ease, -webkit-transform 333ms ease;
}
.wall .brick a:hover, .wall .brick a:focus {
  -webkit-transform: translateY(-1rem);
          transform: translateY(-1rem);
}
.wall .brick .thumbnail {
  margin-bottom: 0.5rem;
}
.wall .brick figcaption {
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="wall column">
  <div class="hide brick template">
    <a>
      <figure>
        <img class="thumbnail" /><figcaption></figcaption>
      </figure>
    </a>
  </div>
</div>

CodePen Demo

Theological answered 17/4, 2017 at 15:0 Comment(7)
It might be interesting to note that for me (Safari 10.1) only the middle and right picture of the top row flicker, the other images move back and forth as intended.Weintraub
Since Chrome is also Webkit, this might solve your issue: #2947248Weintraub
This is also similar. Did you look at these Google results yet? Many seem applicable.Weintraub
Try adding will-change:transform; to your a element https://mcmap.net/q/1158635/-css-transition-with-border-radius-and-linear-gradient ... seems to work codepen.io/anon/pen/qmdGRjWhelm
@Whelm Safari simply stops rendering the two images that flickered before after adding the will-change.Weintraub
Seems fine to me on Safari too ...Whelm
Thank you comments! Those suggestions helped. If one of you would like to post it as an answer, I will accept itTheological
S
6

Placing the following code in the element with the transform property should solve:

-webkit-perspective: 1000;
-webkit-backface-visibility: hidden;

In your case:

a {
  display: inline-block;
  transition: transform 333ms ease;
  &:hover, &:focus {
    transform: translateY(-1rem);
    -webkit-perspective: 1000;
    -webkit-backface-visibility: hidden;
  }
}
Saberhagen answered 8/8, 2017 at 15:16 Comment(1)
Same fix works with the new bootstrap 4 card-deck as well!Governorship

© 2022 - 2024 — McMap. All rights reserved.