Skip to content

feat(core, react): css scoping#80

Merged
chakrihacker merged 32 commits into
mainfrom
feat/css-scoping
Mar 5, 2026
Merged

feat(core, react): css scoping#80
chakrihacker merged 32 commits into
mainfrom
feat/css-scoping

Conversation

@chakrihacker

@chakrihacker chakrihacker commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

This PR establishes a clear contract between two CSS distribution modes:

  • styles.css — Scoped build. Auth0 feature components always render with Auth0's own design system, fully isolated from the user's global styles.
  • tailwind.css — Unscoped build. Auth0 components participate in the user's Tailwind design tokens, allowing branding customization.

Previously, styles.css consumers who wrapped their app in Auth0ComponentProvider had their own page elements inadvertently isolated from their custom global styles. This PR fixes that isolation boundary so it applies only to auth0 feature components, not to the user's content.

What Changed

The data-theme attribute is moved from the outer Auth0ComponentProvider wrapper down to the root element of each individual auth0 feature component. This makes the CSS scope boundary precise — it covers exactly the components that need it, nothing more.

Scenario Coverage

Consumer Their page elements Auth0 feature components
styles.css, no custom styles default system styles Auth0 design system
styles.css, custom global styles defined their custom styles apply Auth0 design system (unaffected)
styles.css, app wrapped in Auth0ComponentProvider their custom styles apply Auth0 design system (unaffected)
tailwind.css, no custom styles default Tailwind tokens Auth0 design system
tailwind.css, custom branding tokens their custom tokens apply their custom tokens apply
Dialog / dropdown portals (styles.css) Auth0 design system (portal container retains scope)

Changes

packages/react/postcss.config.mjs

  • Added postcss-prefix-selector plugin (gated behind CSS_SCOPE=true env var) that prefixes all selectors with .auth0, transforming [data-theme='default'] → .auth0
    [data-theme='default']. html/body selectors are excluded; :root is expanded to :root, .auth0.

packages/react/src/styles/globals.css

  • Added three [data-theme] blocks (default, minimal, rounded) that re-anchor all bridge variables to Auth0 design-system tokens. After the PostCSS transform these become
    .auth0 [data-theme='...'] { ... } in the built dist/styles.css.

packages/react/src/providers/theme-provider.tsx

  • Removed data-theme from the main .auth0 content wrapper (scoping is now done per-component, not at the provider level).
  • Exposed theme in ThemeContext.Provider value so feature components can read it.
  • Added a dedicated portal container
    that Radix UI portals render into, ensuring overlay elements still receive the correct theme.

packages/react/src/providers/portal-context.tsx (new)

  • New PortalContext that stores the portal container element and exposes it via usePortalContainer() hook, consumed by Radix UI primitives (Dialog, Popover,
    DropdownMenu, Select, Tooltip).

Feature components (domain-table, organization-details-edit, user-mfa-management, sso-provider-table, sso-provider-edit, sso-provider-create)

  • Each component destructures theme from useTheme() and renders data-theme={theme || 'default'} on its root div, creating the isolation boundary that the CSS rules
    target.

Examples (next-rwa, react-spa-npm)

  • Updated to demonstrate CSS scoping in action: host app declares custom :root variables while Auth0 components render with their own design-system colours.

Testing

Please describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this library has unit and tests should be added for new functionality and existing tests should complete without errors.

  • This change adds unit test coverage
  • This change has been tested on the latest version of the platform/language or why not

Checklist

@github-actions

github-actions Bot commented Feb 11, 2026

Copy link
Copy Markdown

🚀 Preview deployment

Branch: refs/pull/80/merge
Commit: 24be294

📝 Preview URL: https://auth0-universal-components-f36rltp7y-okta.vercel.app


Updated at 2026-03-05T07:16:14.646Z

@codecov-commenter

codecov-commenter commented Feb 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.18%. Comparing base (4cc59cf) to head (181be08).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #80      +/-   ##
==========================================
+ Coverage   88.17%   88.18%   +0.01%     
==========================================
  Files         143      144       +1     
  Lines       12497    12513      +16     
  Branches     1670     1320     -350     
==========================================
+ Hits        11019    11035      +16     
  Misses       1478     1478              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chakrihacker chakrihacker marked this pull request as ready for review February 24, 2026 13:12
