Tailwind CSS: Tailwind CSS 交互状态:hover/focus/active状态前缀与光标样式

1. 状态前缀概述

Tailwind 使用状态前缀为元素在不同状态下应用样式,无需编写伪类 CSS。

前缀 CSS 伪类 说明
hover: :hover 鼠标悬停
focus: :focus 获得焦点
active: :active 鼠标按下
disabled: :disabled 禁用状态
visited: :visited 已访问链接
first: :first-child 第一个子元素
last: :last-child 最后一个子元素
odd: :nth-child(odd) 奇数子元素
even: :nth-child(even) 偶数子元素

▶ 示例

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>状态前缀演示</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <!-- hover 悬停状态 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">hover 悬停状态</h3>
      <div class="flex gap-4">
        <button class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-700 transition-colors">
          悬停变深
        </button>
        <button class="px-6 py-3 bg-white border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 hover:border-gray-400 transition-colors">
          悬停边框
        </button>
        <button class="px-6 py-3 bg-green-500 text-white rounded-lg hover:shadow-lg hover:shadow-green-500/50 transition-all">
          悬停阴影
        </button>
      </div>
    </div>

    <!-- focus 焦点状态 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">focus 焦点状态</h3>
      <div class="space-y-4">
        <input type="text" placeholder="点击输入框查看焦点效果"
               class="w-full p-3 border border-gray-300 rounded-lg focus:border-blue-500 focus:ring-2 focus:ring-blue-500/50 focus:outline-none transition-all">
        <input type="text" placeholder="自定义焦点阴影"
               class="w-full p-3 border border-gray-300 rounded-lg focus:shadow-lg focus:shadow-purple-500/30 focus:border-purple-500 focus:outline-none transition-all">
      </div>
    </div>

    <!-- active 按下状态 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">active 按下状态</h3>
      <div class="flex gap-4">
        <button class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 active:bg-blue-800 active:scale-95 transition-all">
          按下变深缩小
        </button>
        <button class="px-6 py-3 bg-white border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 active:bg-gray-100 active:scale-95 transition-all">
          按下效果
        </button>
      </div>
    </div>

    <!-- disabled 禁用状态 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">disabled 禁用状态</h3>
      <div class="flex gap-4">
        <button class="px-6 py-3 bg-blue-500 text-white rounded-lg disabled:opacity-50 disabled:cursor-not-allowed">
          可用按钮
        </button>
        <button disabled class="px-6 py-3 bg-blue-500 text-white rounded-lg disabled:opacity-50 disabled:cursor-not-allowed">
          禁用按钮
        </button>
        <input type="text" placeholder="可用输入框"
               class="p-3 border border-gray-300 rounded-lg disabled:bg-gray-100 disabled:cursor-not-allowed">
        <input type="text" disabled placeholder="禁用输入框"
               class="p-3 border border-gray-300 rounded-lg disabled:bg-gray-100 disabled:cursor-not-allowed">
      </div>
    </div>

    <!-- visited 已访问链接 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">visited 已访问链接</h3>
      <div class="flex gap-4">
        <a href="#visited1" class="text-blue-600 hover:text-blue-800 visited:text-purple-600">
          点击后变紫色
        </a>
        <a href="#visited2" class="text-green-600 hover:text-green-800 visited:text-gray-400">
          点击后变灰色
        </a>
      </div>
    </div>
  </div>
</body>
</html>
逻辑代码 73 行(超过 40 行限制,仅展示)

传统 CSS vs Tailwind 传统方式需要编写 button:hover { background-color: ... } 等伪类规则,而 Tailwind 使用 hover:bg-blue-700 等前缀直接声明。

💡 提示: 状态前缀可以组合使用,如 hover:focus:ring-2 表示同时悬停和聚焦时应用样式。


2. 结构化伪类(first/last/odd/even)

结构化伪类前缀用于选择特定位置的子元素。

