SnippetUI

自定CSS逼ま手琖琴(一般看问题答案)

不使用JavaScript,不使用HTML细节/摘要元素,CSS,实用的功能,高度自由的移动,以及缺点(常见问题)。

HTMLCSS

通过使用HTML5中引入的 <details><summary> 元素,完全不需要编写JavaScript,即可实现可展开/折叠的手风琴组件。它对SEO友好,并且标准支持键盘操作(无障碍访问)。

演示

这个手风琴的特点是什么?

不使用JavaScript,仅用HTML标准功能和CSS构建。非常轻量,且在SEO和无障碍访问(如支持键盘操作)方面也非常优秀。

可以同时打开多个项目吗?

通过将 name 属性设置为相同的值(在本例中为 name=“faq”),可以实现互斥控制,即打开一个项目时其他项目会自动关闭。如果希望可以同时打开多个,请删除 name 属性。

动画是如何实现的?

使用CSS的 transition@keyframes 实现了图标的旋转动画和内容的淡入效果。

代码

<div class="accordion-container">
  <details class="accordion" name="faq">
    <summary class="accordion-summary">
      这个手风琴的特点是什么?
      <span class="icon"></span>
    </summary>
    <div class="accordion-content">
      <p>不使用JavaScript,仅用HTML标准功能和CSS构建。非常轻量,且在SEO和无障碍访问(如支持键盘操作)方面也非常优秀。</p>
    </div>
  </details>
  
  <details class="accordion" name="faq">
    <summary class="accordion-summary">
      可以同时打开多个项目吗?
      <span class="icon"></span>
    </summary>
    <div class="accordion-content">
      <p>通过将name属性设置为相同的值,可以实现互斥控制(打开一个时另一个关闭)。</p>
    </div>
  </details>
</div>
/* 容器的样式 */
.accordion-container {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}

/* 手风琴主体 */
.accordion {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background-color: #ffffff;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}

/* 摘要(标题)的样式 */
.accordion-summary {
  padding: 1.25rem 1.5rem;
  font-weight: 600;
  font-size: 1.05rem;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  list-style: none; /* 隐藏默认的三角形标记 */
  color: #1e293b;
  transition: background-color 0.2s ease;
  user-select: none;
}

/* 面向Safari的默认三角形标记隐藏 */
.accordion-summary::-webkit-details-marker {
  display: none;
}

.accordion-summary:hover {
  background-color: #f8fafc;
}

/* 打开状态下摘要的下划线 */
.accordion[open] .accordion-summary {
  border-bottom: 1px solid #e2e8f0;
}

/* 开闭图标的样式 */
.icon {
  position: relative;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-left: 1rem;
}

/* 图标的横线和竖线 */
.icon::before,
.icon::after {
  content: '';
  position: absolute;
  background-color: #64748b;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  border-radius: 2px;
}

.icon::before {
  width: 16px;
  height: 2px;
}

.icon::after {
  width: 2px;
  height: 16px;
}

/* 手风琴打开时的动画(+变成-) */
.accordion[open] .icon::after {
  transform: rotate(90deg) scaleY(0);
}

.accordion[open] .icon::before {
  background-color: #3b82f6;
}

/* 内容部分的样式 */
.accordion-content {
  padding: 1.5rem;
  color: #475569;
  line-height: 1.6;
  animation: fadeDown 0.3s ease-out forwards;
}

.accordion-content p {
  margin: 0;
}

/* 柔和显示的动画 */
@keyframes fadeDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

实现要点

  1. 活用 <details><summary> 元素: 通过使用这些元素,无需编写如点击事件或状态管理等任何JavaScript代码,即可实现开闭功能。
  2. 隐藏默认箭头图标: 通过指定 list-style: none;::-webkit-details-marker { display: none; },隐藏了浏览器标准的三角形图标,替换为您自己独特的时尚图标。
  3. 基于 name 属性的互斥控制: 通过给多个 name 元素赋予相同的 <details> 属性,能够仅用HTML实现“打开一个就会自动关闭其他项目”的所谓“手风琴”行为(这是相对较新的规范)。
  4. CSS动画: 展开时的淡入效果(@keyframes)以及加号(+)变为减号(-)的图标动画(transition)均仅用CSS实现,提供丰富的用户体验。