【问题标题】:Collapse expand animation without transitioning the `height` property?折叠展开动画而不转换“高度”属性?
【发布时间】:2019-11-24 10:36:57
【问题描述】:

我读了很多文章说如果你想要平滑的 CSS 过渡,你应该坚持使用 transformopacity

例如:https://www.netcentric.biz/insights/2017/09/css-transition-performance.html

核心思想似乎总是:

...为了优化您的过渡体验,浏览器应确保动画 CSS 不会导致重绘。

问题

我需要做类似下面的 sn-p 的操作:当用户点击它时展开/折叠过滤器框。到目前为止,我只能通过转换它们的height 属性来做到这一点。我可以通过其他方式做到这一点,而无需像我一样转换 height 属性吗?


注意:这是一个移动视图,我确实希望Filters 在打开时将Results 向下“推”。结果将是一个包含 30 个产品的画廊,其中包含缩略图、标题和链接。

const styled = window.styled;

const Header_DIV = styled.div`
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  height: 50px;
  background-color: lightblue;
`;

const Main_DIV = styled.div`
  padding-top: 42px;
`;

const Filters1_DIV = styled.div`
  width: 100%;
  background-color: lightgreen;
  cursor: pointer;
  height: ${props => props.open ? '100px' : '16px' };
  transition: height ease-out .5s;
`;

const Filters2_DIV = styled.div`
  width: 100%;
  background-color: lightcoral;
  cursor: pointer;
  height: ${props => props.open ? '100px' : '16px' };
  transition: height ease-out .5s;
`;

const Results_DIV = styled.div`
  background-color: lightgray;
`;

function App() {
  
  const [openFilter1,setOpenFilter1] = React.useState(false);
  const [openFilter2,setOpenFilter2] = React.useState(false);
  
  function toggleFilter1() {
    setOpenFilter1((prevState) => !prevState);  
  }
  
  function toggleFilter2() {
    setOpenFilter2((prevState) => !prevState);  
  }
  
  return(
    <React.Fragment>
      <Header_DIV>
        Header
      </Header_DIV>
      <Main_DIV>
        <Filters1_DIV
          onClick={toggleFilter1}
          open={openFilter1}
        >
          Filter1 ----------- Click to open/close!
        </Filters1_DIV>
        <Filters2_DIV
          onClick={toggleFilter2}
          open={openFilter2}
        >
          Filter2 ----------- Click to open/close!
        </Filters2_DIV>
        <Results_DIV>
          Results
        </Results_DIV>
      </Main_DIV>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
* {
  box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<script src="//unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id="root"/>

【问题讨论】:

  • 您可以改为转换“最大高度”。虽然这仍然会触发重绘,但它允许您切除元素的自然高度。如果您希望“过滤器将结果向下推送”,我怀疑是否可以重排内容浏览器不必重绘。
  • @Moob 使用max-height 会触发重绘,但以更有效的方式,是这样吗?谢谢!

标签: javascript html css reactjs styled-components


【解决方案1】:

您可以尝试在转换中使用transform: scale(0)opacity: 0。但是您可能需要稍微调整一下布局和样式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    相关资源
    最近更新 更多