▶ 示例

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>结构化伪类演示</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <!-- first/last 第一个/最后一个 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">first/last 第一个/最后一个</h3>
      <ul class="space-y-2">
        <li class="p-3 bg-gray-50 rounded first:bg-blue-50 first:text-blue-700 last:bg-green-50 last:text-green-700">
          第一项(first:bg-blue-50)
        </li>
        <li class="p-3 bg-gray-50 rounded first:bg-blue-50 first:text-blue-700 last:bg-green-50 last:text-green-700">
          第二项
        </li>
        <li class="p-3 bg-gray-50 rounded first:bg-blue-50 first:text-blue-700 last:bg-green-50 last:text-green-700">
          第三项
        </li>
        <li class="p-3 bg-gray-50 rounded first:bg-blue-50 first:text-blue-700 last:bg-green-50 last:text-green-700">
          最后一项(last:bg-green-50)
        </li>
      </ul>
    </div>

    <!-- odd/even 奇数/偶数 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">odd/even 奇数/偶数</h3>
      <ul class="space-y-0">
        <li class="p-3 odd:bg-white even:bg-gray-50 border-b">第 1 行(odd:bg-white)</li>
        <li class="p-3 odd:bg-white even:bg-gray-50 border-b">第 2 行(even:bg-gray-50)</li>
        <li class="p-3 odd:bg-white even:bg-gray-50 border-b">第 3 行(odd:bg-white)</li>
        <li class="p-3 odd:bg-white even:bg-gray-50 border-b">第 4 行(even:bg-gray-50)</li>
        <li class="p-3 odd:bg-white even:bg-gray-50 border-b">第 5 行(odd:bg-white)</li>
        <li class="p-3 odd:bg-white even:bg-gray-50">第 6 行(even:bg-gray-50)</li>
      </ul>
    </div>

    <!-- 综合表格 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">表格斑马纹</h3>
      <table class="w-full">
        <thead>
          <tr class="bg-gray-100">
            <th class="p-3 text-left">姓名</th>
            <th class="p-3 text-left">邮箱</th>
            <th class="p-3 text-left">角色</th>
          </tr>
        </thead>
        <tbody>
          <tr class="odd:bg-white even:bg-gray-50 hover:bg-blue-50 transition-colors">
            <td class="p-3">张三</td>
            <td class="p-3">zhangsan@example.com</td>
            <td class="p-3">管理员</td>
          </tr>
          <tr class="odd:bg-white even:bg-gray-50 hover:bg-blue-50 transition-colors">
            <td class="p-3">李四</td>
            <td class="p-3">lisi@example.com</td>
            <td class="p-3">编辑</td>
          </tr>
          <tr class="odd:bg-white even:bg-gray-50 hover:bg-blue-50 transition-colors">
            <td class="p-3">王五</td>
            <td class="p-3">wangwu@example.com</td>
            <td class="p-3">用户</td>
          </tr>
          <tr class="odd:bg-white even:bg-gray-50 hover:bg-blue-50 transition-colors">
            <td class="p-3">赵六</td>
            <td class="p-3">zhaoliu@example.com</td>
            <td class="p-3">用户</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</body>
</html>
逻辑代码 75 行(超过 40 行限制,仅展示)

传统 CSS vs Tailwind 传统方式需要编写 li:first-child { ... }tr:nth-child(even) { ... } 等选择器,而 Tailwind 使用 first:bg-blue-50even:bg-gray-50 等前缀直接声明。


3. group-hover 和 peer

group-hover:peer 用于处理父子或兄弟元素之间的交互状态。

