Skip to content

Commit 429fe07

Browse files
Fix defaults optimization when vendor prefixes are involved (#6369)
1 parent 08241c3 commit 429fe07

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Ensure complex variants with multiple classes work ([#6311](https://github.com/tailwindlabs/tailwindcss/pull/6311))
1313
- Re-add `default` interop to public available functions ([#6348](https://github.com/tailwindlabs/tailwindcss/pull/6348))
1414
- Detect circular dependencies when using `@apply` ([#6365](https://github.com/tailwindlabs/tailwindcss/pull/6365))
15+
- Fix defaults optimization when vendor prefixes are involved ([#6369](https://github.com/tailwindlabs/tailwindcss/pull/6369))
1516

1617
## [3.0.0] - 2021-12-09
1718

src/lib/resolveDefaultsAtRules.js

+28-7
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ function extractElementSelector(selector) {
7171
export default function resolveDefaultsAtRules({ tailwindConfig }) {
7272
return (root) => {
7373
let variableNodeMap = new Map()
74+
75+
/** @type {Set<import('postcss').AtRule>} */
7476
let universals = new Set()
7577

7678
root.walkAtRules('defaults', (rule) => {
@@ -90,31 +92,50 @@ export default function resolveDefaultsAtRules({ tailwindConfig }) {
9092
})
9193

9294
for (let universal of universals) {
93-
let selectors = new Set()
95+
/** @type {Map<string, Set<string>>} */
96+
let selectorGroups = new Map()
9497

9598
let rules = variableNodeMap.get(universal.params) ?? []
9699

97100
for (let rule of rules) {
98101
for (let selector of extractElementSelector(rule.selector)) {
102+
// If selector contains a vendor prefix after a pseudo element or class,
103+
// we consider them separately because merging the declarations into
104+
// a single rule will cause browsers that do not understand the
105+
// vendor prefix to throw out the whole rule
106+
let selectorGroupName =
107+
selector.includes(':-') || selector.includes('::-') ? selector : '__DEFAULT__'
108+
109+
let selectors = selectorGroups.get(selectorGroupName) ?? new Set()
110+
selectorGroups.set(selectorGroupName, selectors)
111+
99112
selectors.add(selector)
100113
}
101114
}
102115

103-
if (selectors.size === 0) {
116+
if (selectorGroups.size === 0) {
104117
universal.remove()
105118
continue
106119
}
107120

108-
let universalRule = postcss.rule()
109-
110121
if (flagEnabled(tailwindConfig, 'optimizeUniversalDefaults')) {
111-
universalRule.selectors = [...selectors]
122+
for (let [, selectors] of selectorGroups) {
123+
let universalRule = postcss.rule()
124+
125+
universalRule.selectors = [...selectors]
126+
127+
universalRule.append(universal.nodes.map((node) => node.clone()))
128+
universal.before(universalRule)
129+
}
112130
} else {
131+
let universalRule = postcss.rule()
132+
113133
universalRule.selectors = ['*', '::before', '::after']
134+
135+
universalRule.append(universal.nodes)
136+
universal.before(universalRule)
114137
}
115138

116-
universalRule.append(universal.nodes)
117-
universal.before(universalRule)
118139
universal.remove()
119140
}
120141
}

tests/apply.test.js

+39
Original file line numberDiff line numberDiff line change
@@ -577,3 +577,42 @@ it('should throw when trying to apply an indirect circular dependency with a mod
577577
expect(err.reason).toBe('Circular dependency detected when using: `@apply a`')
578578
})
579579
})
580+
581+
it('rules with vendor prefixes are still separate when optimizing defaults rules', () => {
582+
let config = {
583+
experimental: { optimizeUniversalDefaults: true },
584+
content: [{ raw: html`<div class="border"></div>` }],
585+
corePlugins: { preflight: false },
586+
}
587+
588+
let input = css`
589+
@tailwind base;
590+
@tailwind components;
591+
@tailwind utilities;
592+
593+
@layer components {
594+
input[type='range']::-moz-range-thumb {
595+
@apply border;
596+
}
597+
}
598+
`
599+
600+
return run(input, config).then((result) => {
601+
return expect(result.css).toMatchFormattedCss(css`
602+
[type='range']::-moz-range-thumb {
603+
--tw-border-opacity: 1;
604+
border-color: rgb(229 231 235 / var(--tw-border-opacity));
605+
}
606+
.border {
607+
--tw-border-opacity: 1;
608+
border-color: rgb(229 231 235 / var(--tw-border-opacity));
609+
}
610+
input[type='range']::-moz-range-thumb {
611+
border-width: 1px;
612+
}
613+
.border {
614+
border-width: 1px;
615+
}
616+
`)
617+
})
618+
})

0 commit comments

Comments
 (0)