Skip to content

Commit fe48ca8

Browse files
Insert @defaults at start of stylesheet (#14427)
Prior to this PR, we'd put all of the `@defaults` (the CSS variables and stuff) _after_ the `base` rules. This creates an issue when using `optimizeUniversalDefaults` with CSS that looks like this: ```css @tailwind base; @tailwind components; @tailwind utilities; @layer base { input { @apply shadow; } } ``` …because the default shadow stuff ends up after the base `input` rules, so the generated styles are like this: ```css input { --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } input { --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; } ``` This means all of the actual shadow values for the input are reset and the shadow doesn't work. Fixes #14426. Lots of failing tests right because this changes a ton of stuff, albeit in a totally inconsequential way. @thecrypticace if you could update these for me this week that would be a huge help, just banging this fix out quick while the kids are napping 😴 --------- Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com> Co-authored-by: Jordan Pittman <jordan@cryptica.me>
1 parent 818d10a commit fe48ca8

13 files changed

+376
-339
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
- Nothing yet!
10+
### Fixed
11+
12+
- Ensure using `@apply` with utilities that use `@defaults` works with rules defined in the base layer when using `optimizeUniversalDefaults` ([#14427](https://github.com/tailwindlabs/tailwindcss/pull/14427))
1113

1214
## [3.4.11] - 2024-09-11
1315

src/lib/expandTailwindAtRules.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ export default function expandTailwindAtRules(context) {
192192

193193
if (layerNodes.base) {
194194
layerNodes.base.before(
195-
cloneNodes([...baseNodes, ...defaultNodes], layerNodes.base.source, {
195+
cloneNodes([...defaultNodes, ...baseNodes], layerNodes.base.source, {
196196
layer: 'base',
197197
})
198198
)

src/lib/resolveDefaultsAtRules.js

+11-13
Original file line numberDiff line numberDiff line change
@@ -118,22 +118,20 @@ export default function resolveDefaultsAtRules({ tailwindConfig }) {
118118
}
119119
}
120120

121-
if (flagEnabled(tailwindConfig, 'optimizeUniversalDefaults')) {
122-
if (selectorGroups.size === 0) {
123-
universal.remove()
124-
continue
125-
}
121+
if (selectorGroups.size === 0) {
122+
universal.remove()
123+
continue
124+
}
126125

127-
for (let [, selectors] of selectorGroups) {
128-
let universalRule = postcss.rule({
129-
source: universal.source,
130-
})
126+
for (let [, selectors] of selectorGroups) {
127+
let universalRule = postcss.rule({
128+
source: universal.source,
129+
})
131130

132-
universalRule.selectors = [...selectors]
131+
universalRule.selectors = [...selectors]
133132

134-
universalRule.append(universal.nodes.map((node) => node.clone()))
135-
universal.before(universalRule)
136-
}
133+
universalRule.append(universal.nodes.map((node) => node.clone()))
134+
universal.before(universalRule)
137135
}
138136

139137
universal.remove()

tests/apply.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,7 @@ it('apply partitioning works with media queries', async () => {
16401640
const result = await run(input, config)
16411641

16421642
expect(result.css).toMatchFormattedCss(css`
1643+
${defaults}
16431644
html,
16441645
body {
16451646
--tw-text-opacity: 1;
@@ -1654,7 +1655,6 @@ it('apply partitioning works with media queries', async () => {
16541655
font-size: 2rem;
16551656
}
16561657
}
1657-
${defaults}
16581658
`)
16591659
})
16601660

tests/basic-usage.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -460,11 +460,11 @@ it('does not produce duplicate output when seeing variants preceding a wildcard
460460
* {
461461
color: #00f;
462462
}
463+
${defaults}
463464
.combined,
464465
* {
465466
color: red;
466467
}
467-
${defaults}
468468
.underline {
469469
text-decoration-line: underline;
470470
}

tests/collapse-adjacent-rules.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ test('collapse adjacent rules', () => {
7070

7171
return run(input, config).then((result) => {
7272
expect(result.css).toMatchFormattedCss(css`
73+
${defaults}
7374
@font-face {
7475
font-family: Poppins;
7576
src: url('/fonts/Poppins.woff2') format('woff2'), url('/fonts/Poppins.woff') format('woff');
@@ -79,7 +80,6 @@ test('collapse adjacent rules', () => {
7980
src: url('/fonts/ProximaNova.woff2') format('woff2'),
8081
url('/fonts/ProximaNova.woff') format('woff');
8182
}
82-
${defaults}
8383
@font-face {
8484
font-family: Inter;
8585
src: url('/fonts/Inter.woff2') format('woff2'), url('/fonts/Inter.woff') format('woff');

tests/combined-selectors.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ it('should generate the partial selector, if only a partial is used (base layer)
2525

2626
return run(input, config).then((result) => {
2727
return expect(result.css).toMatchFormattedCss(css`
28+
${defaults}
2829
:root {
2930
font-weight: bold;
3031
}
3132
:root,
3233
.a {
3334
color: #000;
3435
}
35-
${defaults}
3636
`)
3737
})
3838
})

tests/custom-plugins.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,13 @@ test('plugins can add base styles with object syntax', () => {
239239

240240
return run('@tailwind base', config).then((result) => {
241241
expect(result.css).toMatchFormattedCss(css`
242+
${defaults}
242243
img {
243244
max-width: 100%;
244245
}
245246
button {
246247
font-family: inherit;
247248
}
248-
${defaults}
249249
`)
250250
})
251251
})
@@ -280,13 +280,13 @@ test('plugins can add base styles with raw PostCSS nodes', () => {
280280

281281
return run('@tailwind base', config).then((result) => {
282282
expect(result.css).toMatchFormattedCss(css`
283+
${defaults}
283284
img {
284285
max-width: 100%;
285286
}
286287
button {
287288
font-family: inherit;
288289
}
289-
${defaults}
290290
`)
291291
})
292292
})

tests/import-syntax.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ test('using @import instead of @tailwind', () => {
3333

3434
return run(input, config).then((result) => {
3535
expect(result.css).toMatchFormattedCss(css`
36+
${defaults}
3637
h1 {
3738
font-size: 32px;
3839
}
39-
${defaults}
4040
.container {
4141
width: 100%;
4242
}

tests/kitchen-sink.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ test('it works', () => {
352352
}
353353
}
354354
}
355+
${defaults}
355356
h1 {
356357
font-size: 1.5rem;
357358
font-weight: 700;
@@ -362,7 +363,6 @@ test('it works', () => {
362363
div {
363364
background: #654321;
364365
}
365-
${defaults}
366366
.container {
367367
width: 100%;
368368
}

tests/layer-at-rules.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ test('comments can be used inside layers without crashing', () => {
9090

9191
return run(input, config).then((result) => {
9292
expect(result.css).toMatchFormattedCss(css`
93+
${defaults}
9394
div {
9495
background-color: #bada55;
9596
}
96-
${defaults}
9797
.important-component,
98-
.important-utility {
98+
.important-utility {
9999
text-align: banana;
100100
}
101101
`)
@@ -144,10 +144,10 @@ test('comments can be used inside layers (with important) without crashing', ()
144144

145145
return run(input, config).then((result) => {
146146
expect(result.css).toMatchFormattedCss(css`
147+
${defaults}
147148
div {
148149
background-color: #bada55;
149150
}
150-
${defaults}
151151
.important-component {
152152
text-align: banana;
153153
}
@@ -245,6 +245,7 @@ test('layers are grouped and inserted at the matching @tailwind rule', () => {
245245
font-weight: medium;
246246
}
247247
}
248+
${defaults}
248249
body {
249250
margin: 0;
250251
}
@@ -254,7 +255,6 @@ test('layers are grouped and inserted at the matching @tailwind rule', () => {
254255
p {
255256
font-weight: normal;
256257
}
257-
${defaults}
258258
.input {
259259
background: #fff;
260260
}

tests/resolve-defaults-at-rules.test.js

+38
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,44 @@ test('no defaults and apply without @tailwind base', () => {
770770
})
771771
})
772772

773+
test('apply to rule in base layer puts defaults first with optimizeUniversalDefaults', () => {
774+
let config = {
775+
experimental: { optimizeUniversalDefaults: true },
776+
content: [{ raw: html`<div class="my-card"></div>` }],
777+
corePlugins: ['boxShadow'],
778+
}
779+
780+
// Optimize universal defaults doesn't work well with isolated modules
781+
// We require you to use @tailwind base to inject the defaults
782+
let input = css`
783+
@tailwind base;
784+
@tailwind components;
785+
@tailwind utilities;
786+
787+
@layer base {
788+
input {
789+
@apply shadow;
790+
}
791+
}
792+
`
793+
794+
return run(input, config).then((result) => {
795+
return expect(result.css).toMatchFormattedCss(css`
796+
input {
797+
--tw-ring-offset-shadow: 0 0 #0000;
798+
--tw-ring-shadow: 0 0 #0000;
799+
--tw-shadow: 0 0 #0000;
800+
--tw-shadow-colored: 0 0 #0000;
801+
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
802+
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color),
803+
0 1px 2px -1px var(--tw-shadow-color);
804+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
805+
var(--tw-shadow);
806+
}
807+
`)
808+
})
809+
})
810+
773811
test('optimize universal defaults groups :has separately', () => {
774812
let config = {
775813
experimental: { optimizeUniversalDefaults: true },

0 commit comments

Comments
 (0)