▶ 示例

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>group-hover 和 peer 演示</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <!-- group-hover 父子悬停 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">group-hover 父子悬停</h3>
      <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
        <div class="group bg-gray-50 rounded-lg p-4 cursor-pointer transition-all hover:shadow-lg">
          <div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center mb-3 group-hover:bg-blue-500 transition-colors">
            <span class="text-blue-500 group-hover:text-white transition-colors">🎨</span>
          </div>
          <h4 class="font-semibold group-hover:text-blue-600 transition-colors">设计工具</h4>
          <p class="text-gray-600 text-sm mt-1 group-hover:text-gray-900 transition-colors">悬停父元素查看效果</p>
        </div>
        <div class="group bg-gray-50 rounded-lg p-4 cursor-pointer transition-all hover:shadow-lg">
          <div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center mb-3 group-hover:bg-green-500 transition-colors">
            <span class="text-green-500 group-hover:text-white transition-colors">⚡</span>
          </div>
          <h4 class="font-semibold group-hover:text-green-600 transition-colors">性能优化</h4>
          <p class="text-gray-600 text-sm mt-1 group-hover:text-gray-900 transition-colors">悬停父元素查看效果</p>
        </div>
        <div class="group bg-gray-50 rounded-lg p-4 cursor-pointer transition-all hover:shadow-lg">
          <div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center mb-3 group-hover:bg-purple-500 transition-colors">
            <span class="text-purple-500 group-hover:text-white transition-colors">🔒</span>
          </div>
          <h4 class="font-semibold group-hover:text-purple-600 transition-colors">安全防护</h4>
          <p class="text-gray-600 text-sm mt-1 group-hover:text-gray-900 transition-colors">悬停父元素查看效果</p>
        </div>
      </div>
    </div>

    <!-- group 组合使用 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">group 组合使用</h3>
      <div class="space-y-4">
        <div class="group flex items-center gap-4 p-4 bg-gray-50 rounded-lg hover:bg-blue-50 transition-colors cursor-pointer">
          <div class="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center group-hover:bg-blue-500 transition-colors">
            <svg class="w-5 h-5 text-blue-500 group-hover:text-white transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
            </svg>
          </div>
          <div class="flex-1">
            <h4 class="font-medium group-hover:text-blue-600 transition-colors">菜单项 1</h4>
            <p class="text-sm text-gray-500 group-hover:text-blue-400 transition-colors">描述文字</p>
          </div>
          <svg class="w-5 h-5 text-gray-400 group-hover:text-blue-500 group-hover:translate-x-1 transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
          </svg>
        </div>

        <div class="group flex items-center gap-4 p-4 bg-gray-50 rounded-lg hover:bg-green-50 transition-colors cursor-pointer">
          <div class="w-10 h-10 bg-green-100 rounded-full flex items-center justify-center group-hover:bg-green-500 transition-colors">
            <svg class="w-5 h-5 text-green-500 group-hover:text-white transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
            </svg>
          </div>
          <div class="flex-1">
            <h4 class="font-medium group-hover:text-green-600 transition-colors">菜单项 2</h4>
            <p class="text-sm text-gray-500 group-hover:text-green-400 transition-colors">描述文字</p>
          </div>
          <svg class="w-5 h-5 text-gray-400 group-hover:text-green-500 group-hover:translate-x-1 transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
          </svg>
        </div>
      </div>
    </div>

    <!-- peer 兄弟元素 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">peer 兄弟元素</h3>
      <div class="space-y-4">
        <div>
          <input type="email" id="email" placeholder=" "
                 class="peer w-full p-3 pt-5 border border-gray-300 rounded-lg focus:border-blue-500 focus:ring-2 focus:ring-blue-500/50 focus:outline-none transition-all">
          <label for="email"
                 class="absolute left-3 top-1 text-gray-400 text-sm transition-all peer-placeholder-shown:top-3.5 peer-placeholder-shown:text-base peer-focus:top-1 peer-focus:text-sm peer-focus:text-blue-500">
            邮箱地址
          </label>
        </div>
        <div class="relative">
          <input type="password" id="password" placeholder=" "
                 class="peer w-full p-3 pt-5 border border-gray-300 rounded-lg focus:border-purple-500 focus:ring-2 focus:ring-purple-500/50 focus:outline-none transition-all">
          <label for="password"
                 class="absolute left-3 top-1 text-gray-400 text-sm transition-all peer-placeholder-shown:top-3.5 peer-placeholder-shown:text-base peer-focus:top-1 peer-focus:text-sm peer-focus:text-purple-500">
            密码
          </label>
        </div>
        <div class="flex items-center gap-3">
          <input type="checkbox" id="agree" class="peer sr-only">
          <label for="agree"
                 class="w-5 h-5 border-2 border-gray-300 rounded peer-checked:bg-blue-500 peer-checked:border-blue-500 cursor-pointer transition-colors flex items-center justify-center">
            <svg class="w-3 h-3 text-white opacity-0 peer-checked:opacity-100" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path>
            </svg>
          </label>
          <span class="text-gray-700">我同意服务条款</span>
        </div>
      </div>
    </div>
  </div>
