Tailwind CSS on GitHub

Hover、Focus以及其他变体

直接使用工具类去添加hover、focus等效果

Overview

类似于Tailwind处理自适应设计,hover、focus等样式元素可以通过使用对应的前缀加工具类来完成。

<form>
  <input class="border border-transparent focus:outline-none focus:ring-2 focus:ring-purple-600 focus:border-transparent ...">
  <button class="bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-opacity-50 ...">
    Sign up
  </button>
</form>

出于文件大小的考虑,并不是所有的变体都默认为所有的工具类启用,但是我们已经尽了最大的努力来启用最常用的组合。

有关默认启用的变体的完整列表,请查看本页末尾的参考表

如果你需要一个Tailwind不支持的变体,你可以通过编写一个变体插件来扩展。


Hover

添加hover:前缀到工具类来实现hover效果。

<button class="bg-red-500 hover:bg-red-700 ...">
  Hover me
</button>

默认情况下,hover只为以下工具类开启:

  • backgroundColor
  • backgroundOpacity
  • borderColor
  • borderOpacity
  • boxShadow
  • gradientColorStops
  • opacity
  • rotate
  • scale
  • skew
  • textColor
  • textDecoration
  • textOpacity
  • translate

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启hover:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      padding: ['hover'],
    }
  },
}

Focus

添加focus:前缀到工具类来实现focus效果。

<input class="focus:ring-2 focus:ring-blue-600 ...">

默认情况下,focus只为以下工具类开启:

  • accessibility
  • backgroundColor
  • backgroundOpacity
  • borderColor
  • borderOpacity
  • boxShadow
  • gradientColorStops
  • opacity
  • outline
  • placeholderColor
  • placeholderOpacity
  • ringColor
  • ringOffsetColor
  • ringOffsetWidth
  • ringOpacity
  • ringWidth
  • rotate
  • scale
  • skew
  • textColor
  • textDecoration
  • textOpacity
  • translate
  • zIndex

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启focus:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      maxHeight: ['focus'],
    }
  },
}

Active

添加active:前缀到工具类来实现active效果。

<button class="bg-green-500 active:bg-green-700 ...">
  Click me
</button>

默认情况下,active对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启active:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['active'],
    }
  },
}

Group-hover

当鼠标悬停在特定的父元素上时,如果你需要样式化子元素,可以在父元素上添加group类,并在子元素上添加group-hover:前缀。

New Project

Create a new project from a variety of starting templates.

<div class="group border-indigo-500 hover:bg-white hover:shadow-lg hover:border-transparent ...">
  <p class="text-indigo-600 group-hover:text-gray-900 ...">New Project</p>
  <p class="text-indigo-500 group-hover:text-gray-500 ...">Create a new project from a variety of starting templates.</p>
</div>

默认情况下,group-hover只为以下工具类开启:

  • backgroundColor
  • backgroundOpacity
  • borderColor
  • borderOpacity
  • boxShadow
  • opacity
  • textColor
  • textDecoration
  • textOpacity

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启group-hover:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      divideColor: ['group-hover'],
    }
  },
}

Group-focus

group-focus的原理和使用跟group-hover一样:

<button class="group bg-yellow-500 focus:bg-yellow-600 ...">
  <svg class="text-white group-focus:text-yellow-300 ..."></svg>
  Bookmark
</button>

默认情况下,group-focus对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启group-focus:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['group-focus'],
    }
  },
}

Focus-within

父元素添加focus-within:前缀到对应工具类,当子元素focus时,父元素就会应用该工具类。

<form>
  <div class="text-gray-400 focus-within:text-gray-600 ...">
    <div class="...">
      <svg fill="currentColor"></svg>
    </div>
    <input class="focus:ring-2 focus:ring-gray-300 ...">
  </div>
</form>

