Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk4 min

CSS Modules: How to Scope Styles

CSS Modules map local class names to generated selectors. Learn how to import and use them, when to use global selectors, composition constraints, and framework caveats.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

CSS Modules scope class names locally by default: define a class in a module stylesheet, import that stylesheet, and use the exported mapping (such as styles.button) in your markup. The build integration turns the local name into a generated class name, so another module can use the same source name without a collision. This is build-time class-name mapping—not browser-level isolation.

How CSS Modules scope styles

CSS Modules let you write ordinary CSS while your project’s build integration treats class selectors as local to the module by default. Importing a module gives you a mapping from the names you wrote to generated names used in the output. The CSS Modules project describes the compilation target as ICSS, a low-level interchange format. This approach is not limited to React; JSX is used here because it makes the mapping easy to see.

For example, a .button class in one module and a .button in another can coexist: each module’s local name is mapped independently. In component markup, refer to the class through the imported object rather than writing the generated name yourself. See the CSS Modules project documentation.

Define and use a local class

Create a module stylesheet and import it in the component or code that needs the styles.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
/* Card.module.css */
.card {
  border: 1px solid #ddd;
}

.title {
  font-weight: 700;
}
import styles from './Card.module.css';

export function Card() {
  return (
    <article className={styles.card}>
      <h2 className={styles.title}>Title</h2>
    </article>
  );
}

styles.card and styles.title refer to the generated class mappings produced by the project’s CSS Modules integration. The exact generated spelling is an implementation detail and can vary; use the exported mapping instead of hard-coding it. Keep the CSS selector name and the mapping property aligned, and make sure the module is imported where its styles are used.

Use global selectors only as deliberate exceptions

When a style must target a global hook—such as a class supplied by a third-party library—CSS Modules documents :global(...) as an escape hatch. For example:

/* Widget.module.css */
:global(.vendor-widget) {
  margin-block: 1rem;
}

This explicitly targets the global .vendor-widget class instead of creating a local class mapping for it. Use global selectors for integration points, not as a substitute for local component styles. See the project’s CSS Modules documentation for its documented global-selector forms.

Combine local classes with composition

The composes declaration lets one local class include another local class, including one defined in a different module:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
/* Button.module.css */
.base {
  font: inherit;
  border: 0;
}

.primary {
  composes: base;
  background: navy;
  color: white;
}

The exported mapping for styles.primary includes the composed class as well as the class generated for primary. Composition has constraints: it applies to a single local class selector, and its declarations must appear before other declarations in that rule. Circular composition has undefined override behavior and may produce an error, so keep composition dependencies one-way. The CSS Modules composition documentation describes these rules.

Configure CSS Modules in a framework

CSS Modules behavior depends on the framework or build integration. In Next.js, the documented filename convention is .module.css, and importing the file yields a styles object. Follow the documentation for the router and framework version actually used by the project.

Next.js Pages Router

For the Pages Router, Next.js recommends importing site-wide global CSS at the application root. CSS import order can affect predictable production output, so keep global imports deliberate and consult the Pages Router CSS guide for the applicable version.

Next.js App Router

The App Router documentation permits global CSS imports in layouts, pages, or components and describes production CSS concatenation and code splitting. Do not apply the Pages Router placement rule as if it were universal; use the App Router CSS guide for the router in use.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What local scope does—and does not—guarantee

CSS Modules prevent collisions between local class names through build-time mapping. They are not Shadow DOM, a runtime security boundary, or complete isolation from the cascade. Global selectors and element selectors still participate in ordinary CSS; inherited properties, custom properties, specificity, and import order can also affect rendered styles. Treat the module boundary as a way to manage class selector names, not as a promise that no outside CSS can affect an element.

Common problems and fixes

  • The class is missing or styles do not apply: Confirm the stylesheet follows the module convention recognized by your framework (in Next.js, .module.css), is imported, and the markup uses the exported mapping such as styles.card.
  • A global or vendor class is not targeted: A module’s ordinary class selectors are local. Use the documented :global(...) form for a deliberate global selector.
  • The same class name appears in multiple modules: That is expected; local names are mapped per module. Do not replace mapping references with guessed generated names.
  • Composed styles fail or have surprising precedence: Check that composes applies to one local class selector, appears before other declarations in the rule, and does not form a circular dependency.
  • Global CSS behaves differently in production: Review import placement and ordering for your framework and router. Next.js documents different global CSS guidance for its Pages and App Routers.

Or skip the browser setup

If you need screenshots of a page while checking the result, ScreenshotNeo provides a website screenshot API: one GET request can return a PNG, JPEG, WebP, or PDF. Its cleanup steps can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify page verdict and billing status in headers. An MCP server also exposes screenshot tools to AI agents and MCP clients.

For example, save a screenshot of a page as WebP with cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Its free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for the free plan.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
  2. Cupertino desk5 min
    Apple Unveils AirPods Max 2: The Upgrade That Should Have Happened Years AgoAirPods Max 2 adds H2-powered audio features and Apple claims up to 1.5× more effective ANC, but its design, Smart Case, and 20-hour battery rating are unchanged. Wired lossless audio…
  3. Cupertino desk4 min
    Apple’s OLED Touch MacBooks Are Coming—but the Dynamic Island Is the Real GambleApple has not announced an OLED touchscreen MacBook, but reports point to high-end models arriving in late 2026 or early 2027. The reported Mac Dynamic Island could be useful, but…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.