</body>
</html>
逻辑代码 103 行(超过 40 行限制,仅展示)
💡 提示: group 类添加到父元素,group-hover: 前缀用于子元素。peer 类添加到前一个兄弟元素,peer-focus: 等前缀用于后续兄弟元素。


4. 光标样式(cursor-*)

cursor-* 类控制鼠标悬停时的光标样式。

类名 CSS 值 说明
cursor-auto cursor: auto 自动(默认)
cursor-default cursor: default 默认箭头
cursor-pointer cursor: pointer 手型指针
cursor-wait cursor: wait 等待
cursor-text cursor: text 文本选择
cursor-move cursor: move 移动
cursor-not-allowed cursor: not-allowed 禁止
cursor-grab cursor: grab 抓取
cursor-grabbing cursor: grabbing 抓取中
cursor-crosshair cursor: crosshair 十字准星
cursor-zoom-in cursor: zoom-in 放大
cursor-zoom-out cursor: zoom-out 缩小

▶ 示例

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>光标样式演示</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto">
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">光标样式</h3>
      <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-auto">
          <div class="text-2xl mb-2">👆</div>
          <div class="text-sm">cursor-auto</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-default">
          <div class="text-2xl mb-2">👆</div>
          <div class="text-sm">cursor-default</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-pointer">
          <div class="text-2xl mb-2">👆</div>
          <div class="text-sm">cursor-pointer</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-wait">
          <div class="text-2xl mb-2">⏳</div>
          <div class="text-sm">cursor-wait</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-text">
          <div class="text-2xl mb-2">📝</div>
          <div class="text-sm">cursor-text</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-move">
          <div class="text-2xl mb-2">✋</div>
          <div class="text-sm">cursor-move</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-not-allowed">
          <div class="text-2xl mb-2">🚫</div>
          <div class="text-sm">cursor-not-allowed</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-grab">
          <div class="text-2xl mb-2">✊</div>
          <div class="text-sm">cursor-grab</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-grabbing">
          <div class="text-2xl mb-2">✊</div>
          <div class="text-sm">cursor-grabbing</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-crosshair">
          <div class="text-2xl mb-2">➕</div>
          <div class="text-sm">cursor-crosshair</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-zoom-in">
          <div class="text-2xl mb-2">🔍</div>
          <div class="text-sm">cursor-zoom-in</div>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg text-center cursor-zoom-out">
          <div class="text-2xl mb-2">🔍</div>
          <div class="text-sm">cursor-zoom-out</div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>
逻辑代码 66 行(超过 40 行限制,仅展示)

传统 CSS vs Tailwind 传统方式需要编写 cursor: pointer 等 CSS 属性,而 Tailwind 使用 cursor-pointer 类名直接声明。


5. 选择控制(select-*)

select-* 类控制用户是否可以选中文本。

类名 CSS 值 说明
select-none user-select: none 不可选中
select-text user-select: text 可选中(默认)
select-all user-select: all 点击全选
select-auto user-select: auto 自动

▶ 示例

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>选择控制演示</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">选择控制</h3>
      <div class="space-y-4">
        <div class="p-4 bg-gray-50 rounded-lg">
          <p class="text-sm text-gray-500 mb-2">select-none:不可选中</p>
          <p class="select-none">这段文字无法被选中,适合用于按钮、标签等交互元素。</p>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg">
          <p class="text-sm text-gray-500 mb-2">select-text:可选中(默认)</p>
          <p class="select-text">这段文字可以被选中,适合用于正文内容。</p>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg">
          <p class="text-sm text-gray-500 mb-2">select-all:点击全选</p>
          <p class="select-all bg-blue-50 p-2 rounded font-mono">const apiKey = "abc123";</p>
        </div>
      </div>
    </div>

    <!-- 实际应用 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">实际应用</h3>
      <div class="space-y-4">
        <!-- 代码块 -->
        <div class="bg-gray-900 text-green-400 p-4 rounded-lg font-mono text-sm select-all">
          npm install tailwindcss
        </div>
        <!-- 按钮文字不可选中 -->
        <div class="flex gap-4">
          <button class="px-6 py-3 bg-blue-500 text-white rounded-lg select-none cursor-pointer hover:bg-blue-600">
            按钮文字不可选
          </button>
          <button class="px-6 py-3 bg-green-500 text-white rounded-lg select-none cursor-pointer hover:bg-green-600">
            确认提交
          </button>
        </div>
      </div>
    </div>
  </div>
