【问题标题】:Using transform: scale is not appropriately hiding a div使用 transform: scale 没有适当地隐藏 div
【发布时间】:2017-05-18 14:37:40
【问题描述】:

我试图隐藏一个带有动画的 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。

如何正确应用此变换来隐藏第二个框?

【问题讨论】:

    标签: javascript css reactjs css-animations


    【解决方案1】:

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

    回到height 的示例,您可以通过使用transform: translateZ(0); 之类的假变换属性欺骗浏览器来强制浏览器使用GPU 加速(translateZ()translate3d() 的3D 组件,很像scaleZ() 是 3D 组件 of scale3d())。

    这是一个快速演示:

    document.querySelector('button').addEventListener('click', function() {
      document.querySelector('.row').classList.toggle('hidden');
    });
    .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;
    }
    <div class="row">Some text</div>
    
    <button>Toggle Row Visibility</button>

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 2012-03-19
      • 2012-08-05
      • 2011-09-14
      • 2013-03-14
      • 2017-12-13
      • 2018-02-01
      相关资源
      最近更新 更多