diff --git a/CHANGELOG.md b/CHANGELOG.md index 0390f3674b08..f76ebf4e353e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allows fallback values in plugin API helpers ([#8762](https://github.com/tailwindlabs/tailwindcss/pull/8762)) - Fix usage of postcss.config.js in standalone CLI ([#8769](https://github.com/tailwindlabs/tailwindcss/pull/8769)) - Fix usage of special-character prefixes ([#8772](https://github.com/tailwindlabs/tailwindcss/pull/8772)) +- Don’t prefix selectors in arbitrary variants ([#8773](https://github.com/tailwindlabs/tailwindcss/pull/8773)) ## [3.1.4] - 2022-06-21 diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index fa790a455230..e1cad8f7d9b2 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -129,6 +129,7 @@ function applyVariant(variant, matches, context) { } let args + let isArbitraryVariant = false // Find partial arbitrary variants if (variant.endsWith(']') && !variant.startsWith('[')) { @@ -144,6 +145,8 @@ function applyVariant(variant, matches, context) { return [] } + isArbitraryVariant = true + let fn = parseVariant(selector) let sort = Array.from(context.variantOrder.values()).pop() << 1n @@ -300,6 +303,7 @@ function applyVariant(variant, matches, context) { ...meta, sort: variantSort | meta.sort, collectedFormats: (meta.collectedFormats ?? []).concat(collectedFormats), + isArbitraryVariant, }, clone.nodes[0], ] @@ -627,6 +631,7 @@ function* resolveMatches(candidate, context, original = candidate) { base: candidate .split(new RegExp(`\\${context?.tailwindConfig?.separator ?? ':'}(?![^[]*\\])`)) .pop(), + isArbitraryVariant: match[0].isArbitraryVariant, context, }) diff --git a/src/util/formatVariantSelector.js b/src/util/formatVariantSelector.js index 2684cdc7f6b6..3c2e1f9db733 100644 --- a/src/util/formatVariantSelector.js +++ b/src/util/formatVariantSelector.js @@ -35,6 +35,7 @@ export function finalizeSelector( selector, candidate, context, + isArbitraryVariant, // Split by the separator, but ignore the separator inside square brackets: // @@ -50,7 +51,8 @@ export function finalizeSelector( ) { let ast = selectorParser().astSync(selector) - if (context?.tailwindConfig?.prefix) { + // We explicitly DO NOT prefix classes in arbitrary variants + if (context?.tailwindConfig?.prefix && !isArbitraryVariant) { format = prefixSelector(context.tailwindConfig.prefix, format) } diff --git a/tests/arbitrary-variants.test.js b/tests/arbitrary-variants.test.js index a42300c4c53c..be9704e87b71 100644 --- a/tests/arbitrary-variants.test.js +++ b/tests/arbitrary-variants.test.js @@ -527,3 +527,42 @@ test('allows attribute variants with quotes', () => { `) }) }) + +test('classes in arbitrary variants should not be prefixed', () => { + let config = { + prefix: 'tw-', + content: [ + { + raw: ` +
should not be red
+
+
should be red
+
+
+
should not be red
+
should be red
+
+ `, + }, + ], + corePlugins: { preflight: false }, + } + + let input = ` + @tailwind utilities; + ` + + return run(input, config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .foo .\[\.foo_\&\]\:tw-text-red-400 { + --tw-text-opacity: 1; + color: rgb(248 113 113 / var(--tw-text-opacity)); + } + + .\[\&_\.foo\]\:tw-text-red-400 .foo { + --tw-text-opacity: 1; + color: rgb(248 113 113 / var(--tw-text-opacity)); + } + `) + }) +})