默认情况下,focus-within只为以下工具类开启:

  • accessibility
  • backgroundColor
  • backgroundOpacity
  • borderColor
  • borderOpacity
  • boxShadow
  • opacity
  • outline
  • ringColor
  • ringOffsetColor
  • ringOffsetWidth
  • ringOpacity
  • ringWidth
  • textColor
  • textDecoration
  • textOpacity
  • zIndex

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启focus-within:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      scale: ['focus-within'],
    }
  },
}

Focus-visible

注意,Focus-visible目前需要JS和PostCSS polyfills来获得足够的浏览器支持。

添加focus-visible:前缀到工具类,只有用户使用键盘使该元素获得焦点的时候,才会应用该工具类。

<button class="focus:ring-2 focus:ring-red-500 ...">
  Ring on focus
</button>
<button class="focus-visible:ring-2 focus-visible:ring-rose-500 ...">
  Ring on focus-visible
</button>

注意,目前只有Chrome、Edg、Firefox本地支持焦点可见,因此为了获得足够的浏览器支持,你应该同时安装和配置focus-visible JS polyfillfocus-visible PostCSS polyfill。并确保在你的PostCSS插件配置在Tailwind插件之后:

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    'postcss-focus-visible': {},
    autoprefixer: {}
  }
}

默认情况下,focus-visible对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启focus-visible:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      textDecoration: ['focus-visible'],
    }
  },
}

Motion-safe

添加motion-safe:前缀到工具类, 当设备的媒体查询特性prefers-reduced-motionno-preference时应用该工具类。

例如,如果用户没有在系统中启用“Reduce motion”,这个按钮会在鼠标hover时显示动画。

<button class="transform motion-safe:hover:scale-110 ...">
  Hover me
</button>

注意,与大多数其他变体不同的是,motion-safe可以与响应式前缀以及其他变体(如hover)结合在一起,按以下顺序堆叠它们:

<div class="sm:motion-safe:hover:animate-spin">
  <!-- ... -->
</div>

默认情况下,motion-safe对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启motion-safe:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      translate: ['motion-safe'],
    }
  },
}

Motion-reduce

添加motion-reduce:前缀到工具类, 当设备的媒体查询特性prefers-reduced-motionreduce时应用该工具类。

例如,默认情况下,这个按钮会在hover时变大,但是如果用户在系统中启用了“Reduce motion”,动画将会被禁用。

<button class="transform hover:scale-110 motion-reduce:transform-none ...">
  Hover me
</button>

注意,与大多数其他变体不同的是,motion-reduce可以与响应式前缀以及其他变体(如hover)结合在一起,按以下顺序堆叠它们:

<div class="sm:motion-reduce:hover:animate-none">
  <!-- ... -->
</div>

默认情况下,motion-reduce对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启motion-reduce:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      translate: ['motion-reduce'],
    }
  },
}

Disabled

添加disabled:前缀到工具类,当元素disabled的时候应用该工具类。

<button class="disabled:opacity-50 ...">
  Submit
</button>
<button class="disabled:opacity-50 ..." disabled>
  Submit
</button>

默认情况下,disabled对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启disabled:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      opacity: ['disabled'],
    }
  },
}

Visited

为链接添加visited:到工具类,当链接被访问过了就会应用该工具类。

<a href="#" class="text-blue-600 visited:text-purple-600 ...">Link</a>

默认情况下,visited对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启visited:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      textColor: ['visited'],
    }
  },
}

Checked

为radio或者checkbox添加visited:到工具类,当它们checked的时候应用该工具类。

<input type="checkbox" class="appearance-none checked:bg-blue-600 checked:border-transparent ...">

默认情况下,checked对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启checked:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['checked'],
      borderColor: ['checked'],
    }
  },
}

First-child

添加first:前缀到工具类,当该元素是父标签的第一个元素的时候,就会应用该工具类。这在循环输出元素的时候非常有用。

<div class="...">
  <div v-for="item in items" class="transform first:rotate-45 ...">
    {{ item }}
  </div>