</body>
</html>
逻辑代码 46 行(超过 40 行限制,仅展示)
💡 提示: select-none 常用于按钮、标签等不需要选中文字的元素。select-all 常用于代码块、命令行等需要一键复制的场景。


6. 缩放控制(resize-*)

resize-* 类控制元素是否可以缩放。

类名 CSS 值 说明
resize-none resize: none 不可缩放
resize-y resize: vertical 仅垂直缩放
resize-x resize: horizontal 仅水平缩放
resize resize: both 可缩放

▶ 示例

HTML
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>缩放控制演示</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">缩放控制</h3>
      <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
        <div>
          <p class="text-sm text-gray-500 mb-2">resize-none:不可缩放</p>
          <textarea class="w-full p-3 border border-gray-300 rounded-lg resize-none h-24 focus:outline-none focus:border-blue-500"
                    placeholder="不可缩放的文本框"></textarea>
        </div>
        <div>
          <p class="text-sm text-gray-500 mb-2">resize-y:仅垂直缩放</p>
          <textarea class="w-full p-3 border border-gray-300 rounded-lg resize-y h-24 focus:outline-none focus:border-blue-500"
                    placeholder="可垂直缩放的文本框"></textarea>
        </div>
        <div>
          <p class="text-sm text-gray-500 mb-2">resize-x:仅水平缩放</p>
          <textarea class="w-full p-3 border border-gray-300 rounded-lg resize-x h-24 focus:outline-none focus:border-blue-500"
                    placeholder="可水平缩放的文本框"></textarea>
        </div>
        <div>
          <p class="text-sm text-gray-500 mb-2">resize:可缩放</p>
          <textarea class="w-full p-3 border border-gray-300 rounded-lg resize h-24 focus:outline-none focus:border-blue-500"
                    placeholder="可自由缩放的文本框"></textarea>
        </div>
      </div>
    </div>
  </div>
</body>
</html>
▶ 试一试

传统 CSS vs Tailwind 传统方式需要编写 resize: vertical 等 CSS 属性,而 Tailwind 使用 resize-y 类名直接声明。


7. 滚动行为(scroll-*)

scroll-* 类控制滚动行为。

类名 CSS 值 说明
scroll-auto scroll-behavior: auto 自动(默认)
scroll-smooth scroll-behavior: smooth 平滑滚动
snap-start scroll-snap-align: start 对齐到起点
snap-center scroll-snap-align: center 对齐到中心
snap-end scroll-snap-align: end 对齐到终点
snap-none scroll-snap-type: none 无吸附
snap-x scroll-snap-type: x mandatory 水平吸附
snap-y scroll-snap-type: y mandatory 垂直吸附

