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

React Accordion过渡效果实现遇阻,寻求解决方案

React Accordion 展开/收起过渡与图标旋转实现方案

现有代码

JSX 结构

<div className="accordion-item">
    <h2 className="accordion-header">
       <button className={`accordion-button ${!showAccordion ? "collapsed" : ""}`} onClick={() => setShowAccordion(!showAccordion)}>
          Sample Text
       </button>
    </h2>
    <div className={`accordion-collapse collapse ${showAccordion ? "show" : ""}`}>
       <div className="accordion-body">
          <p>
               Example Text
          </p>
       </div>
    </div>
</div>

样式文件(styles.css)

.accordion-button{
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    text-align: left;
    background-color: #fff;
    border: 0;
    border-radius: 0;
    padding: 20px 24px;
    font-weight: 500;
    font-size: 18px;
    line-height: 1.3333333333;
    color: var(--bs-gray-900);
    transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
}
.accordion-button::after{
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    margin-left: auto;
    content: "";
    background-repeat: no-repeat;
    background-size: 1.25rem;
    background-image: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M3.125 10H16.875' stroke='%2377878F' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M10 3.125V16.875' stroke='%2377878F' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round'/%3E%3C/svg%3E");
    transition: transform .2s ease-in-out;
}
.accordion-button:not(.collapsed){
    border: 1px solid var(--bs-primary-500);
    box-shadow: none;
    background: var(--bs-primary-500);
    color: white;
}
.accordion-button:not(.collapsed)::after{
    background-image: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M3.125 10H16.875' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.collapse:not(.show){
  display: none;
}

问题说明

当前实现中,折叠区域使用display: none无法触发过渡动画,按钮图标也没有旋转效果,需解决这两个问题。

解决方案


1. 实现图标旋转动画

给展开状态的按钮图标添加旋转样式,修改CSS中.accordion-button:not(.collapsed)::after规则:

.accordion-button:not(.collapsed)::after{
    background-image: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M3.125 10H16.875' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    /* 添加旋转效果 */
    transform: rotate(90deg);
}

可根据图标设计调整旋转角度,比如从十字转横线用90度,若需要其他动画逻辑,也可调整为rotate(45deg)等数值。

2. 实现折叠区域的展开/收起过渡效果

display: none会直接移除元素,无法触发过渡,改用max-height+opacity结合过渡实现:

/* 重置折叠容器基础样式,默认收起状态 */
.collapse {
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    transition: max-height 0.3s ease-in-out, opacity 0.2s ease-in-out;
}

/* 展开状态样式 */
.collapse.show {
    max-height: 1000px; /* 设置足够大的值覆盖内容高度 */
    opacity: 1;
}

/* 移除原有的display: none规则 */
/* .collapse:not(.show){ display: none; } */

若内容高度不确定,设置一个足够大的max-height即可满足大部分场景;如果需要精确高度,可通过React动态计算内容高度后绑定到样式上。

3. 优化过渡体验(可选)

给.accordion-body添加上下内边距的过渡,让展开时内容更平滑:

.accordion-body {
    padding: 0 24px;
    transition: padding 0.2s ease-in-out;
}

.collapse.show .accordion-body {
    padding: 20px 24px;
}

收起时内容内边距为0,展开时恢复内边距,配合容器的max-height过渡,整体动画更自然。


内容的提问来源于stack exchange,提问作者Programming MERN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:17:09