Skip to content

Commit

Permalink
Only apply hover styles when supported (future) (#8394)
Browse files Browse the repository at this point in the history
* Only apply hover styles when supported (future)

Co-Authored-By: Andrew Brown <browner12@gmail.com>

* update changelog

Co-authored-by: Andrew Brown <browner12@gmail.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
  • Loading branch information
3 people committed May 20, 2022
1 parent bb4f5da commit 128030f
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Try using local `postcss` installation first in the CLI ([#8270](https://github.com/tailwindlabs/tailwindcss/pull/8270))
- Only apply hover styles when supported (future) ([#8394](https://github.com/tailwindlabs/tailwindcss/pull/8394))

### Added

Expand Down
32 changes: 19 additions & 13 deletions src/corePlugins.js
Expand Up @@ -14,6 +14,7 @@ import { version as tailwindVersion } from '../package.json'
import log from './util/log'
import { normalizeScreens } from './util/normalizeScreens'
import { formatBoxShadowValue, parseBoxShadowValue } from './util/parseBoxShadowValue'
import { flagEnabled } from './featureFlags'

export let variantPlugins = {
pseudoElementVariants: ({ addVariant }) => {
Expand Down Expand Up @@ -60,14 +61,14 @@ export let variantPlugins = {
})
},

pseudoClassVariants: ({ addVariant }) => {
pseudoClassVariants: ({ addVariant, config }) => {
let pseudoVariants = [
// Positional
['first', ':first-child'],
['last', ':last-child'],
['only', ':only-child'],
['odd', ':nth-child(odd)'],
['even', ':nth-child(even)'],
['first', '&:first-child'],
['last', '&:last-child'],
['only', '&:only-child'],
['odd', '&:nth-child(odd)'],
['even', '&:nth-child(even)'],
'first-of-type',
'last-of-type',
'only-of-type',
Expand All @@ -92,11 +93,11 @@ export let variantPlugins = {
}
})

return ':visited'
return '&:visited'
},
],
'target',
['open', '[open]'],
['open', '&[open]'],

// Forms
'default',
Expand All @@ -116,35 +117,40 @@ export let variantPlugins = {

// Interactive
'focus-within',
'hover',
[
'hover',
!flagEnabled(config(), 'hoverOnlyWhenSupported')
? '&:hover'
: '@media (hover: hover) and (pointer: fine) { &:hover }',
],
'focus',
'focus-visible',
'active',
'enabled',
'disabled',
].map((variant) => (Array.isArray(variant) ? variant : [variant, `:${variant}`]))
].map((variant) => (Array.isArray(variant) ? variant : [variant, `&:${variant}`]))

for (let [variantName, state] of pseudoVariants) {
addVariant(variantName, (ctx) => {
let result = typeof state === 'function' ? state(ctx) : state

return `&${result}`
return result
})
}

for (let [variantName, state] of pseudoVariants) {
addVariant(`group-${variantName}`, (ctx) => {
let result = typeof state === 'function' ? state(ctx) : state

return `:merge(.group)${result} &`
return result.replace(/&(\S+)/, ':merge(.group)$1 &')
})
}

for (let [variantName, state] of pseudoVariants) {
addVariant(`peer-${variantName}`, (ctx) => {
let result = typeof state === 'function' ? state(ctx) : state

return `:merge(.peer)${result} ~ &`
return result.replace(/&(\S+)/, ':merge(.peer)$1 ~ &')
})
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/featureFlags.js
Expand Up @@ -6,7 +6,7 @@ let defaults = {
}

let featureFlags = {
future: [],
future: ['hoverOnlyWhenSupported'],
experimental: ['optimizeUniversalDefaults'],
}

Expand Down
36 changes: 36 additions & 0 deletions tests/variants.test.js
Expand Up @@ -769,3 +769,39 @@ it('variants only picks the used selectors in a group (apply)', () => {
`)
})
})

test('hoverOnlyWhenSupported adds hover and pointer media features by default', () => {
let config = {
future: {
hoverOnlyWhenSupported: true,
},
content: [
{ raw: html`<div class="hover:underline group-hover:underline peer-hover:underline"></div>` },
],
corePlugins: { preflight: false },
}

let input = css`
@tailwind base;
@tailwind components;
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
${defaults}
@media (hover: hover) and (pointer: fine) {
.hover\:underline:hover {
text-decoration-line: underline;
}
.group:hover .group-hover\:underline {
text-decoration-line: underline;
}
.peer:hover ~ .peer-hover\:underline {
text-decoration-line: underline;
}
}
`)
})
})

0 comments on commit 128030f

Please sign in to comment.