Skip to content

fix issue 33735: Global background + color styles affecting stories#34071

Open
Axadali wants to merge 5 commits intostorybookjs:nextfrom
Axadali:33735-global-style-issue
Open

fix issue 33735: Global background + color styles affecting stories#34071
Axadali wants to merge 5 commits intostorybookjs:nextfrom
Axadali:33735-global-style-issue

Conversation

@Axadali
Copy link

@Axadali Axadali commented Mar 9, 2026

Summary

Refactor the CSS in base-preview-head.html to remove nested selectors and replace them with flat, fully-qualified selectors to prevent style leakage during CSS post-processing. Additionally, correct the selector used for styling the error stack <pre> element so it matches the actual markup structure.

Root Cause

The error display styles previously relied on nested CSS syntax such as:

.sb-errordisplay_main {
  * {
    background: white;
    color: black;
  }
}

During production builds, some CSS processors and minifiers used in common toolchains (e.g. Vite + PostCSS + cssnano/lightningcss) incorrectly flattened this nested rule into a global selector:

* {
  background: #fff;
  color: #000;
}

This caused the rule to escape the .sb-errordisplay_main scope and override styles of all components rendered inside the Storybook preview iframe.

A similar nesting pattern existed in .sb-nopreview_main using rules like & *, which could also be flattened incorrectly by certain CSS processors.

Additionally, one selector introduced during the refactor targeted:

.sb-errordisplay_main .sb-errordisplay pre

However, the actual markup defined in base-preview-body.html renders the stack trace as:

<pre class="sb-errordisplay_code">

directly under .sb-errordisplay_main. As a result, the selector did not match the DOM and the intended white-space styling was not applied.

Fix

This change removes all nested CSS selectors and replaces them with explicit flat selectors to ensure compatibility with all CSS processing pipelines.

Examples of the changes include:

  • Replace nested selectors with explicit scoped selectors:
.sb-errordisplay_main * { ... }
.sb-errordisplay_main ol { ... }
.sb-errordisplay_main h1 { ... }
  • Replace .sb-nopreview_main nested rules with flat equivalents:
.sb-nopreview_main * { ... }
  • Correct the error stack selector to match the actual markup:
.sb-errordisplay_main .sb-errordisplay_code { ... }

Using flat selectors ensures that styles remain properly scoped and prevents build tools from incorrectly hoisting selectors to the global scope.

Testing

This change affects a static HTML/CSS asset and does not have associated unit tests. The fix can be validated by:

  1. Build Storybook:
    npm run build-storybook
  2. Inspect the generated preview output to confirm:
    • No global * { background: ... } rule appears.
    • All styles remain scoped to .sb-errordisplay_main or .sb-nopreview_main.
  3. Verify runtime behavior:
    • Error overlays render correctly.
    • Error stack traces display with proper formatting.
    • Story components in the preview iframe are not affected by the error overlay styles.

Closes #34036
Closes #33947
Closes #33735

Summary by CodeRabbit

  • Style
    • Scoped global CSS resets to specific preview and error-display areas to prevent unintended styling bleed and improve maintainability.
    • Tightened and reorganized selectors to confine resets, restored targeted code-block and error-header styling, preserved visual output and dark error-theme (including code colors), and added clarifying comments for future edits.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e41ad4a8-1391-4755-bf81-8eb3ad7f34e8

📥 Commits

Reviewing files that changed from the base of the PR and between 95112ec and d177fb1.

📒 Files selected for processing (1)
  • code/core/assets/server/base-preview-head.html
🚧 Files skipped from review as they are similar to previous changes (1)
  • code/core/assets/server/base-preview-head.html

📝 Walkthrough

Walkthrough

Replaced global/universal CSS selectors in code/core/assets/server/base-preview-head.html with scoped rules under .sb-nopreview_main and .sb-errordisplay_main, converting nested/ampersand selectors to explicit class-scoped selectors and adding targeted overrides for error code blocks and headings.

Changes

Cohort / File(s) Summary
CSS Selector Scoping
code/core/assets/server/base-preview-head.html
Replaced broad/global selectors and ampersand-based nesting with scoped selectors under .sb-nopreview_main and .sb-errordisplay_main; constrained resets to these blocks, restored scoped code-block/ANSI color rules, added explicit error header and text styling, and adjusted padding/margins/typography within those components.

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
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

🧹 Nitpick comments (1)
code/core/assets/server/base-preview-head.html (1)

117-120: Add a regression check against the post-processed asset, not just the source CSS.

This bug only showed up after downstream CSS processing, so it would be worth adding a fixture/snapshot/assertion on the built preview asset that fails if a top-level * { background: ...; color: ... } rule reappears or if .sb-errordisplay_code loses its scoped styling. That would make this fix much harder to regress silently.

Also applies to: 157-160, 201-226

