intermediate

CSS Modules

Scope class names per component while keeping regular CSS, composition, and build-time integration.

CSS Modules compile to locally scoped class names while keeping regular CSS syntax. Import styles as objects; the build rewrites selectors to unique hashes per module.

					/* Button.module.css */
.root { padding: 0.5rem 1rem; }
.primary { composes: root; background: var(--accent); }
				
					import styles from './Button.module.css';
<button className={styles.primary}>Save</button>
				

Composition (`composes`) shares declarations; `:global` escapes scope for resets or third-party hooks — use sparingly.

On interviews: trade-offs around scope, SSR, theming, shared tokens, and global utility layers.

Common pitfalls: local names do not fix cascade order; overusing :global erases the main benefit.

The trade-off is build-time safety versus explicit global token and layer strategy still required.

Checklist:

  • Keep exported class APIs small and explicit.
  • Share design tokens outside modules.
  • Limit :global escapes.
  • Verify SSR and code-split CSS loading.