如何实现从百分比max-height到固定像素height的过渡动画?
实现从百分比max-height到固定像素height的过渡动画
核心问题在于:元素展开状态下height默认是auto,而CSS过渡需要明确的数值起点和终点才能生效。我们可以通过以下方式解决:
- 展开状态时,动态获取元素的实际高度(受
max-height:60%限制),将其设为元素的height值 - 最小化时,将
height设为固定的55px,利用CSS过渡实现平滑动画 - 监听窗口resize事件,在窗口尺寸变化时更新展开状态下的元素高度,适配不同屏幕
修改后的代码示例
React 代码
const { useState, useRef, useEffect } = React; const App = () => { const [isMinimized, setIsMinimized] = useState(false); const containerRef = useRef(null); // 处理展开/最小化时的高度设置 useEffect(() => { const container = containerRef.current; if (!container) return; if (!isMinimized) { // 展开时,先重置height为auto,获取实际高度后再设置为固定值 container.style.height = 'auto'; const computedHeight = container.offsetHeight; container.style.height = `${computedHeight}px`; } else { // 最小化时设置固定高度 container.style.height = '55px'; } }, [isMinimized]); // 监听窗口resize,更新展开状态下的高度 useEffect(() => { const handleResize = () => { const container = containerRef.current; if (!container || isMinimized) return; container.style.height = 'auto'; const computedHeight = container.offsetHeight; container.style.height = `${computedHeight}px`; }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, [isMinimized]); return ( <div className="App"> <div ref={containerRef} className={`container ${isMinimized ? 'container-minimized' : ''}`} > <p>Foo</p> <p>Bar</p> <p>Foobar</p> <div onClick={() => setIsMinimized(!isMinimized)} className="minimize-element" > <span /> </div> </div> </div> ); } ReactDOM.render( <App />, document.getElementById("root") );
CSS 代码
.App { font-family: sans-serif; text-align: center; display: flex; justify-content: center; align-items: center; position: relative; } .container { transition: height 0.3s ease-out; width: 100%; background-color: hotpink; top: 0; left: 0; position: fixed; box-shadow: 0px 3px 3px -2px rgba(0, 0, 0, 0.2), 0px 3px 4px 0px rgba(0, 0, 0, 0.14), 0px 1px 8px 0px rgba(0, 0, 0, 0.12); max-height: 60%; overflow: hidden; display: flex; flex-direction: column; } .minimize-element { width: 100%; display: flex; justify-content: center; align-items: center; margin-top: auto; background-color: yellowgreen; padding-top: 4px; padding-bottom: 4px; } .minimize-element:hover { cursor: pointer; } .minimize-element > span { background-color: red; width: 35px; height: 6px; border-radius: 7px; }
HTML 代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.development.js"></script> <div id="root"></div>
关键说明
- 通过
useRef获取容器元素,动态计算并设置展开状态下的实际高度,确保过渡有明确的数值起点 - 监听窗口
resize事件,在屏幕尺寸变化时重新计算高度,保证适配性 - 调整了
minimize-element的margin-top为auto,让按钮始终固定在容器底部,布局更合理
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

