Skip to content

Tailwind CSS - 悬停、焦点及其他状态

现代 Web 界面是交互式的。Tailwind CSS 擅长通过强大的状态修饰符系统来样式化这些交互。这些修饰符,例如 hover:、focus: 和 group-hover:,作为前缀添加到工具类上,以便在元素处于特定状态时有条件地应用样式。

本章提供了一份全面的指南,帮助您掌握 Tailwind 中的状态管理,从简单的悬停效果到涉及父、兄弟和后代元素的复杂交互,所有这些都优先考虑了可访问性。

伪类根据元素的当前状态(例如悬停、聚焦或激活)来定位元素。

这些是用于按钮和链接等交互式元素最常见的状态修饰符。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>Hover, Focus, Active States</title>
</head>
<body class="bg-slate-100 p-8 flex justify-center items-center">
<button class="px-8 py-4 bg-violet-600 text-white font-semibold rounded-lg shadow-lg
transition-all duration-200 ease-in-out
hover:bg-violet-700 hover:-translate-y-1
focus:outline-none focus:ring-4 focus:ring-violet-400 focus:ring-opacity-75
active:bg-violet-800 active:translate-y-0">
Click or Tab to Me
</button>
</body>
</html>

可访问性提示:对于焦点环,请使用 focus-visible: 而不是 focus:。focus-visible: 只为键盘用户显示焦点轮廓,这对于鼠标用户来说视觉侵扰较小,但对可访问性至关重要。

根据元素在文档树中的位置来样式化元素,例如 first:、last:、odd: 和 even:。这非常适合样式化列表和表格。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>Positional Styling</title>
</head>
<body class="bg-gray-50 p-8">
<ul class="max-w-md mx-auto bg-white rounded-lg shadow overflow-hidden">
<li class="p-4 border-b border-gray-200 first:pt-6 last:border-b-0 odd:bg-gray-50 even:bg-white">
List Item 1
</li>
<li class="p-4 border-b border-gray-200 first:pt-6 last:border-b-0 odd:bg-gray-50 even:bg-white">
List Item 2
</li>
<li class="p-4 border-b border-gray-200 first:pt-6 last:border-b-0 odd:bg-gray-50 even:bg-white">
List Item 3
</li>
<li class="p-4 border-b border-gray-200 first:pt-6 last:border-b-0 odd:bg-gray-50 even:bg-white">
List Item 4
</li>
</ul>
</body>
</html>

使用 disabled:、required:、invalid: 和 checked: 等状态修饰符为表单元素提供清晰的视觉反馈。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>Form States</title>
</head>
<body class="bg-gray-100 p-8">
<form class="max-w-lg mx-auto bg-white p-8 rounded-xl shadow-lg space-y-6">
<div>
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="email" required
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm
focus:outline-none focus:ring-indigo-500 focus:border-indigo-500
invalid:border-pink-500 invalid:text-pink-600
focus:invalid:border-pink-500 focus:invalid:ring-pink-500"/>
<p class="mt-2 invisible peer-invalid:visible text-pink-600 text-sm">
Please provide a valid email address.
</p>
</div>
<div>
<label for="username" class="block text-sm font-medium text-gray-700">Username (Disabled)</label>
<input type="text" id="username" disabled value="readonly-user"
class="mt-1 block w-full px-3 py-2 rounded-md shadow-sm bg-gray-100
disabled:border-gray-200 disabled:text-gray-500 disabled:cursor-not-allowed"/>
</div>
</form>
</body>
</html>

2. 组和同级:基于关系进行样式化

Section titled “2. 组和同级:基于关系进行样式化”

group 和 peer 是强大的特性,它们允许您根据相关元素的状态来样式化一个元素,而无需任何 JavaScript。

基于父元素状态进行样式化 (group-hover)

Section titled “基于父元素状态进行样式化 (group-hover)”

将 group 类添加到父元素。现在,您可以在任何子元素上使用 group-hover:、group-focus: 等,以便在父元素处于该状态时对其进行样式化。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>Group Hover Example</title>
</head>
<body class="bg-slate-100 p-8 flex justify-center">
<a href="#" class="group block max-w-sm p-6 bg-white rounded-lg border border-gray-200 shadow-md hover:bg-gray-100">
<h5 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 group-hover:text-blue-600 transition-colors duration-200">
Card Title
</h5>
<p class="font-normal text-gray-700 group-hover:text-gray-800 transition-colors duration-200">
When you hover over the card (the parent group), the title turns blue and this text darkens.
</p>
<div class="mt-4 opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<span class="text-blue-600 font-semibold">Read more &rarr;</span>
</div>
</a>
</body>
</html>

基于同级元素状态进行样式化 (peer-checked)

Section titled “基于同级元素状态进行样式化 (peer-checked)”

