Include :open in the open variant (#15349)

Update the `open` variant to addtionally match the new `:open` pseudo
class.

See spec at https://drafts.csswg.org/selectors-4/#open-state

See Chromium intent to ship:
https://groups.google.com/a/chromium.org/g/blink-dev/c/Pdo4oOXYKcA

`:open` matches open `<details>` and `<dialog>` elements (already
covered by [open]), but also matches select elements with their picker
open and inputs with their picker open.

Thanks to `:is()` taking a forgiving selector list, this is safe to add
even with limited browser support.

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This commit is contained in:
Luke Warlow 2025-01-27 12:43:12 +00:00 • committed by GitHub
parent a707fed089
commit 6dd4c334c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 8 additions and 4 deletions

View file

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Target `:open` in existing `open` variant ([#15349](https://github.com/tailwindlabs/tailwindcss/pull/15349))
### Fixed
- Remove invalid `min-w/h-none` utilities ([#15845](https://github.com/tailwindlabs/tailwindcss/pull/15845))

View file

@ -233,7 +233,7 @@ test('target', async () => {
test('open', async () => {
expect(await run(['open:flex', 'group-open:flex', 'peer-open:flex'])).toMatchInlineSnapshot(`
".group-open\\:flex:is(:where(.group):is([open], :popover-open) *), .peer-open\\:flex:is(:where(.peer):is([open], :popover-open) ~ *), .open\\:flex:is([open], :popover-open) {
".group-open\\:flex:is(:where(.group):is([open], :popover-open, :open) *), .peer-open\\:flex:is(:where(.peer):is([open], :popover-open, :open) ~ *), .open\\:flex:is([open], :popover-open, :open) {
display: flex;
}"
`)
@ -1473,7 +1473,7 @@ test('not', async () => {
display: flex;
}
.not-open\\:flex:not([open], :popover-open) {
.not-open\\:flex:not([open], :popover-open, :open) {
display: flex;
}
@ -2214,7 +2214,7 @@ test('variant order', async () => {
display: flex;
}
.first\\:flex:first-child, .last\\:flex:last-child, .only\\:flex:only-child, .odd\\:flex:nth-child(odd), .even\\:flex:nth-child(2n), .first-of-type\\:flex:first-of-type, .last-of-type\\:flex:last-of-type, .only-of-type\\:flex:only-of-type, .visited\\:flex:visited, .target\\:flex:target, .open\\:flex:is([open], :popover-open), .default\\:flex:default, .checked\\:flex:checked, .indeterminate\\:flex:indeterminate, .placeholder-shown\\:flex:placeholder-shown, .autofill\\:flex:autofill, .optional\\:flex:optional, .required\\:flex:required, .valid\\:flex:valid, .invalid\\:flex:invalid, .in-range\\:flex:in-range, .out-of-range\\:flex:out-of-range, .read-only\\:flex:read-only, .empty\\:flex:empty, .focus-within\\:flex:focus-within {
.first\\:flex:first-child, .last\\:flex:last-child, .only\\:flex:only-child, .odd\\:flex:nth-child(odd), .even\\:flex:nth-child(2n), .first-of-type\\:flex:first-of-type, .last-of-type\\:flex:last-of-type, .only-of-type\\:flex:only-of-type, .visited\\:flex:visited, .target\\:flex:target, .open\\:flex:is([open], :popover-open, :open), .default\\:flex:default, .checked\\:flex:checked, .indeterminate\\:flex:indeterminate, .placeholder-shown\\:flex:placeholder-shown, .autofill\\:flex:autofill, .optional\\:flex:optional, .required\\:flex:required, .valid\\:flex:valid, .invalid\\:flex:invalid, .in-range\\:flex:in-range, .out-of-range\\:flex:out-of-range, .read-only\\:flex:read-only, .empty\\:flex:empty, .focus-within\\:flex:focus-within {
display: flex;
}

View file

@ -681,7 +681,7 @@ export function createVariants(theme: Theme): Variants {
// State
staticVariant('visited', ['&:visited'])
staticVariant('target', ['&:target'])
staticVariant('open', ['&:is([open], :popover-open)'])
staticVariant('open', ['&:is([open], :popover-open, :open)'])
// Forms
staticVariant('default', ['&:default'])