仅使用 HTML+CSS 创建 tabs 布局

项目背景

我有一个用 webView2 做界面的桌面软件,其中有个配置页,因为内容较多,需要用 tabs 布局。 之前是使用 Bootstrap 的 CSS+JS 实现的。 今天我想使用 Tailwind CSS 重构此页面, 查了下教程, 找到了不使用 JS,纯 CSS 的实现方法,特此记录下学习过程。

实现过程

先在 html 中定义文档结构,主要是 4 个 tab-content 块,4 个控制标签切换的 input 和 4 个用于遥控的 label 标签。

<input type="radio" id="tab1" name="tab" class="hidden" checked />
<input type="radio" id="tab2" name="tab" class="hidden" />
<input type="radio" id="tab3" name="tab" class="hidden" />
<input type="radio" id="tab4" name="tab" class="hidden" />

<div class="my-10 border-b border-gray-200" id="nav">
  <nav class="-mb-px flex h-10">
    <label for="tab1" class="tab-label">tab1</label>
    <label for="tab2" class="tab-label">tab2</label>
    <label for="tab3" class="tab-label">tab3</label>
    <label for="tab4" class="tab-label">tab4</label>
  </nav>
</div>

<div id="tab-content1" class="tab-content">tab-content1</div>
<div id="tab-content2" class="tab-content">tab-content2</div>
<div id="tab-content3" class="tab-content">tab-content3</div>
<div id="tab-content4" class="tab-content">tab-content4</div>

实现原理就是,利用 input 的:checked 选择器,选中时显示 tab-content,未选中时默认隐藏。 然后将 input 都隐藏起来,再用 label 来美化成 tab 标签,通过 label 的 for 属性遥控 input。

CSS 样式如下:

#tab1:checked ~ #tab-content1 {
  @apply block;
}

#tab2:checked ~ #tab-content2 {
  @apply block;
}

#tab3:checked ~ #tab-content3 {
  @apply block;
}

#tab4:checked ~ #tab-content4 {
  @apply block;
}

.tab-content {
  @apply hidden h-28 w-full;
}

.tab-label {
  @apply w-1/4 cursor-pointer border-b-2 border-transparent px-1 text-center 
  text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700;
}

#tab1:checked ~ #nav > nav > label:nth-child(1) {
  @apply border-indigo-500 text-indigo-600;
}

#tab2:checked ~ #nav > nav > label:nth-child(2) {
  @apply border-indigo-500 text-indigo-600;
}

#tab3:checked ~ #nav > nav > label:nth-child(3) {
  @apply border-indigo-500 text-indigo-600;
}

#tab4:checked ~ #nav > nav > label:nth-child(4) {
  @apply border-indigo-500 text-indigo-600;
}

What I Learned

  • CSS 中:checked 伪类选择器和通用兄弟关系选择器(~)
  • 利用 label 标签的 for 属性,遥控隐藏的 input 按钮。