</div>

需要格外注意的是,应该将first:添加到子元素,而不是父元素。

默认情况下,first-child对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启first:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      borderWidth: ['first'],
    }
  },
}

Last-child

添加last:前缀到工具类,当该元素是父标签的最后一个元素的时候,就会应用该工具类。这在循环输出元素的时候非常有用。

<div class="...">
  <div v-for="item in items" class="transform last:rotate-45 ...">
    {{ item }}
  </div>
</div>

需要格外注意的是,应该将last:添加到子元素,而不是父元素。

默认情况下,last-child对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启last:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      borderWidth: ['last'],
    }
  },
}

Odd-child

添加odd:前缀到工具类,当该元素是父标签的第奇数个元素的时候,就会应用该工具类。这在循环输出元素的时候非常有用。

<div class="...">
  <div v-for="item in items" class="transform odd:rotate-45 ...">
    {{ item }}
  </div>
</div>

需要格外注意的是,应该将odd:添加到子元素,而不是父元素。

默认情况下,odd-child对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启odd:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['odd'],
    }
  },
}

Even-child

添加even:前缀到工具类,当该元素是父标签的第奇数个元素的时候,就会应用该工具类。这在循环输出元素的时候非常有用。

<div class="...">
  <div v-for="item in items" class="transform even:rotate-45 ...">
    {{ item }}
  </div>
</div>

需要格外注意的是,应该将even:添加到子元素,而不是父元素。

默认情况下,even-child对于全部工具类都是未启用的。.

你可以在你的tailwind.config.js配置文件为你想支持的工具类组开启even:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['even'],
    }
  },
}

与响应式前缀组合

变体也具有响应性,这意味着你可以做一些事情,比如在不同的断点更改元素的hover样式。

要在特定的断点上应用一个变体,在变体前缀之前先添加响应式前缀:

<button class="... hover:bg-green-500 sm:hover:bg-blue-500">
  <!-- ... -->
</button>

为自定义的类创建生成变体

你可以为你自己的CSS类生成变体,用@variant指令包装它们:

/* Input: */
@variants group-hover, hover, focus {
  .banana {
    color: yellow;
  }
}

/* Output: */
.banana {
  color: yellow;
}
.group:hover .group-hover\:banana {
  color: yellow;
}
.hover\:banana:hover {
  color: yellow;
}
.focus\:banana:focus {
  color: yellow;
}

更多细节,查看@variants指令.


创建自定义变体

你可以创建Tailwind默认不支持的变体,方法是编写一个自定义的变量插件。

例如,这个简单的插件增加了对required伪类变体的支持:

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e }) {
      addVariant('required', ({ modifySelectors, separator }) => {
        modifySelectors(({ className }) => {
          return `.${e(`required${separator}${className}`)}:required`
        })
      })
    })
  ]
}

更多细节,查看变体插件.


默认变体支持

由于文件大小的考虑,默认情况下,Tailwind并不包括所有工具类的所有变体。

要为你的项目配置启用哪些变体,查看配置变体.

