0

Chromium 版本 75.0.3770.100(官方构建)Arch Linux(64 位)。
在 Brave 的 Android 上也观察到(同样基于 Chromium 75)。

我正在制作一个充满白色渐变的旋转正方形:

.spinning {
  animation-name: spinning;
  animation-duration: 2s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  width: 100px;
  height: 100px;
  background-image: radial-gradient(farthest-corner at 40% 40%, #fff, #f7f7f7 50%, #e8e8e8 75%, #d1d1d1 100%);
  backface-visibility: hidden;
}

@keyframes spinning {
  0% { transform: rotate3d(1, -1, 0, -180deg); }
  100% { transform: rotate3d(1, -1, 0, 180deg); }
}
<div class="spinning"></div>

这在 Firefox 上运行良好。但是,在 Chrome 上,我最初看到的是黑色方块而不是白色方块。就好像 Chrome 忘记渲染元素的图层一样。此外,旋转轴稍微偏离中心。当我右键单击方块并选择“检查”时,它突然意识到自己的方式错误并变成白色。

看起来我遇到了问题 966019,它出现在 Chrome 75 或 74 中,并且已被确认和分配,但尚未修复。

值得注意:

  • Abackground-color 除了使background-image正方形变成那种颜色而不是黑色。
  • 如果我在 div 中放置一些文本,我会得到一个不可见的正方形而不是黑色的。

解决方法:

  • 它不会发生在backface-visibility: visible. 但我需要隐藏它,因为在我的实际情况下,正方形有两个不同颜色的边,由两个异相 180 度的旋转正方形创建。
  • background-color 普通而不是渐变不会发生这种情况。但是需要渐变以适应其余样式。
  • 0deg如果我从 开始旋转并通过,则不会发生这种情况360deg。但随后它将与“前”面同时开始。

由于所有这些都有不良的副作用,我正在寻找更好的解决方法。

4

3 回答 3

1

Another solution is to consider pseudo element to create both sides and you won't have the bug and you can easily manage each side alone.

.spinning {
  animation-name: spinning;
  animation-duration: 2s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  width: 100px;
  height: 100px;
  position: relative;
  transform-style:preserve-3d;
}
.spinning:before,
.spinning:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  backface-visibility: hidden;
}
.spinning:before {
  background-image: radial-gradient(farthest-corner at 40% 40%, #fff, #f7f7f7 50%, #e8e8e8 75%, #d1d1d1 100%);
}
.spinning:after {
  transform: rotateY(180deg);
  background:rgba(255,0,0,0.5);
}

@keyframes spinning {
  0% {
    transform: rotate3d(1, -1, 0, -180deg);
  }
  100% {
    transform: rotate3d(1, -1, 0, 180deg);
  }
}
<div class="spinning"></div>

于 2019-07-09T09:42:23.473 回答
0

另一种解决方法是在元素的伪元素content属性上触发动画:

.spinning {
  animation-name: spinning;
  animation-duration: 2s;
  animation-delay: 0s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  width: 100px;
  height: 100px;
  backface-visibility: hidden;
  animation-fill-mode: forwards;
  background-image: radial-gradient(farthest-corner at 40% 40%, #fff, #f7f7f7 50%, #e8e8e8 75%, #d1d1d1 100%);

}
.spinning::after {
  content: "";
  animation: trigger-paint .1s forwards 1;
}
@keyframes spinning {
  0% { transform: rotate3d(1, -1, 0, -180deg); }
  100% { transform: rotate3d(1, -1, 0, 180deg); }
}
@keyframes trigger-paint {
  0% {content: ""}
  100% {content: none}
}
<div class="spinning"></div>

但由于这里的技巧是它强制重新绘制,我担心这会带来巨大的性能影响(根据我的开发工具,它确实会重新启动动画很多次,即使它设置为启动一次)。

于 2019-07-09T08:09:51.257 回答
0

最后通过不依赖backface-visibility而只是动画visibility自己来解决它:

.spinning {
  animation-name: spinning, hide-backface;
  animation-duration: 2s;
  animation-iteration-count: infinite;
  animation-timing-function: linear, step-start;
  width: 100px;
  height: 100px;
  background-image: radial-gradient(farthest-corner at 40% 40%, #fff, #f7f7f7 50%, #e8e8e8 75%, #d1d1d1 100%);
}

@keyframes spinning {
  0% { transform: rotate3d(1, -1, 0, -180deg); }
  100% { transform: rotate3d(1, -1, 0, 180deg); }
}

@keyframes hide-backface {
  0% { visibility: hidden; }
  25% { visibility: hidden; }
  75% { visibility: visible; }
  100% { visibility: hidden; }
}
<div class="spinning"></div>

于 2019-07-09T08:13:47.220 回答