▶ 示例

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>滚动行为演示</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <!-- 平滑滚动 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">平滑滚动</h3>
      <div class="flex gap-4 mb-4">
        <a href="#section1" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600">跳转到部分 1</a>
        <a href="#section2" class="px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600">跳转到部分 2</a>
        <a href="#section3" class="px-4 py-2 bg-purple-500 text-white rounded-lg hover:bg-purple-600">跳转到部分 3</a>
      </div>
      <div class="h-48 overflow-y-auto scroll-smooth border rounded-lg">
        <div id="section1" class="p-4 bg-blue-50 h-48 flex items-center justify-center">
          <h4 class="text-xl font-bold text-blue-700">部分 1</h4>
        </div>
        <div id="section2" class="p-4 bg-green-50 h-48 flex items-center justify-center">
          <h4 class="text-xl font-bold text-green-700">部分 2</h4>
        </div>
        <div id="section3" class="p-4 bg-purple-50 h-48 flex items-center justify-center">
          <h4 class="text-xl font-bold text-purple-700">部分 3</h4>
        </div>
      </div>
    </div>

    <!-- 滚动吸附 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">滚动吸附(snap)</h3>
      <div class="flex overflow-x-auto snap-x snap-mandatory gap-4 pb-4">
        <div class="snap-center flex-shrink-0 w-64 h-40 bg-blue-100 rounded-lg flex items-center justify-center">
          <span class="text-blue-700 font-semibold">卡片 1</span>
        </div>
        <div class="snap-center flex-shrink-0 w-64 h-40 bg-green-100 rounded-lg flex items-center justify-center">
          <span class="text-green-700 font-semibold">卡片 2</span>
        </div>
        <div class="snap-center flex-shrink-0 w-64 h-40 bg-purple-100 rounded-lg flex items-center justify-center">
          <span class="text-purple-700 font-semibold">卡片 3</span>
        </div>
        <div class="snap-center flex-shrink-0 w-64 h-40 bg-orange-100 rounded-lg flex items-center justify-center">
          <span class="text-orange-700 font-semibold">卡片 4</span>
        </div>
        <div class="snap-center flex-shrink-0 w-64 h-40 bg-red-100 rounded-lg flex items-center justify-center">
          <span class="text-red-700 font-semibold">卡片 5</span>
        </div>
      </div>
    </div>

    <!-- 滚动条隐藏 -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">滚动条隐藏</h3>
      <div class="flex overflow-x-auto scrollbar-hide gap-4 pb-4">
        <div class="flex-shrink-0 w-48 h-32 bg-gradient-to-br from-blue-400 to-blue-600 rounded-lg flex items-center justify-center text-white">
          隐藏滚动条
        </div>
        <div class="flex-shrink-0 w-48 h-32 bg-gradient-to-br from-green-400 to-green-600 rounded-lg flex items-center justify-center text-white">
          使用 scrollbar-hide
        </div>
        <div class="flex-shrink-0 w-48 h-32 bg-gradient-to-br from-purple-400 to-purple-600 rounded-lg flex items-center justify-center text-white">
          可横向滚动
        </div>
        <div class="flex-shrink-0 w-48 h-32 bg-gradient-to-br from-orange-400 to-orange-600 rounded-lg flex items-center justify-center text-white">
          继续滚动
        </div>
      </div>
    </div>
  </div>
</body>
</html>
逻辑代码 69 行(超过 40 行限制,仅展示)
💡 提示: scroll-smooth 添加到 <html> 元素上可以让整个页面平滑滚动。snap-x snap-mandatory 配合 snap-center 可以创建轮播图效果。

❓ 常见问题

Q group-hover 和 hover 有什么区别?
A hover: 是元素自身的悬停状态。group-hover: 是当父元素(添加了 group 类)被悬停时,子元素应用样式。适合处理父子元素的联动悬停效果。
Q peer 是如何工作的?
A peer 类添加到一个元素上,然后使用 peer-focus:peer-valid: 等前缀为后续兄弟元素设置样式。常用于浮动标签、表单验证等场景。
Q 为什么 disabled:opacity-50 不生效?
A 确保 disabled: 前缀与实际的 disabled 属性配合使用。Tailwind 会生成 .disabled\:opacity-50:disabled 选择器,元素必须有 disabled 属性才会生效。
Q 如何实现滚动吸附效果?
A 在滚动容器上添加 snap-x snap-mandatory(水平)或 snap-y snap-mandatory(垂直),在子元素上添加 snap-centersnap-start

📖 小节

📝 作业

  1. ⭐ 创建一个按钮组件,使用 hover:focus:active:disabled: 状态前缀实现完整的交互状态样式

  2. ⭐⭐ 创建一个导航菜单,使用 groupgroup-hover: 实现悬停时图标、文字、箭头的联动变化效果

  3. ⭐⭐⭐ 创建一个表单,使用 peerpeer-focus: 实现浮动标签效果,配合 focus:invalid: 状态实现表单验证样式

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