Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move unknown pseudo elements outside of :is #11345

Merged
merged 2 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Remove `autoprefixer` dependency ([#11315](https://github.com/tailwindlabs/tailwindcss/pull/11315))
- Fix source maps issue resulting in a crash ([#11319](https://github.com/tailwindlabs/tailwindcss/pull/11319))
- Fallback to RegEx based parser when using custom transformers or extractors ([#11335](https://github.com/tailwindlabs/tailwindcss/pull/11335))
- Move unknown pseudo-elements outside of `:is` by default ([#11345](https://github.com/tailwindlabs/tailwindcss/pull/11345))

### Added

Expand Down
23 changes: 10 additions & 13 deletions src/util/pseudoElements.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@
// **Jumpable**
// Any terminal element may "jump" over combinators when moving to the end of the selector
//
// This is a backwards-compat quirk of :before and :after variants.
// This is a backwards-compat quirk of pseudo element variants from earlier versions of Tailwind CSS.

/** @typedef {'terminal' | 'actionable' | 'jumpable'} PseudoProperty */

/** @type {Record<string, PseudoProperty[]>} */
let elementProperties = {
// Pseudo elements from the spec
'::after': ['terminal', 'jumpable'],
'::backdrop': ['terminal', 'jumpable'],
'::before': ['terminal', 'jumpable'],
Expand All @@ -41,18 +42,14 @@ let elementProperties = {
'::spelling-error': ['terminal'],
'::target-text': ['terminal'],

// other
// Pseudo elements from the spec with special rules
'::file-selector-button': ['terminal', 'actionable'],
'::-webkit-progress-bar': ['terminal', 'actionable'],

// Webkit scroll bar pseudo elements can be combined with user-action pseudo classes
'::-webkit-scrollbar': ['terminal', 'actionable'],
'::-webkit-scrollbar-button': ['terminal', 'actionable'],
'::-webkit-scrollbar-thumb': ['terminal', 'actionable'],
'::-webkit-scrollbar-track': ['terminal', 'actionable'],
'::-webkit-scrollbar-track-piece': ['terminal', 'actionable'],
'::-webkit-scrollbar-corner': ['terminal', 'actionable'],
'::-webkit-resizer': ['terminal', 'actionable'],
// Library-specific pseudo elements used by component libraries
// These are Shadow DOM-like
'::deep': ['actionable'],
'::v-deep': ['actionable'],
'::ng-deep': ['actionable'],

// Note: As a rule, double colons (::) should be used instead of a single colon
// (:). This distinguishes pseudo-classes from pseudo-elements. However, since
Expand All @@ -65,8 +62,8 @@ let elementProperties = {

// The default value is used when the pseudo-element is not recognized
// Because it's not recognized, we don't know if it's terminal or not
// So we assume it can't be moved AND can have user-action pseudo classes attached to it
__default__: ['actionable'],
// So we assume it can be moved AND can have user-action pseudo classes attached to it
__default__: ['terminal', 'actionable'],
}

/**
Expand Down
4 changes: 4 additions & 0 deletions tests/util/apply-important-selector.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ it.each`
${':is(.foo) :is(.bar)'} | ${'#app :is(:is(.foo) :is(.bar))'}
${':is(.foo)::before'} | ${'#app :is(.foo)::before'}
${'.foo:before'} | ${'#app :is(.foo):before'}
${'.foo::some-uknown-pseudo'} | ${'#app :is(.foo)::some-uknown-pseudo'}
${'.foo::some-uknown-pseudo:hover'} | ${'#app :is(.foo)::some-uknown-pseudo:hover'}
${'.foo:focus::some-uknown-pseudo:hover'} | ${'#app :is(.foo:focus)::some-uknown-pseudo:hover'}
${'.foo:hover::some-uknown-pseudo:focus'} | ${'#app :is(.foo:hover)::some-uknown-pseudo:focus'}
`('should generate "$after" from "$before"', ({ before, after }) => {
expect(applyImportantSelector(before, '#app')).toEqual(after)
})