Flickering moving html element on windows in chrome browser

41 Views Asked by At

I have a problem with a flickering vertical line while moving horizontally. In non-constant intervals the line just disappear for a while.

I have created small playground to reproduce the issue.

let i = 0;
(function tick() {
  requestAnimationFrame(() => {
    const playhead = document.querySelectorAll("div.playhead")[0];
    playhead.style.left = i + "px";
    if (i === 500) return;
    i++;
    tick();
  });
})();
.container {
  position: relative;
  border: 1px solid gray;
  width: 500px;
  height: 100px;
}

.playhead {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 1px;
  background-color: red;
  z-index: 3;
  user-select: none;
}
<div class="container">
  <div class="playhead" />
</div>

The issue occurs in Chrome on Windows, on macOS everything works correctly.

1

There are 1 best solutions below

0
ashish singh On

In general you should try to use transform property instead of changing the position of element

let i = 0;
(function tick() {
  requestAnimationFrame(() => {
    const playhead = document.querySelectorAll("div.playhead")[0];
    playhead.style.transform = `translateX(${i}px)`
    if (i === 500) return;
    i++;
    tick();
  });
})();
.container {
  position: relative;
  border: 1px solid gray;
  width: 500px;
  height: 100px;
}

.playhead {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 1px;
  background-color: red;
  z-index: 3;
  user-select: none;
}
<div class="container">
  <div class="playhead" />
</div>

The second solution is to use will-change property on playhead ( see css section ), but I will strongly suggest using transform for these kinds of cases.

let i = 0;
(function tick() {
  requestAnimationFrame(() => {
    const playhead = document.querySelectorAll("div.playhead")[0];
    playhead.style.left = i + "px";
    if (i === 500) return;
    i++;
    tick();
  });
})();
.container {
  position: relative;
  border: 1px solid gray;
  width: 500px;
  height: 100px;
}

.playhead {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 1px;
  background-color: red;
  z-index: 3;
  user-select: none;
  will-change: left;  /* I ADDED THIS LINE ONLY */
}
<div class="container">
  <div class="playhead" />
</div>