// Default configuration
module.exports = {
  // ...
  variants: {
    accessibility: ['responsive', 'focus-within', 'focus'],
    alignContent: ['responsive'],
    alignItems: ['responsive'],
    alignSelf: ['responsive'],
    animation: ['responsive'],
    appearance: ['responsive'],
    backgroundAttachment: ['responsive'],
    backgroundClip: ['responsive'],
    backgroundColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    backgroundImage: ['responsive'],
    backgroundOpacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    backgroundPosition: ['responsive'],
    backgroundRepeat: ['responsive'],
    backgroundSize: ['responsive'],
    borderCollapse: ['responsive'],
    borderColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    borderOpacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    borderRadius: ['responsive'],
    borderStyle: ['responsive'],
    borderWidth: ['responsive'],
    boxShadow: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    boxSizing: ['responsive'],
    clear: ['responsive'],
    container: ['responsive'],
    cursor: ['responsive'],
    display: ['responsive'],
    divideColor: ['responsive', 'dark'],
    divideOpacity: ['responsive'],
    divideStyle: ['responsive'],
    divideWidth: ['responsive'],
    fill: ['responsive'],
    flex: ['responsive'],
    flexDirection: ['responsive'],
    flexGrow: ['responsive'],
    flexShrink: ['responsive'],
    flexWrap: ['responsive'],
    float: ['responsive'],
    fontFamily: ['responsive'],
    fontSize: ['responsive'],
    fontSmoothing: ['responsive'],
    fontStyle: ['responsive'],
    fontVariantNumeric: ['responsive'],
    fontWeight: ['responsive'],
    gap: ['responsive'],
    gradientColorStops: ['responsive', 'dark', 'hover', 'focus'],
    gridAutoColumns: ['responsive'],
    gridAutoFlow: ['responsive'],
    gridAutoRows: ['responsive'],
    gridColumn: ['responsive'],
    gridColumnEnd: ['responsive'],
    gridColumnStart: ['responsive'],
    gridRow: ['responsive'],
    gridRowEnd: ['responsive'],
    gridRowStart: ['responsive'],
    gridTemplateColumns: ['responsive'],
    gridTemplateRows: ['responsive'],
    height: ['responsive'],
    inset: ['responsive'],
    justifyContent: ['responsive'],
    justifyItems: ['responsive'],
    justifySelf: ['responsive'],
    letterSpacing: ['responsive'],
    lineHeight: ['responsive'],
    listStylePosition: ['responsive'],
    listStyleType: ['responsive'],
    margin: ['responsive'],
    maxHeight: ['responsive'],
    maxWidth: ['responsive'],
    minHeight: ['responsive'],
    minWidth: ['responsive'],
    objectFit: ['responsive'],
    objectPosition: ['responsive'],
    opacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    order: ['responsive'],
    outline: ['responsive', 'focus-within', 'focus'],
    overflow: ['responsive'],
    overscrollBehavior: ['responsive'],
    padding: ['responsive'],
    placeContent: ['responsive'],
    placeItems: ['responsive'],
    placeSelf: ['responsive'],
    placeholderColor: ['responsive', 'dark', 'focus'],
    placeholderOpacity: ['responsive', 'focus'],
    pointerEvents: ['responsive'],
    position: ['responsive'],
    resize: ['responsive'],
    ringColor: ['responsive', 'dark', 'focus-within', 'focus'],
    ringOffsetColor: ['responsive', 'dark', 'focus-within', 'focus'],
    ringOffsetWidth: ['responsive', 'focus-within', 'focus'],
    ringOpacity: ['responsive', 'focus-within', 'focus'],
    ringWidth: ['responsive', 'focus-within', 'focus'],
    rotate: ['responsive', 'hover', 'focus'],
    scale: ['responsive', 'hover', 'focus'],
    skew: ['responsive', 'hover', 'focus'],
    space: ['responsive'],
    stroke: ['responsive'],
    strokeWidth: ['responsive'],
    tableLayout: ['responsive'],
    textAlign: ['responsive'],
    textColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    textDecoration: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    textOpacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    textOverflow: ['responsive'],
    textTransform: ['responsive'],
    transform: ['responsive'],
    transformOrigin: ['responsive'],
    transitionDelay: ['responsive'],
    transitionDuration: ['responsive'],
    transitionProperty: ['responsive'],
    transitionTimingFunction: ['responsive'],
    translate: ['responsive', 'hover', 'focus'],
    userSelect: ['responsive'],
    verticalAlign: ['responsive'],
    visibility: ['responsive'],
    whitespace: ['responsive'],
    width: ['responsive'],
    wordBreak: ['responsive'],
    zIndex: ['responsive', 'focus-within', 'focus']
  }
}