纯CSS实现Accordion组件:点击h2保持展开并切换内容需求
纯CSS实现互斥手风琴(点击保持+动画)
核心思路
利用CSS的:target伪类实现点击后的持久状态,结合兄弟选择器实现互斥关闭逻辑,用max-height和opacity替代display属性实现平滑开合动画(display无法支持过渡动画效果)。
实现步骤
1. 补充HTML标识(若允许修改)
:target伪类需要元素带有唯一ID才能生效,若页面原有h2未设置ID,需补充唯一标识(示例如下):
<h2 id="accordion-1">+ Accordion 1</h2> <p>This is the first paragraph. It is hidden by default and will be shown when the heading is clicked.</p> <p>This is the first paragraph. It is hidden by default and will be shown when the heading is clicked.</p> <p>This is the first paragraph. It is hidden by default and will be shown when the heading is clicked.</p> <h2 id="accordion-2">+ Accordion 2</h2> <p>This is the second paragraph. It is hidden by default and will be shown when the heading is clicked.</p> <h2 id="accordion-3">+ Accordion 3</h2> <p>This is the third paragraph. It is hidden by default and will be shown when the heading is clicked.</p>
2. 纯CSS实现代码(仅需上传此文件)
/* 手风琴标题基础样式 */ h2 { cursor: pointer; padding: 10px; background-color: #f1f1f1; margin: 0 0 1px; border: 1px solid #ccc; font-size: 18px; font-weight: bold; position: relative; } /* 标题点击后的激活状态 */ h2:target { background-color: #ddd; } /* 展开/收起图标及动画 */ h2::after { content: "+"; position: absolute; right: 15px; transition: transform 0.3s ease; } h2:target::after { transform: rotate(45deg); } /* 段落默认隐藏状态(带动画基础) */ h2 ~ p { padding: 0 10px; max-height: 0; opacity: 0; margin: 0; background-color: #f9f9f9; overflow: hidden; transition: max-height 0.5s ease, opacity 0.3s ease; border-left: 1px solid #ccc; border-right: 1px solid #ccc; } /* 最后一段添加底部边框,保证视觉完整性 */ h2 ~ p:last-of-type { border-bottom: 1px solid #ccc; margin-bottom: 8px; } /* 点击当前标题时,展开其下方所有段落 */ h2:target ~ p { max-height: 2000px; /* 设置足够大的值适配内容高度 */ opacity: 1; padding: 10px; } /* 互斥逻辑:点击其他标题时,关闭之前展开的所有段落 */ h2:target ~ h2 ~ p { max-height: 0; opacity: 0; padding: 0 10px; }
3. 无法修改HTML的替代方案
若完全不能调整HTML结构,可使用:focus-within结合CSS强制设置tabindex实现(需浏览器支持该特性):
h2 { cursor: pointer; padding: 10px; background-color: #f1f1f1; margin: 0 0 1px; border: 1px solid #ccc; font-size: 18px; font-weight: bold; position: relative; /* 强制让h2获得焦点能力 */ tab-index: 0; outline: none; } h2:focus { background-color: #ddd; } h2::after { content: "+"; position: absolute; right: 15px; transition: transform 0.3s ease; } h2:focus::after { transform: rotate(45deg); } h2 ~ p { padding: 0 10px; max-height: 0; opacity: 0; margin: 0; background-color: #f9f9f9; overflow: hidden; transition: max-height 0.5s ease, opacity 0.3s ease; border-left: 1px solid #ccc; border-right: 1px solid #ccc; } h2 ~ p:last-of-type { border-bottom: 1px solid #ccc; margin-bottom: 8px; } h2:focus ~ p { max-height: 2000px; opacity: 1; padding: 10px; } h2:focus ~ h2 ~ p { max-height: 0; opacity: 0; padding: 0 10px; }
效果说明
- 点击任意h2,其下方所有段落平滑展开,标题样式变化,图标旋转
- 点击另一个h2,之前展开的段落自动平滑收起,新标题对应的段落展开
- 全程无需JavaScript,仅通过CSS实现状态控制和动画
内容的提问来源于stack exchange,提问作者Mellad
相关产品推荐
相关产品推荐

