You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:55:23