将 peer 类添加到元素(如输入框)。现在,您可以在后续的同级元素上使用 peer-checked: 或 peer-invalid: 等修饰符,根据 peer 元素的状态对其进行样式化。这对于创建自定义表单控件非常有用。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>Peer Checked Example</title>
</head>
<body class="bg-gray-100 p-8 flex justify-center">
<label for="toggle" class="flex items-center cursor-pointer">
<!-- The peer element -->
<input type="checkbox" id="toggle" class="sr-only peer">
<!-- The element that will be styled -->
<div class="relative w-11 h-6 bg-gray-200 rounded-full
peer-focus:ring-4 peer-focus:ring-blue-300
peer-checked:after:translate-x-full peer-checked:after:border-white
peer-checked:bg-blue-600
after:content-[''] after:absolute after:top-0.5 after:left-[2px]
after:bg-white after:border-gray-300 after:border after:rounded-full
after:h-5 after:w-5 after:transition-all">
</div>
<span class="ml-3 text-sm font-medium text-gray-900 peer-checked:text-blue-600">
Enable Feature
</span>
</label>
</body>
</html>

重要提示:peer-* 修饰符仅适用于 HTML 中 peer 元素之后的元素。

3. 伪元素:样式化元素的特定部分

Section titled “3. 伪元素:样式化元素的特定部分”

伪元素样式化元素的特定部分,例如第一行、列表标记或占位符文本。

  • before: 和 after::在元素的实际内容之前或之后添加内容。常用于装饰。示例:before:content-['*'] before:text-red-500。
  • placeholder::样式化输入框的占位符文本。示例:placeholder:text-gray-400。
  • file::样式化文件输入框的按钮部分。示例:file:bg-blue-50 file:text-blue-700。
  • marker::样式化列表项的圆点或数字。示例:marker:text-sky-500。
  • selection::样式化用户选择文本的外观。示例:selection:bg-yellow-300。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>Pseudo-elements Example</title>
</head>
<body class="p-8 bg-slate-50 selection:bg-fuchsia-300 selection:text-fuchsia-900">
<div class="max-w-lg mx-auto space-y-4">
<ul class="list-disc list-inside space-y-2 marker:text-green-600">
<li>First item</li>
<li>Second item</li>
</ul>
<input type="text" placeholder="I have custom placeholder text..."
class="w-full p-2 border rounded placeholder:italic placeholder:text-slate-400"/>
</div>
</body>
</html>

这些修饰符根据环境(如视口大小或用户偏好)应用样式。

  • 响应式断点 (sm:、md:、lg: 等):Tailwind 响应式设计的基石。在特定的最小视口宽度下应用样式。
  • 深色模式 (dark:):当用户偏好深色配色方案时应用样式。
  • 减少动画 (motion-reduce:、motion-safe:):根据用户的动画偏好调整动画,以提高可访问性。
  • 打印 (print:):专门定义页面打印时的样式。
<!DOCTYPE html>
<!-- 要测试深色模式,您可以将 class="dark" 添加到 html 标签 -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>Media Queries Example</title>
</head>
<body class="bg-white dark:bg-slate-900">
<div class="p-4 sm:p-6 md:p-8">
<div class="text-center md:text-left">
<h1 class="text-2xl md:text-4xl font-bold text-slate-900 dark:text-white">
Responsive & Dark Mode Ready
</h1>
<p class="mt-4 text-slate-600 dark:text-slate-400 print:hidden">
This text changes alignment on medium screens and up. The colors adapt to light/dark mode. This paragraph is hidden when printing.
</p>
<button class="mt-6 px-4 py-2 bg-blue-600 text-white rounded-lg transition-transform motion-safe:hover:scale-110 motion-reduce:hover:opacity-80">
I animate safely
</button>
</div>
</div>
</body>
</html>

5. 属性选择器 (aria-*、data-*、open)

Section titled “5. 属性选择器 (aria-*、data-*、open)”

根据 HTML 属性的存在或值应用样式。这对于可访问组件和自定义状态管理至关重要。

  • ARIA 状态 (aria-checked:、aria-disabled:):根据元素的无障碍状态进行样式化。
  • 数据属性 (data-[state=active]:):根据自定义 data-* 属性样式化元素。这对于 JavaScript 驱动的状态很有用。
  • 打开/关闭状态 (open:):样式化处于打开状态的 <details> 和 <dialog> 元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>Attribute Selectors</title>
</head>
<body class="bg-gray-100 p-8">
<details class="max-w-lg mx-auto bg-white rounded-lg shadow-md open:ring-2 open:ring-blue-500">
<summary class="p-4 font-semibold cursor-pointer select-none">
Click to Open
</summary>
<div class="p-4 border-t border-gray-200">
This content is visible when the 'open' attribute is present.
</div>
</details>
</body>
</html>
  • group 或 peer 不起作用?:请记住 peer 必须是前一个同级元素,而不是父元素或后一个同级元素。group 必须是您使用 group-hover: 等样式化的元素的祖先元素(通常是直接父元素)。
  • 堆叠修饰符的顺序很重要:像 dark:hover:bg-gray-800 这样的修饰符顺序会生成特定的 CSS 选择器。dark 在前意味着它会在父元素中查找 .dark 类,然后查找其中的悬停元素。hover:dark:bg-gray-800 则会查找自身也带有 .dark 类的悬停元素。对于 group 和 peer,状态修饰符(group-hover、peer-checked)通常放在前面。
  • 任意变体需要 JIT:data-[state=active]: 或 group-has-[:focus]: 等特性是 JIT(即时)引擎的一部分,该引擎在 Tailwind v3 中默认启用。如果您使用的是旧版本或配置异常,请确保 JIT 已激活。