Comment thread packages/react/postcss.config.mjs Outdated
'@tailwindcss/postcss': {},
...(isScoped && {
'postcss-prefix-selector': {
prefix: '.auth0',

@rax7389 rax7389 Feb 24, 2026

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.

please cross check with suraj once, regarding the prefix, he had some suggestion

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@SurajThotakura please provide your inputs here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The name auth0 is too generic and there is a chance that the customers might have a class with the same name. Let's update this to .auth0-uic or .auth0-root whichever makes more sense. @rax7389 please suggest the name.

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.

@SurajThotakura @chakrihacker .auth0-universal?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

.auth0-universal is good

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.

i think it should be

// Before: keeps :root (leaks)
return ${selector}, ${prefix}${selector.replace(':root', '')};

// After: replaces :root (scoped)

if (selector === ':root') return prefix;
if (selector.match(/^:root/)) return `${prefix}${selector.replace(':root', '')}`;
if (selector.match(/^\.dark/)) return `${prefix}${selector}`;

Comment thread examples/next-rwa/src/components/navigation/profile-dropdown.tsx
import CodeBlock from '../components/CodeBlock';
import TabbedCodeBlock from '../components/TabbedCodeBlock';

export default function Styling() {

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.

Please have this confirmed form suraj or jcobo, if we need a separate page for this or we are good to have it in Getting Started

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@SurajThotakura Need your inputs here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's keep styling in it's dedicated page. This is inline with what other UI Libraries do, shadcn has "Theming" and Clerk has "Appearance".

Minor enhancement:
We should add a "Styling" section in the getting started page where we describe how we can customize our components and link to the Styling page.

## Styling                                                                                                                      
                                                                                                                                  
Auth0 components come with pre-built styles — no CSS configuration required. Choose the stylesheet that fits your setup, and customize with CSS variables to match your brand.         

<CardGroup cols={2}>
  <Card title="Standalone Apps" icon="box">
    Import `styles.css` for a self-contained stylesheet with all Tailwind utilities pre-compiled and scoped. No Tailwind setup
required.
    ```tsx
    import '@auth0/universal-components-react/styles';
    ```
  </Card>
  <Card title="Tailwind Apps" icon="wind">
    Import `tailwind.css` to integrate with your existing Tailwind build. Class names are scanned automatically.
    ```tsx
    import '@auth0/universal-components-react/tailwind';
    ```
  </Card>
</CardGroup>

**Theming options:**
- **Color modes** — Light and dark themes with automatic switching
- **Theme variants** — Choose from `default`, `minimal`, or `rounded` styles
- **CSS variables** — Override 50+ design tokens for colors, typography, shadows, and border radii

<Card title="Styling & Theming Guide" icon="paintbrush" href="/universal-components/styling">
  Learn how to customize colors, typography, and component styles to match your brand.
</Card>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can further improve this page by addressing the following gaps.

  1. CardGroup with code blocks in 2 columns - looks cramped
  2. Redundancy - CSS variables in Tabs are repeated verbatim in tables below
  3. Missing dark mode - no guidance on dark theme variables

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.

@chakrihacker can you confirm if this above suggestion is taken care of can you also have this reviewed again by Suraj on the above?

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.

@chakrihacker can you confirm if this above suggestion is taken care of can you also have this reviewed again by Suraj on the above?

can you confirm on this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes it's added

Comment thread packages/react/src/styles/globals.css Outdated
Comment thread packages/react/src/providers/theme-provider.tsx
Comment thread packages/react/src/providers/theme-provider.tsx Outdated
<ThemeContext.Provider value={{ isDarkMode: mode === 'dark', theme, variables, loader }}>
<PortalContext.Provider value={portalContainer}>
<div className="auth0">{children}</div>
<div className="auth0" data-theme={theme || 'default'} ref={setPortalContainer} />

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.

why not set a fallback value here

const { variables, loader, mode, theme } = React.useMemo(
    () => ({
      variables: themeSettings?.variables ?? defaultStyleOverrides,
      loader: themeSettings?.loader ?? null,
      mode: themeSettings?.mode,
      theme: themeSettings?.theme ?? 'default',
    }),
    [themeSettings],
  );

so you dont have to do this data-theme={theme || 'default'} and just have data-theme={theme}

Comment thread packages/react/src/styles/globals.css Outdated
*/
[data-theme='default'] {
--background: var(--color-neutral-min);
--foreground: var(--color-neutral-12);

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.

Dont think , this should be needed

--color-page: var(--color-neutral-2);
--color-background: var(--background, var(--color-neutral-min));
--color-foreground: var(--foreground, var(--color-neutral-12));
--color-background: var(--auth0-background, var(--color-neutral-min));

@NaveenChand755 NaveenChand755 Mar 2, 2026

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.

why are we hardcoding auth0 ? what if user defines --foreground at root in his app , shouldnt those be inherited by default by component library ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Users have to add auth0 variables to their style variables. It will be documented

@rax7389 rax7389 left a comment

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.

@chakrihacker please correct the title of this PR

@chakrihacker chakrihacker changed the title css scoping feat(core, react): css scoping Mar 3, 2026
@chakrihacker

Copy link
Copy Markdown
Contributor Author

@chakrihacker please correct the title of this PR

done

Comment thread packages/react/src/components/auth0/my-organization/sso-provider-edit.tsx Outdated
Comment thread packages/react/src/providers/portal-context.tsx
Comment thread packages/react/src/providers/theme-provider.tsx Outdated
Comment thread packages/react/src/providers/theme-provider.tsx
@chakrihacker chakrihacker merged commit 4fd37f1 into main Mar 5, 2026
7 checks passed
@chakrihacker chakrihacker deleted the feat/css-scoping branch March 5, 2026 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants