使用transform:scale不适当隐藏div

时间:2017-05-18 14:37:40

标签: javascript css reactjs css-animations

我试图在某个动作上隐藏带有动画的div。我最初的传球看起来如下:

.row {
  height: 50px;
  transition: height 200ms ease-in-out;
  &.hidden {
    height: 0;
  }
}

我的DOM结构如下(带有反应):

<div className={styles.container}>
  <div className={styles.row} />
  <div className={classnames(styles.row, { [styles.hidden]: !this.state.active })}
</div>

虽然这确实有效,但速度很慢。我听说转换在CSS中转换是有效的,所以我决定尝试以下方法。

.row {
  height: 50px;
  transform-origin: top;
  transition: transform 200ms ease-in-out;

  &.hidden {
    transform: scaleY(0);
  }
}

但是,在容器中,第二行仍然显示作为50px框,但检查员说它的高度为0。

如何正确应用此转换以隐藏第二个框?

1 个答案:

答案 0 :(得分:1)

3D变换是高效的,因为浏览器会将目标元素合成到自己的图层中,并将动画卸载到GPU。 height甚至scaleY()不是3D转换,也不会受益于GPU加速(CPU仍会处理它)。

要使用height回到您的示例,您可以强制浏览器使用虚拟转换属性(例如transform: translateZ(0);)欺骗浏览器来加速GPU加速(translateZ()是3D组件translate3d()scaleZ()非常相似,是3D组件of scale3d())。

这是一个快速演示:

&#13;
&#13;
document.querySelector('button').addEventListener('click', function() {
  document.querySelector('.row').classList.toggle('hidden');
});
&#13;
.row {
  background-color: green;
  height: 50px;
  overflow: hidden;
  transition: height 200ms ease-in-out;
  transform: translateZ(0); /* or translate3d(0,0,0), rotateZ(360deg), etc. */
}

.row.hidden {
  height: 0;
}

button {
  left: 0;
  position: absolute;
  top: 100px;
}
&#13;
<div class="row">Some text</div>

<button>Toggle Row Visibility</button>
&#13;
&#13;
&#13;

通过添加属性,浏览器应该利用GPU加速,显着改善动画效果。有关转换和GPU加速的更多信息,请参阅this question

我建议先尝试一下,看看它是否足以在你的应用中加快动画效果。您也可以尝试添加will-change属性,尽管这是工作草案的一部分,目前是非标准的。