Pseudo-Class Variants
Overview
Similar to how Tailwind handles responsive design, styling elements on hover, focus, and more can be accomplished by prefixing utilities with the appropriate pseudo-class.
<form>
<input class="bg-gray-200 hover:bg-white hover:border-gray-300 focus:outline-none focus:bg-white focus:shadow-outline focus:border-gray-300 ...">
<button class="bg-teal-500 hover:bg-teal-600 focus:outline-none focus:shadow-outline ...">
Sign Up
</button>
</form>
Not all pseudo-class variants are enabled for all utilities by default due to file-size considerations, but we've tried our best to enable the most commonly used combinations out of the box.
For a complete list of which variants are enabled by default, see the reference table at the end of this page.
Tailwind includes first-class support for styling elements on hover, focus, active, disabled, visited, first-child, last-child, odd-child, even-child, group-hover, and focus-within.
If you need to target a pseudo-class that Tailwind doesn't support, you can extend the supported variants by writing a variant plugin.
Hover
Add the hover: prefix to only apply a utility on hover.
<button class="bg-transparent hover:bg-blue-500 text-blue-700 hover:text-white...">
Hover me
</button>
You can control whether hover variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
backgroundColor: ['responsive', 'hover', 'focus'],
},
}
Focus
Add the focus: prefix to only apply a utility on focus.
<input class="bg-gray-200 focus:bg-white border-transparent focus:border-blue-400 ..." placeholder="Focus me">
You can control whether focus variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
backgroundColor: ['responsive', 'hover', 'focus'],
},
}
Active
Add the active: prefix to only apply a utility when an element is active.
<button class="bg-blue-500 active:bg-blue-700 text-white...">
Click me
</button>
You can control whether active variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
backgroundColor: ['responsive', 'hover', 'focus', 'active'],
},
}
Disabled
Add the disabled: prefix to only apply a utility when an element is disabled.
<button class="disabled:opacity-75 bg-blue-500...">
Submit
</button>
<button disabled class="disabled:opacity-75 bg-blue-500...">
Submit
</button>
You can control whether disabled variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
opacity: ['responsive', 'hover', 'focus', 'disabled'],
},
}
Visited
Add the visited: prefix to only apply a utility when a link has been visited.
<a href="#" class="text-blue-600 visited:text-purple-600 ...">Link</a>
You can control whether visited variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
textColor: ['responsive', 'hover', 'focus', 'visited'],
},
}
First-child
Add the first: prefix to only apply a utility when it is the first-child of its parent. This is mostly useful when elements are being generated in some kind of loop.
<div class="border rounded">
<div v-for="item in items" class="border-t first:border-t-0">
{{ item }}
</div>
</div>
It's important to note that you should add any first: utilities to the child element, not the parent element.
You can control whether first variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
borderWidth: ['responsive', 'first', 'hover', 'focus'],
},
}
Last-child
Add the last: prefix to only apply a utility when it is the last-child of its parent. This is mostly useful when elements are being generated in some kind of loop.
<div class="border rounded">
<div v-for="item in items" class="border-b last:border-b-0">
{{ item }}
</div>
</div>
It's important to note that you should add any last: utilities to the child element, not the parent element.
You can control whether last variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
borderWidth: ['responsive', 'last', 'hover', 'focus'],
},
}
Odd-child
Add the odd: prefix to only apply a utility when it is an odd-child of its parent. This is mostly useful when elements are being generated in some kind of loop.
<div class="border rounded">
<div v-for="item in items" class="bg-white odd:bg-gray-200">
{{ item }}
</div>
</div>
It's important to note that you should add any odd: utilities to the child element, not the parent element.
You can control whether odd variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
borderWidth: ['responsive', 'odd', 'hover', 'focus'],
},
}
Even-child
Add the even: prefix to only apply a utility when it is an even-child of its parent. This is mostly useful when elements are being generated in some kind of loop.
<div class="border rounded">
<div v-for="item in items" class="bg-white even:bg-gray-200">
{{ item }}
</div>
</div>
It's important to note that you should add any even: utilities to the child element, not the parent element.
You can control whether even variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
borderWidth: ['responsive', 'even', 'hover', 'focus'],
},
}
Group-hover
If you need to style a child element when hovering over a specific parent element, add the .group class to the parent element and add the group-hover: prefix to the utility on the child element.
New Project
Create a new project from a variety of starting templates.
<div class="group bg-white hover:bg-blue-500 ...">
<p class="text-gray-900 group-hover:text-white ...">New Project</p>
<p class="text-gray-700 group-hover:text-white ...">Create a new project from a variety of starting templates.</p>
</div>
You can control whether group-hover variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
textColor: ['responsive', 'hover', 'focus', 'group-hover'],
},
}
Focus-within
Note that focus-within is not supported in IE or Edge.
Add the focus-within: prefix to only apply a utility when a child element has focus.
<form class="border-b-2 border-gray-400 focus-within:border-teal-500 ...">
<input class="..." placeholder="Jane Doe" ...>
<button class="...">
Sign Up
</button>
</form>
You can control whether focus-within variants are enabled for a utility in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
borderColor: ['responsive', 'hover', 'focus', 'focus-within'],
},
}
Combining with responsive prefixes
Pseudo-class variants are also responsive, meaning you can do things like change an element's hover style at different breakpoints for example.
To apply a pseudo-class variant at a specific breakpoint, add the responsive prefix first, before the pseudo-class prefix:
Generative variants for custom utilities
You can generate pseudo-class variants for your own custom utilities by wrapping them with the @variants directive in your CSS:
/* 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;
}
For more information, see the @variants directive documentation.
Creating custom variants
You can create your own variants for any pseudo-classes Tailwind doesn't include by default by writing a custom variant plugin.
For example, this simple plugin adds support for the disabled pseudo-class variant:
// tailwind.config.js
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addVariant, e }) {
addVariant('disabled', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`disabled${separator}${className}`)}:disabled`
})
})
})
]
}
Learn more about writing variant plugins in the variant plugin documentation.
Default variants reference
Due to file-size considerations, Tailwind does not generate active, group-hover, or focus-within variants for any utilities by default.
To configure which variants are enabled for your project, see the configuring variants documentation.
| Core Plugin | Hover | Focus |
|---|---|---|
alignContent |
||
alignItems |
||
alignSelf |
||
appearance |
||
backgroundAttachment |
||
backgroundColor |
✓ | ✓ |
backgroundPosition |
||
backgroundRepeat |
||
backgroundSize |
||
borderCollapse |
||
borderColor |
✓ | ✓ |
borderRadius |
||
borderStyle |
||
borderWidth |
||
boxShadow |
✓ | ✓ |
cursor |
||
display |
||
fill |
||
flex |
||
flexDirection |
||
flexGrow |
||
flexShrink |
||
flexWrap |
||
float |
||
fontFamily |
||
fontSize |
||
fontSmoothing |
||
fontStyle |
||
fontWeight |
✓ | ✓ |
height |
||
inset |
||
justifyContent |
||
letterSpacing |
||
lineHeight |
||
listStylePosition |
||
listStyleType |
||
margin |
||
maxHeight |
||
maxWidth |
||
minHeight |
||
minWidth |
||
objectFit |
||
objectPosition |
||
opacity |
✓ | ✓ |
order |
||
outline |
✓ | |
overflow |
||
padding |
||
pointerEvents |
||
position |
||
resize |
||
stroke |
||
tableLayout |
||
textAlign |
||
textColor |
✓ | ✓ |
textDecoration |
✓ | ✓ |
textTransform |
||
userSelect |
||
verticalAlign |
||
visibility |
||
whitespace |
||
width |
||
wordBreak |
||
zIndex |