🤖 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 117 - 120, Add a
regression test that asserts against the post-processed built preview asset (not
the source CSS) to ensure the top-level universal rule and scoping regressions
do not reappear: build or load the final preview bundle/asset produced from
base-preview-head.html and assert that there is no top-level "* { background:
rgb(247, 247, 247); color: rgb(46, 52, 56); }" rule present and that the
".sb-errordisplay_code" selector retains its scoped styles (i.e., its expected
rules exist in the processed CSS). Locate the preview output artifact for the
preview HTML/CSS (the built preview asset), run a snapshot or string/assertion
check against it, and add this test alongside existing preview tests so future
downstream CSS processing changes fail the test if the universal selector or
unscoped styles reappear.
🤖 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 157-160: The global selector .sb-errordisplay_main * is forcing a
white background onto all descendants, which overrides ANSI-colored spans
injected via innerHTML into `#error-stack` by preview-web/WebView.ts and breaks
the dark stack-trace block; adjust the CSS so the blanket reset excludes the
stack-trace subtree (e.g., exempt .sb-errordisplay_code and its descendants or
target only textual containers) so that <pre>/<code> inside
.sb-errordisplay_code keep their intended backgrounds and nested <span> colors
are not overwritten.

---

Nitpick comments:
In `@code/core/assets/server/base-preview-head.html`:
- Around line 117-120: Add a regression test that asserts against the
post-processed built preview asset (not the source CSS) to ensure the top-level
universal rule and scoping regressions do not reappear: build or load the final
preview bundle/asset produced from base-preview-head.html and assert that there
is no top-level "* { background: rgb(247, 247, 247); color: rgb(46, 52, 56); }"
rule present and that the ".sb-errordisplay_code" selector retains its scoped
styles (i.e., its expected rules exist in the processed CSS). Locate the preview
output artifact for the preview HTML/CSS (the built preview asset), run a
snapshot or string/assertion check against it, and add this test alongside
existing preview tests so future downstream CSS processing changes fail the test
if the universal selector or unscoped styles reappear.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 63576d3c-5918-4e03-8a1a-45ea03a86e57

📥 Commits

Reviewing files that changed from the base of the PR and between 533dcc0 and a73a4c3.

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

Copy link
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: 2

🧹 Nitpick comments (1)
code/core/assets/server/base-preview-head.html (1)

208-234: Consider consolidating duplicate selector blocks.

.sb-errordisplay_main .sb-errordisplay_code is declared twice (lines 208-225 and 232-234). While functionally correct, merging them improves maintainability.

♻️ Suggested consolidation
   .sb-errordisplay_main .sb-errordisplay_code {
     padding: 10px;
     flex: 1;
     background: `#242424`;
     color: `#c6c6c6`;
     box-sizing: border-box;

     font-size: 14px;
     font-weight: 400;
     line-height: 19px;
     border-radius: 4px;

     font-family:
       'Operator Mono', 'Fira Code Retina', 'Fira Code', 'FiraCode-Retina', 'Andale Mono',
       'Lucida Console', Consolas, Monaco, monospace;
     margin: 0;
     overflow: auto;
+    white-space: pre-wrap;
   }

   .sb-errordisplay_main .sb-errordisplay_code code {
     background-color: inherit;
     color: inherit;
   }
-
-  .sb-errordisplay_main .sb-errordisplay_code {
-    white-space: pre-wrap;
-  }
🤖 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 208 - 234, The
selector .sb-errordisplay_main .sb-errordisplay_code is defined twice;
consolidate by merging all properties (padding, flex, background, color,
box-sizing, font-size, font-weight, line-height, border-radius, font-family,
margin, overflow and white-space) into a single .sb-errordisplay_main
.sb-errordisplay_code rule and keep the nested .sb-errordisplay_main
.sb-errordisplay_code code rule as-is, then remove the duplicate
empty/overlapping block to improve maintainability.
🤖 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 170-177: In .sb-errordisplay_main h1 update the font-family to
quote the multi-word family (e.g., "Nunito Sans") and remove the duplicate
font-weight declaration so only one font-weight (either 400 or normal) remains;
locate the .sb-errordisplay_main h1 rule in base-preview-head.html and make
those two edits.
- Around line 189-196: The CSS rule for .sb-errordisplay_main p and
.sb-errordisplay_main ol uses an unquoted multi-word font family "Nunito Sans";
update the font-family declaration in that rule to quote the multi-word name
(e.g., "Nunito Sans") so the browser parses it correctly and matches the
existing h1 fix pattern.

---

Nitpick comments:
In `@code/core/assets/server/base-preview-head.html`:
- Around line 208-234: The selector .sb-errordisplay_main .sb-errordisplay_code
is defined twice; consolidate by merging all properties (padding, flex,
background, color, box-sizing, font-size, font-weight, line-height,
border-radius, font-family, margin, overflow and white-space) into a single
.sb-errordisplay_main .sb-errordisplay_code rule and keep the nested
.sb-errordisplay_main .sb-errordisplay_code code rule as-is, then remove the
duplicate empty/overlapping block to improve maintainability.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aa397a4f-c788-4356-8370-773fc1f6e13c

📥 Commits

Reviewing files that changed from the base of the PR and between a73a4c3 and f04aacf.

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

Copy link
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 170-171: The CSS for .sb-errordisplay_main h1 (and similarly for p
and ol) overrides the intended .sb-wrapper font stack with only 'Nunito Sans';
change the rule to either inherit the wrapper stack or repeat the full fallback
system sans stack instead of a single font so browsers fall back correctly when
'Nunito Sans' is unavailable — update the selectors .sb-errordisplay_main h1,
.sb-errordisplay_main p, and .sb-errordisplay_main ol to use font-family:
inherit; or font-family: 'Nunito Sans', -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol";

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8284b08c-ec3a-4e2e-bb82-7b3d351034da

📥 Commits

Reviewing files that changed from the base of the PR and between f04aacf and 95112ec.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant