Skip to content

fix(compiler-sfc): handle nested :deep in selector pseudos#14725

Merged
edison1105 merged 1 commit into
mainfrom
edison/fix/14724
Apr 22, 2026
Merged

fix(compiler-sfc): handle nested :deep in selector pseudos#14725
edison1105 merged 1 commit into
mainfrom
edison/fix/14724

Conversation

@edison1105

@edison1105 edison1105 commented Apr 15, 2026

Copy link
Copy Markdown
Member

close #14724

Summary by CodeRabbit

  • Bug Fixes

    • Corrected scoped CSS handling for nested deep selectors inside complex pseudo-classes (:is, :where, :has, :not), including proper application of scope attributes and correct splitting of combined selectors so styles apply as expected.
  • Tests

    • Added and updated tests and snapshots covering nested :deep() scenarios (single and comma-separated arguments), negation/has cases, and selector-splitting behavior.

@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Detects and correctly rewrites nested :deep()/::v-deep inside container pseudo-classes (:is, :where, :has, :not), optionally splitting selectors and gating scoped attribute injection so scope anchors are applied inside the pseudo-arguments and trailing selectors are scoped appropriately.

Changes

Cohort / File(s) Summary
Test assertions
packages/compiler-sfc/__tests__/compileStyle.spec.ts
Expanded test coverage for :deep()/::v-deep nested inside :is(), :where(), :has(), and :not() (single and comma-separated arguments). Updated inline snapshots to assert in-argument scoping and correct splitting of combined selectors.
Selector rewriting logic
packages/compiler-sfc/src/style/pluginScoped.ts
Added hasNestedDeep and splitForNestedDeep state; enhanced rewriteSelector to detect deep-containing container pseudos, propagate deep into branches, optionally split pseudo branches (splitSelectorForNestedDeep), and suppress anchor selection/node injection when nested deep is present. Added helpers: isDeepSelector, isDeepContainerPseudo, canSplitDeepContainerPseudo, and splitSelectorForNestedDeep.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

:hammer: p3-minor-bug

Suggested reviewers

  • Doctor-wu

Poem

🐰 I hop through nested pseudo land,
:deep() tucked safe inside my hand,
I split and scope with careful art,
So selectors compile — each little part. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The code changes fully implement the requirements from issue #14724, adding support for :deep resolution inside :is(), :where(), :not(), and :has() pseudo-classes with proper scope attribute scoping.
Out of Scope Changes check ✅ Passed All changes are directly related to the scope of issue #14724; test extensions validate the fix, and implementation changes handle nested :deep selector resolution without introducing unrelated modifications.
Title check ✅ Passed The title accurately describes the main change: fixing handling of nested :deep selectors within pseudo-classes like :is, :where, :not, and :has.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch edison/fix/14724

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 105 kB 39.9 kB 35.8 kB
vue.global.prod.js 164 kB 59.9 kB 53.2 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 48.3 kB 18.8 kB 17.2 kB
createApp 56.5 kB 21.8 kB 20 kB
createSSRApp 60.7 kB 23.6 kB 21.5 kB
defineCustomElement 62.6 kB 23.8 kB 21.7 kB
overall 71 kB 27.2 kB 24.7 kB

@pkg-pr-new

pkg-pr-new Bot commented Apr 15, 2026

Copy link
Copy Markdown

Open in StackBlitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@14725
npm i https://pkg.pr.new/@vue/compiler-core@14725
yarn add https://pkg.pr.new/@vue/compiler-core@14725.tgz

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@14725
npm i https://pkg.pr.new/@vue/compiler-dom@14725
yarn add https://pkg.pr.new/@vue/compiler-dom@14725.tgz

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@14725
npm i https://pkg.pr.new/@vue/compiler-sfc@14725
yarn add https://pkg.pr.new/@vue/compiler-sfc@14725.tgz

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@14725
npm i https://pkg.pr.new/@vue/compiler-ssr@14725
yarn add https://pkg.pr.new/@vue/compiler-ssr@14725.tgz

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@14725
npm i https://pkg.pr.new/@vue/reactivity@14725
yarn add https://pkg.pr.new/@vue/reactivity@14725.tgz

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@14725
npm i https://pkg.pr.new/@vue/runtime-core@14725
yarn add https://pkg.pr.new/@vue/runtime-core@14725.tgz

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@14725
npm i https://pkg.pr.new/@vue/runtime-dom@14725
yarn add https://pkg.pr.new/@vue/runtime-dom@14725.tgz

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@14725
npm i https://pkg.pr.new/@vue/server-renderer@14725
yarn add https://pkg.pr.new/@vue/server-renderer@14725.tgz

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@14725
npm i https://pkg.pr.new/@vue/shared@14725
yarn add https://pkg.pr.new/@vue/shared@14725.tgz

vue

pnpm add https://pkg.pr.new/vue@14725
npm i https://pkg.pr.new/vue@14725
yarn add https://pkg.pr.new/vue@14725.tgz

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@14725
npm i https://pkg.pr.new/@vue/compat@14725
yarn add https://pkg.pr.new/@vue/compat@14725.tgz

commit: 38a2847

@haoqunjiang

Copy link
Copy Markdown
Member

I think there's a similar issue with :not() and :has() too.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/compiler-sfc/src/style/pluginScoped.ts`:
- Around line 154-162: The current early return inside the condition checking
value === ':not' && !deep && !hasScopeAnchor && hasMixedSelectors &&
hasTrailingNodes silently skips selectors like :not(:deep(.foo), .bar) and
leaves :deep unresolved; update the branch that currently returns to instead
emit a compile-time warning (e.g., call an existing logger/warn helper or add a
new warnUnsupportedNotWithDeep helper) that includes the selector text and
explains :not(...) with mixed selectors and nested :deep() is unsupported, then
return; reference the variables value, deep, hasScopeAnchor, hasMixedSelectors,
hasTrailingNodes and the conditional block in pluginScoped.ts when implementing
this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: df43d668-90ab-4065-9af3-2fa2cfe4c591

📥 Commits

Reviewing files that changed from the base of the PR and between 4dee52f and 38a2847.

📒 Files selected for processing (2)
  • packages/compiler-sfc/__tests__/compileStyle.spec.ts
  • packages/compiler-sfc/src/style/pluginScoped.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/compiler-sfc/tests/compileStyle.spec.ts

Comment thread packages/compiler-sfc/src/style/pluginScoped.ts
@edison1105 edison1105 changed the title fix(compiler-sfc): resolve :deep within :is and :where fix(compiler-sfc): handle nested :deep in selector pseudos Apr 17, 2026
@edison1105 edison1105 added the ready to merge The PR is ready to be merged. label Apr 22, 2026
@edison1105

Copy link
Copy Markdown
Member Author

/ecosystem-ci run

@vue-bot

vue-bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

📝 Ran ecosystem CI: Open

suite result latest scheduled
router success success
vant success success
pinia success success
vueuse success success
radix-vue success success
vite-plugin-vue success success
quasar success success
primevue success success
vitepress success success
vue-macros success success
vue-i18n success success
test-utils success success
nuxt success success
vue-simple-compiler success success
language-tools success success
vuetify success success

@edison1105 edison1105 merged commit bb9d265 into main Apr 22, 2026
15 of 16 checks passed
@edison1105 edison1105 deleted the edison/fix/14724 branch April 22, 2026 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready to merge The PR is ready to be merged. scope: sfc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

:deep within :is is not resolved when there is another selector

3 participants