React折叠组件SCSS高度过渡动画失效问题求助
折叠组件高度过渡动画失效问题解决
问题现象
折叠组件展开/收起时,箭头旋转动画正常工作,但内容区域的高度过渡没有动画效果,直接跳变。
现有代码
React组件代码
import {useState} from "react" import arrow from "../../assets/arrow.png" import "./collapses.css" function Collapses({title, content}){ const [open, setOpen] = useState(false) const toggle = () => { setOpen(!open) } return( <div className="collapse"> <div className="collapse__title" onClick={toggle} >{title} <img src={arrow} alt="arrow" className={`collapse__arrow ${open ? 'collapse__arrow_rotation' : ''}`}/></div> {open && <div className={`collapse__content ${open ? 'open' : ''}`}>{content}</div>} </div> ) } export default Collapses
SCSS代码
.collapse__content{ border-radius: 10px; display: flex; text-align: left; color: #FF6060; font-size: 18px; font-family: Montserrat; font-style: normal; font-weight: 400; width: 100%; padding: 0.5rem; padding-top: 0.5rem; padding-bottom: 0.5rem; background-color: #F6F6F6; overflow: hidden; height: 0px; transition: height 0.3s ease-in-out; } .collapse__content.open { height: auto; } .collapse__arrow { transition: transform 0.3s ease-in-out } .collapse__arrow_rotation { transform: rotate(180deg); }
问题原因
CSS的transition无法在height: 0和height: auto之间生成动画——因为auto是不确定的高度值,浏览器无法计算过渡过程中的中间状态,只能直接切换高度。
解决方案
方案1:用max-height替代height(简单实用)
将固定height替换为max-height,设置一个足够容纳最大内容高度的值,让浏览器能计算过渡动画:
.collapse__content{ /* 保留原有样式,替换height相关设置 */ overflow: hidden; max-height: 0px; transition: max-height 0.3s ease-in-out; } .collapse__content.open { max-height: 1000px; /* 设为比内容最大高度更大的值 */ }
方案2:JS动态计算内容高度(精确控制)
通过JavaScript获取内容的实际高度,动态设置height值,实现精准过渡:
import {useState, useRef, useEffect} from "react" import arrow from "../../assets/arrow.png" import "./collapses.css" function Collapses({title, content}){ const [open, setOpen] = useState(false) const [contentHeight, setContentHeight] = useState(0) const contentRef = useRef(null) useEffect(() => { if (contentRef.current) { // 获取内容的实际滚动高度 const height = contentRef.current.scrollHeight; setContentHeight(height); } }, [content]) const toggle = () => { setOpen(!open) } return( <div className="collapse"> <div className="collapse__title" onClick={toggle} >{title} <img src={arrow} alt="arrow" className={`collapse__arrow ${open ? 'collapse__arrow_rotation' : ''}`}/></div> <div ref={contentRef} className="collapse__content" style={{ height: open ? `${contentHeight}px` : '0px' }} > {content} </div> </div> ) } export default Collapses
对应的SCSS调整(移除.open类的height设置,保留transition):
.collapse__content{ /* 保留原有样式 */ overflow: hidden; height: 0px; transition: height 0.3s ease-in-out; }
内容的提问来源于stack exchange,提问作者SirRichard
相关产品推荐
相关产品推荐

