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
相关产品推荐
相关产品推荐

