From 86fb682b5ff6c246c2f0c4143fc1f9cfba1e37a3 Mon Sep 17 00:00:00 2001 From: koreahghg Date: Fri, 28 Aug 2026 08:57:25 +0900 Subject: [PATCH 1/2] Don't warn about Angular's `::ng-deep` when optimizing generated CSS Lightning CSS's unknown-pseudo-element message quotes `ng-deep`, not `deep`, so the existing filter for `:deep()`/`:slotted()`/`:global()` never matched it and every Angular stylesheet using `::ng-deep` printed a spurious warning during `optimizeCss`. --- CHANGELOG.md | 1 + .../@tailwindcss-node/src/optimize.test.ts | 63 +++++++++++++++++++ packages/@tailwindcss-node/src/optimize.ts | 9 ++- 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 packages/@tailwindcss-node/src/optimize.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fec361f5959..9b3134ccabd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Canonicalization: don't merge utilities that reference different theme variables set to CSS-wide keywords like `unset` ([#20417](https://github.com/tailwindlabs/tailwindcss/pull/20417)) - Don't generate utilities when a modifier is used that would otherwise be silently ignored (e.g. `rounded-sm/[5]`, `shadow-sm/foo`, `stroke-2/50`) ([#20419](https://github.com/tailwindlabs/tailwindcss/pull/20419)) - Only normalize top-level `and`, `or`, and `not` keywords in `supports-[…]` variants (e.g. `selector(a: not (.foo))` → `selector(a:not(.foo))`) ([#20420](https://github.com/tailwindlabs/tailwindcss/pull/20420)) +- Don't warn about Angular's `::ng-deep` when optimizing generated CSS ([#20433](https://github.com/tailwindlabs/tailwindcss/issues/20433)) ## [4.3.3] - 2026-07-16 diff --git a/packages/@tailwindcss-node/src/optimize.test.ts b/packages/@tailwindcss-node/src/optimize.test.ts new file mode 100644 index 000000000000..4dabfb74b922 --- /dev/null +++ b/packages/@tailwindcss-node/src/optimize.test.ts @@ -0,0 +1,63 @@ +import { afterEach, beforeEach, expect, test, vi } from 'vitest' +import { optimize } from './optimize' + +const css = String.raw + +let originalNodeEnv = process.env.NODE_ENV + +beforeEach(() => { + // The warning output is suppressed in tests, so temporarily switch to a + // non-test environment to be able to observe it. + process.env.NODE_ENV = 'production' +}) + +afterEach(() => { + process.env.NODE_ENV = originalNodeEnv + vi.restoreAllMocks() +}) + +test('does not warn about `::ng-deep`, Angular’s deep-selector combinator', () => { + let warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + + optimize(css` + :host { + ::ng-deep .foo { + color: red; + } + } + `) + + expect(warn).not.toHaveBeenCalled() +}) + +test('does not warn about `:deep()`, `:slotted()`, or `:global()`', () => { + let warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + + optimize(css` + :host { + :deep(.foo) { + color: red; + } + :slotted(.bar) { + color: red; + } + } + :global(.baz) { + color: red; + } + `) + + expect(warn).not.toHaveBeenCalled() +}) + +test('still warns about genuinely unknown pseudo-elements', () => { + let warn = vi.spyOn(console, 'warn').mockImplementation(() => {}) + + optimize(css` + .foo::totally-bogus-pseudo { + color: red; + } + `) + + expect(warn).toHaveBeenCalled() +}) diff --git a/packages/@tailwindcss-node/src/optimize.ts b/packages/@tailwindcss-node/src/optimize.ts index 6e60f8b873f6..eb180691cf28 100644 --- a/packages/@tailwindcss-node/src/optimize.ts +++ b/packages/@tailwindcss-node/src/optimize.ts @@ -62,9 +62,12 @@ export function optimize( result.warnings = result.warnings.filter((warning) => { // Ignore warnings about unknown pseudo-classes as they are likely caused - // by the use of `:deep()`, `:slotted()`, and `:global()` which are not - // standard CSS but are commonly used in frameworks like Vue. - if (/'(deep|slotted|global)' is not recognized as a valid pseudo-/.test(warning.message)) { + // by the use of `:deep()`, `:slotted()`, `:global()`, and `::ng-deep` + // which are not standard CSS but are commonly used in frameworks like + // Vue and Angular. + if ( + /'(ng-deep|deep|slotted|global)' is not recognized as a valid pseudo-/.test(warning.message) + ) { return false } From 82870492f53adf9567278eb08655521fd1e60abe Mon Sep 17 00:00:00 2001 From: koreahghg Date: Fri, 28 Aug 2026 09:17:24 +0900 Subject: [PATCH 2/2] Point changelog entry to PR #20437 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b3134ccabd7..b0fc9136d6f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Canonicalization: don't merge utilities that reference different theme variables set to CSS-wide keywords like `unset` ([#20417](https://github.com/tailwindlabs/tailwindcss/pull/20417)) - Don't generate utilities when a modifier is used that would otherwise be silently ignored (e.g. `rounded-sm/[5]`, `shadow-sm/foo`, `stroke-2/50`) ([#20419](https://github.com/tailwindlabs/tailwindcss/pull/20419)) - Only normalize top-level `and`, `or`, and `not` keywords in `supports-[…]` variants (e.g. `selector(a: not (.foo))` → `selector(a:not(.foo))`) ([#20420](https://github.com/tailwindlabs/tailwindcss/pull/20420)) -- Don't warn about Angular's `::ng-deep` when optimizing generated CSS ([#20433](https://github.com/tailwindlabs/tailwindcss/issues/20433)) +- Don't warn about Angular's `::ng-deep` when optimizing generated CSS ([#20437](https://github.com/tailwindlabs/tailwindcss/pull/20437)) ## [4.3.3] - 2026-07-16