Skip to content

fix(core): replace nested CSS selectors with flat selectors in preview iframe#34057

Closed
mibragimov wants to merge 145 commits into
storybookjs:mainfrom
mibragimov:fix/issue-34036
Closed

fix(core): replace nested CSS selectors with flat selectors in preview iframe#34057
mibragimov wants to merge 145 commits into
storybookjs:mainfrom
mibragimov:fix/issue-34036

Conversation

@mibragimov
Copy link
Copy Markdown

@mibragimov mibragimov commented Mar 7, 2026

Summary

Replace all nested CSS selectors in base-preview-head.html with flat, fully-qualified selectors to prevent a global * style leak caused by incorrect CSS nesting flattening.

Root Cause

The CSS nested selector * { background: white; color: black; } inside .sb-errordisplay_main was being incorrectly flattened by some CSS post-processors and build tools (e.g. Vite with CSS minification, PostCSS) into a global * { background: #fff; color: #000; } rule. This leaked out of the Storybook error display block and overrode all user styles in the preview iframe.

The same problem affected .sb-nopreview_main's & * { ... } nested rule.

This is a CSS nesting syntax issue: while modern browsers support @layer-nested CSS natively, many CSS post-processing tools (including some versions of PostCSS/cssnano/lightningcss used by Vite) do not correctly handle arbitrary nesting and may de-nest the * selector to the root scope.

Fix

Replace all nested CSS selectors in base-preview-head.html with flat, explicit selectors:

  • .sb-errordisplay_main * { ... } instead of nesting * { ... } inside .sb-errordisplay_main
  • .sb-errordisplay_main ol { ... }, .sb-errordisplay_main h1 { ... }, etc. instead of & ol, & h1 nested forms
  • .sb-nopreview_main * { ... } instead of & * { ... } inside .sb-nopreview_main

The flat selector approach is unambiguous, universally supported, and safe across all CSS processors.

Testing

This is a static HTML/CSS file with no associated unit tests. The fix can be verified by:

  1. Building Storybook and inspecting the generated base-preview-head.html
  2. Checking that no global * { background: ... } rule appears in the built CSS
  3. Verifying that the error display and no-preview overlays still display correctly

Closes #34036
Closes #33947
Closes #33735

Summary by CodeRabbit

  • Refactor
    • Improved CSS selector specificity and organization for error display and preview blocks to enhance styling isolation and maintainability.

storybook-bot and others added 30 commits January 21, 2026 14:19
…test-mocker-resolution

Builder-Webpack5: Fix @vitest/mocker resolution issue
(cherry picked from commit abd4b01)
…-init-telemetry

CLI: Add init telemetry for CLI integrations
(cherry picked from commit 94f79bf)
…ent-agent-detection-telemetry

Telemetry: Add agent detection
(cherry picked from commit 945a876)
…-factories-monorepo

Docs: Add FAQ about sharing config in monorepos for CSF Next
(cherry picked from commit 90b7abb)
…-loginurl

Composition: Handle 401 responses with loginUrl from Chromatic
(cherry picked from commit afdf02a)
…vitest-prevent-double-nesting

Addon-Vitest: Append Storybook project to existing test.projects array without double nesting
(cherry picked from commit 5bbb915)
…vitest-support-simple-workspace-config

Addon Vitest: Support simple vite.config without defineConfig helper

(cherry picked from commit 751f18f)
…ckage-benchmarking

Build: Fix package benchmarking
(cherry picked from commit 48cecda)
…st-flake

E2E: Fix flakey test
(cherry picked from commit ac039aa)
…vitest-requireassertions

Addon-Vitest: Update Vitest plugin configuration to disable requireAssertions for expect
(cherry picked from commit b18d12e)
Core: Fix `previewHref` when current path does not end with a slash
(cherry picked from commit 00f506c)
…s-addon-vitest-31768

Addon-Vitest: Normalize Windows paths in addon-vitest automigration
(cherry picked from commit 3802b16)
…mod-windows

Codemod: Fix glob pattern handling on Windows
(cherry picked from commit 4d07f57)
…ories-non-interactive-mode

CSFFactories: Add non-interactive mode and --glob flag
(cherry picked from commit e9c8a87)
storybook-bot and others added 17 commits March 3, 2026 10:07
…figfile-parser-warning

CSF-Factories: Fix ConfigFile parser false warning on `definePreview({...}).type<T>()` export default
(cherry picked from commit 011e081)
…etadata

Core: Add vike metadata frameworks
(cherry picked from commit 1fe47b7)
…et-resolution

Core: Resolve builder preset path correctly in pnpm strict mode
(cherry picked from commit 5c8e0ea)
…on-docs

Docs: Add `allowedHosts` core config option
(cherry picked from commit e81fd16)
Core: Add host/origin validation to requests and websocket connections
(cherry picked from commit 7284b33)
…-hosts

Core: Update default allowed hosts in host validation middleware
(cherry picked from commit 0bd0483)
…w iframe

The CSS nested selector syntax `* { ... }` inside `.sb-errordisplay_main`
was being incorrectly flattened by some CSS post-processors and build tools
(e.g. Vite, PostCSS) into a global `* { background: #fff; color: #000; }`
rule that leaked into the story iframe and overrode user styles.

Replace all nested CSS selectors in base-preview-head.html with flat,
fully-qualified selectors that are unambiguous and safe across all CSS
processors. The same issue applied to `.sb-nopreview_main`'s `& *` rule.

Fixes storybookjs#34036
Fixes storybookjs#33947
Fixes storybookjs#33735
@mibragimov mibragimov marked this pull request as ready for review March 7, 2026 14:25
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 7, 2026

📝 Walkthrough

Walkthrough

CSS selectors in the nopreview and error display blocks are refactored from broad/nested patterns to scoped class-specific variants. Changes target code/core/assets/server/base-preview-head.html, converting generic selectors to .sb-nopreview_main and .sb-errordisplay_main scoped rules with equivalent properties.

Changes

Cohort / File(s) Summary
CSS Selector Scoping
code/core/assets/server/base-preview-head.html
Refactored nopreview and error display CSS selectors from broad/nested patterns (e.g., & *, & ol, & h1) to scoped class-specific equivalents (.sb-nopreview_main *, .sb-errordisplay_main ol, etc.). Reorganized related blocks under parent scoped selectors with no functional logic changes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 `@code/core/assets/server/base-preview-head.html`:
- Around line 225-228: The CSS selector targeting the error stack doesn't match
the actual markup: update the rule that currently targets ".sb-errordisplay_main
.sb-errordisplay pre" so it actually matches the <pre> which has class
"sb-errordisplay_code" directly under ".sb-errordisplay_main"; change the
selector to target ".sb-errordisplay_main pre.sb-errordisplay_code" (or
".sb-errordisplay_main .sb-errordisplay_code") and keep the existing white-space
properties to ensure the error stack override is applied to the correct element.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ab0a5d23-4a98-46cf-be29-f60b2f5f6119

📥 Commits

Reviewing files that changed from the base of the PR and between 8a7f39a and 0a66dcd.

📒 Files selected for processing (1)
  • code/core/assets/server/base-preview-head.html

Comment on lines +225 to 228
.sb-errordisplay_main .sb-errordisplay pre {
white-space: pre-wrap;
white-space: revert;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix the pre selector; it no longer matches the error markup.

In code/core/assets/server/base-preview-body.html:84-119, the <pre> itself has class="sb-errordisplay_code" and sits directly under .sb-errordisplay_main, so .sb-errordisplay_main .sb-errordisplay pre never applies. That leaves the error stack white-space override unscoped again.

Suggested fix
-  .sb-errordisplay_main .sb-errordisplay pre {
+  .sb-errordisplay_main .sb-errordisplay_code {
     white-space: pre-wrap;
     white-space: revert;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.sb-errordisplay_main .sb-errordisplay pre {
white-space: pre-wrap;
white-space: revert;
}
.sb-errordisplay_main .sb-errordisplay_code {
white-space: pre-wrap;
white-space: revert;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/core/assets/server/base-preview-head.html` around lines 225 - 228, The
CSS selector targeting the error stack doesn't match the actual markup: update
the rule that currently targets ".sb-errordisplay_main .sb-errordisplay pre" so
it actually matches the <pre> which has class "sb-errordisplay_code" directly
under ".sb-errordisplay_main"; change the selector to target
".sb-errordisplay_main pre.sb-errordisplay_code" (or ".sb-errordisplay_main
.sb-errordisplay_code") and keep the existing white-space properties to ensure
the error stack override is applied to the correct element.

@valentinpalkovic
Copy link
Copy Markdown
Contributor

Hi @mibragimov,

Due to a recent high volume of unreviewed AI-generated PRs, we are randomly requesting verification and proof that the implemented fix actually works. Please provide a simple GIF/Video or image of how the bugfix works, optimally with before-and-after comparisons.

Thank you for your understanding!

@valentinpalkovic
Copy link
Copy Markdown
Contributor

I am closing this PR due to the huge number of changes. Could you please open a new PR and address the feedback I had? Thank you so much for your contribution so far!

@github-project-automation github-project-automation Bot moved this from Blocked to Done in Core Team Projects Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.