Tailwind CSS 折叠面板

在传统前端开发中,如果想要实现一个折叠面板效果,我们需要使用 JavaScript 来监听点击事件并改变元素高度。而在 Tailwind CSS 中,我们则提倡 “能用 CSS 解决的就不用 JavaScript”。

Tailwind CSS 折叠面板原理

在 Tailwind CSS 中,如果想要实现折叠面板,主要有以下 2 种思路:

1. 原生标签法(极简)

使用 HTML5 自带的 detailssummary 标签。这种方式的好处是浏览器原生支持,语义化更好,并且完全不需要任何逻辑代码。

2. 复选框状态法(高级)

使用一个隐藏的 <input type="checkbox"> 配合 Tailwind 的 peer 修饰符,然后通过监听复选框的 checked 状态,来动态改变下方内容区域的高度和显示状态。

Tailwind CSS 折叠面板示例

接下来,我们通过几个简单的例子来讲解一下如何使用 Tailwind CSS 来实现折叠面板效果。

示例 1:FAQ 折叠

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
</head>
<body class="p-10 bg-green-50">
    <div class="w-full max-w-md space-y-4">
        <h2 class="mb-6 text-2xl font-black text-emerald-900 text-center">常见问题</h2>
        <details class="group bg-white rounded-2xl border border-emerald-100 shadow-sm overflow-hidden">
            <summary class="flex items-center justify-between p-5 font-bold text-emerald-900 cursor-pointer list-none">
                <span>绿叶网的教程,适合 0 基础小白学习吗?</span>
                <svg class="w-5 h-5 text-emerald-500 transition-transform duration-300 group-open:rotate-180" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"></path>
                </svg>
            </summary>
            <div class="px-5 pb-5 text-emerald-800/70 text-sm leading-relaxed border-t border-emerald-50 pt-4">
                那必须的。绿叶网专注于教程的易懂性,让完全 0 基础的小白也能更快上手。
            </div>
        </details>
    </div>
</body>
</html>

默认情况下,页面效果如下图 1 所示。当点击选项时,页面效果如下图 2 所示。

Tailwind CSS FAQ 折叠(1)

Tailwind CSS FAQ 折叠(2)

分析:

在这个例子中,我们利用了 Tailwind CSS v4 的一个小技巧:group-open

当 details 标签展开时,它会自动带上一个 open 属性。Tailwind CSS 能够捕捉到这个状态。

我们通过给父级设置 group,然后在箭头图标上写 group-open:rotate-180,就实现了点击时箭头自动旋转的平滑动效,完全不需要编写一行 JavaScript。

示例 2:peer 状态切换(纯 CSS 交互)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
</head>
<body class="p-10 bg-emerald-800">
    <div class="w-full max-w-md bg-white/10 backdrop-blur-md rounded-3xl p-2 border border-white/20">
        <label class="relative block cursor-pointer">
            <input type="checkbox" class="peer hidden">
            <div class="flex items-center justify-between p-4 text-white font-bold bg-white/5 rounded-2xl hover:bg-white/10 transition-all">
                <span>Vue 快速上手</span>
                <span class="text-2xl transition-transform duration-300 peer-checked:rotate-45">+</span>
            </div>
            <div class="max-h-0 overflow-hidden transition-all duration-500 ease-in-out peer-checked:max-h-40">
                <div class="p-4 text-white/70 text-sm">
                    从最基础的 Vue 语法入手,每一个知识点都 “掰开揉碎”。用通俗易懂的方式来讲解,让 0 基础小白能够快速上手。知识点全面、系统、有深度,让老手也能收获满满!
                </div>
            </div>
        </label>
    </div>
</body>
</html>

Tailwind CSS peer 状态切换(1)

Tailwind CSS peer 状态切换(2)

分析:

在这个例子中,首先我们通过 “peer” 类名标记了隐藏的 input 标签。接下来重点在于 “peer-checked:max-h-40”。

当复选框被勾选时(即用户点击了 label 区域),它会触发下方兄弟元素的样式变化。这种方式的灵活性非常高,我们可以用它来控制任何复杂的交互组合。

常见问题

1. 为什么我的折叠面板展开时没有平滑动画?

如果你使用的是 display: none 和 display: block 的切换,浏览器是无法计算中间过渡状态的。为了实现丝滑的展开效果,我们通常会使用 max-h-0 到 max-h-{size} 的高度过渡,或者改变 grid-template-rows 的比例。

2. 多个折叠面板如何实现 “互斥”(开一个关另一个)呢?

对于原生方案,我们只需要给多个 details 标签设置相同的 name 属性(如 name="faq"),浏览器就会自动帮你实现这种 “手风琴” 互斥效果。

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号