掌握 Hover (悬停) 状态的设计原则,利用颜色和变换提供即时视觉反馈。
深入理解 Focus (焦点) 管理,构建符合无障碍标准(Accessibility)的表单和导航体验。
熟练运用 Active (激活) 状态模拟物理按压感,提升按钮的触觉反馈。
正确处理 Disabled (禁用) 状态,通过样式和光标明确告知用户元素不可用。
学会自定义 Cursor (光标) 和 User Select (文本选择),优化特定场景下的用户操作体验。
能够组合多种交互状态,制作出专业、流畅且易于访问的 UI 组件。
悬停是桌面端交互的核心,用于提示用户“此元素可点击”或展示更多细节。
颜色变化: hover:bg-blue-700, hover:text-white, hover:border-red-500。
组合变换: 常与 transition 和 transform 配合,如 hover:scale-105。
伪类链式调用: Tailwind 允许链式使用,如 group-hover: (父元素悬停时触发子元素变化)。
按钮与卡片悬停效果
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Tailwind Auto Cols 对比演示</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="p-8 bg-gray-50 space-y-8">
<!-- 场景 1: 基础按钮悬停 -->
<div class="flex flex-wrap gap-4">
<button
class="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg transition-colors duration-200 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
标准悬停 (Hover Color)
</button>
<button
class="px-6 py-2 bg-white text-gray-700 border border-gray-300 font-medium rounded-lg shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md hover:-translate-y-0.5">
立体悬停 (Hover Lift)
</button>
</div>
<!-- 场景 2: 卡片悬停 (Group Hover) -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div
class="group bg-white rounded-xl shadow-md overflow-hidden cursor-pointer transition-shadow duration-300 hover:shadow-xl">
<div class="h-40 bg-gray-200 relative overflow-hidden">
<img src="https://zhanweifu.com/600x400/cccccc/ffffff" alt="Card Image"
class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110">
<!-- 悬停时显示的遮罩 -->
<div
class="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
<span
class="text-white font-bold px-4 py-2 border border-white rounded-full transform translate-y-4 group-hover:translate-y-0 transition-transform duration-300">查看详情</span>
</div>
</div>
<div class="p-4">
<h3 class="font-bold text-gray-900 group-hover:text-blue-600 transition-colors">项目标题</h3>
<p class="text-sm text-gray-500 mt-1">鼠标悬停时,图片放大,遮罩浮现,标题变色。</p>
</div>
</div>
</div>
</div>
</body>
</html>焦点状态对于键盘导航用户至关重要。忽略焦点样式会导致键盘用户无法知道当前选中了哪个元素。
移除默认轮廓: focus:outline-none (慎用,必须替换为自定义样式)。
自定义光环: focus:ring-2, focus:ring-blue-500, focus:ring-offset-2。
环的位置: focus:ring 默认在元素内部,focus:ring-offset 可以在元素和外环之间创造间隙。
表单输入框的焦点优化
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Tailwind Auto Cols 对比演示</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="p-8 bg-white rounded-xl shadow max-w-md space-y-6">
<h3 class="text-lg font-bold text-gray-800">表单焦点演示</h3>
<!-- 场景 1: 错误的做法 (移除了 outline 但没有替代) -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">错误示范 (无焦点样式)</label>
<input type="text" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none"
placeholder="按 Tab 键试试...">
<p class="text-xs text-red-500">警告:键盘用户无法看到此输入框是否被选中!</p>
</div>
<!-- 场景 2: 标准做法 (自定义 Ring) -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">标准示范 (Ring + Offset)</label>
<input type="text"
class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:border-transparent transition-shadow"
placeholder="按 Tab 键试试...">
<p class="text-xs text-green-600">清晰可见的蓝色光环,且与原边框有间隙。</p>
</div>
<!-- 场景 3: 不同颜色的焦点 -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">成功状态焦点</label>
<input type="text" value="验证通过"
class="w-full border border-green-300 bg-green-50 text-green-900 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2">
</div>
</div>
</body>
</html>active 状态仅在鼠标按下(未松开)或触摸屏触摸时生效,用于提供“被按下”的即时反馈。
颜色加深: active:bg-blue-800 (比 hover 更深)。
尺寸缩小: active:scale-95 (模拟按钮被压下去的物理形变)。
阴影消失: active:shadow-inner 或 active:shadow-none。
具有触感的按钮
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Tailwind Auto Cols 对比演示</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="p-8 bg-gray-100 flex flex-wrap gap-6 justify-center">
<!-- 场景 1: 颜色反馈 -->
<button
class="px-6 py-3 bg-indigo-600 text-white font-bold rounded-lg shadow-md transition-colors duration-100 hover:bg-indigo-700 active:bg-indigo-900">
颜色加深 (Active Darker)
</button>
<!-- 场景 2: 物理按压感 (推荐组合) -->
<button
class="px-6 py-3 bg-emerald-600 text-white font-bold rounded-lg shadow-md transition-all duration-100 hover:shadow-lg hover:-translate-y-0.5 active:shadow-none active:translate-y-0 active:scale-95">
物理按压 (Scale Down)
</button>
<!-- 场景 3: 内部凹陷感 -->
<button
class="px-6 py-3 bg-amber-500 text-white font-bold rounded-lg border-b-4 border-amber-700 active:border-b-0 active:translate-y-1 transition-all duration-75">
复古凹陷 (Border Trick)
</button>
</div>
</body>
</html>明确告知用户某些操作当前不可用,避免无效点击。
样式: disabled:opacity-50, disabled:grayscale。
交互: disabled:cursor-not-allowed, disabled:pointer-events-none (彻底禁止点击事件穿透)。
注意: HTML 原生 disabled 属性会使表单元素无法提交,但普通 <div> 或 <a> 标签没有 disabled 属性,需靠 JS 控制类名或使用 aria-disabled。
cursor-pointer: 手型,表示可点击。
cursor-wait: 沙漏 / 旋转圈,表示加载中。
cursor-not-allowed: 禁止符号,表示不可操作。
cursor-default: 默认箭头。
cursor-text: 工字型,表示可选中文本。
表单禁用与加载状态
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Tailwind Auto Cols 对比演示</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="p-8 bg-white rounded-xl shadow space-y-8">
<!-- 场景 1: 禁用按钮 -->
<div class="flex gap-4 items-center">
<button disabled
class="px-6 py-2 bg-blue-600 text-white font-medium rounded-lg disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none">
提交表单 (Disabled)
</button>
<span class="text-sm text-gray-500">无法点击,光标显示为禁止符号。</span>
</div>
<!-- 场景 2: 加载状态光标 -->
<div class="flex gap-4 items-center">
<button class="px-6 py-2 bg-gray-800 text-white font-medium rounded-lg cursor-wait flex items-center gap-2">
<svg class="animate-spin h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
</path>
</svg>
处理中...
</button>
<span class="text-sm text-gray-500">光标变为等待状态 (cursor-wait)。</span>
</div>
<!-- 场景 3: 文本选择控制 -->
<div class="border p-4 rounded bg-gray-50">
<p class="mb-2 font-bold text-gray-700">文本选择控制:</p>
<p class="select-text mb-2">这段文字可以被正常选中 (select-text)。</p>
<p class="select-none mb-2 user-select-none bg-yellow-100 p-2 rounded">这段文字无法被选中
(select-none),常用于防止用户误选图标或按钮文字。</p>
<p class="select-all bg-blue-50 p-2 rounded">点击这里会全选整段文字 (select-all)。</p>
</div>
</div>
</body>
</html>