diff --git a/CHANGELOG.md b/CHANGELOG.md index 794e0c24b02c..8369a60a6109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add `svh`, `lvh`, and `dvh` values to default `height`/`min-height`/`max-height` theme ([#11317](https://github.com/tailwindlabs/tailwindcss/pull/11317)) +- Add `has-*` variants for `:has(...)` pseudo-class ([#11318](https://github.com/tailwindlabs/tailwindcss/pull/11318)) ## [3.3.6] - 2023-12-04 diff --git a/src/corePlugins.js b/src/corePlugins.js index 5db1fdb74e7b..b8bf04279fd7 100644 --- a/src/corePlugins.js +++ b/src/corePlugins.js @@ -392,6 +392,26 @@ export let variantPlugins = { ) }, + hasVariants: ({ matchVariant }) => { + matchVariant('has', (value) => `&:has(${normalize(value)})`, { values: {} }) + matchVariant( + 'group-has', + (value, { modifier }) => + modifier + ? `:merge(.group\\/${modifier}):has(${normalize(value)}) &` + : `:merge(.group):has(${normalize(value)}) &`, + { values: {} } + ) + matchVariant( + 'peer-has', + (value, { modifier }) => + modifier + ? `:merge(.peer\\/${modifier}):has(${normalize(value)}) ~ &` + : `:merge(.peer):has(${normalize(value)}) ~ &`, + { values: {} } + ) + }, + ariaVariants: ({ matchVariant, theme }) => { matchVariant('aria', (value) => `&[aria-${normalize(value)}]`, { values: theme('aria') ?? {} }) matchVariant( diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index 59c261d698b3..4fc8468a4b83 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -758,6 +758,7 @@ function resolvePlugins(context, root) { let beforeVariants = [ variantPlugins['pseudoElementVariants'], variantPlugins['pseudoClassVariants'], + variantPlugins['hasVariants'], variantPlugins['ariaVariants'], variantPlugins['dataVariants'], ] diff --git a/tests/arbitrary-variants.test.js b/tests/arbitrary-variants.test.js index b210bdc77ecb..c4f8960dc638 100644 --- a/tests/arbitrary-variants.test.js +++ b/tests/arbitrary-variants.test.js @@ -845,6 +845,132 @@ crosscheck(({ stable, oxide }) => { }) }) + test('has-* variants with arbitrary values', () => { + let config = { + theme: {}, + content: [ + { + raw: html` +