Material UI styling
Version 1.0.0
Note: This document is for agents and LLMs maintaining or generating Material UI code. It follows How to customize and related sources in this repository (
docs/data/material/customization/,docs/data/system/).
Abstract
Material UI stacks four strategies from narrowest to broadest scope. Pick the smallest scope that solves the problem to avoid scattering global rules. The sx prop is the default for one-off tweaks; styled() is for reusable wrappers; the theme's components API is for app-wide consistency; GlobalStyles / CssBaseline is for baseline HTML or cross-cutting globals.
Table of contents
- Quick decision (use in order)
- One-off:
sxprop - Reusable:
styled() - Global theme:
createTheme({ components }) - Global CSS:
GlobalStyles/CssBaseline sxvsstyled()- Imports and consistency
- Further reading
Quick decision (use in order)
- Single instance or local layout? →
sx - Same override in many places? →
styled()around the MUI component (or a thin wrapper component) - All instances of a component should look different by default? →
theme.components(styleOverrides,variants,defaultProps) - Global element baselines (for example all
h1) or non-component CSS? →GlobalStylesorCssBaselineoverrides
Do not jump to global theme overrides for a one-off screen; do not use sx for large repeated systems if a themed variant or styled() wrapper is clearer.
1. One-off: sx prop
Use when: changing one instance (or a small inline case) with access to the theme.
- All Material UI components support
sx. - Supports theme shortcuts (
palette,spacing, breakpoints, etc.), pseudo-selectors, nested selectors, and responsive objects. - Array syntax:
sx={[base, condition && extra]}merges styles conditionally — entries applied in order, falsy entries skipped. Prefer this over object spread for conditionalsx.
Nested parts (slots): target internal slots with global class fragments, for example '& .MuiSlider-thumb'. Discover the slot name in DevTools; the pattern is Mui[Component]-[slot]. Do not rely on the full hashed class string. Use only the stable Mui* fragment.
State styles: MUI uses global state classes (.Mui-disabled, .Mui-selected, etc.) with specificity comparable to pseudo-classes. Override with increased specificity (for example combine with your class or the component root), never bare global state selectors alone.
/* Bad: affects every component using .Mui-error */
.Mui-error {
color: red;
}
/* Good: scoped to OutlinedInput root */
.MuiOutlinedInput-root.Mui-error {
color: red;
}
See How to customize—State classes.
className: use when integrating with external CSS or CSS Modules; combine with the same slot/state rules as above.
2. Reusable: styled()
Use when: the same customized component appears in multiple places and deserves a named component.
import { styled } from '@mui/material/styles';
- Prefer
@mui/material/styleswhen using Material UI so the default theme matches the rest of the app. styled()adds theme integration, optionalname/slotfor theme overrides, andsxon the result (unless disabled).- For custom props, use
shouldForwardPropso DOM/React does not receive invalid attributes. Extend the component's prop types in TypeScript.
Dynamic styling: prefer CSS variables or conditional style objects in the style callback; avoid per-field functions inside the style object for readability (see styled() docs).
3. Global theme: createTheme({ components })
Use when: default look of Button, TextField, etc. should change everywhere.
defaultProps: change defaults (for exampledisableRippleonMuiButtonBase).styleOverrides: target slots (root,input, …) with plain CSS-in-JS objects; nested selectors allowed. Use the callback formroot: ({ ownerState, theme }) => ({ ... })to branch on the component's resolved props without extra class names.variants: map props to extra styles (built-in props likevariant: 'outlined'or custom values you document for your design system).
Caveat: the theme is not tree-shakable. For heavy one-off customizations, a new component is often better than bloating the theme.
Full API: Themed components.
4. Global CSS: GlobalStyles / CssBaseline
Use when: styling raw HTML elements or app-wide snippets that are not tied to a single MUI component instance.
- Prefer hoisting
<GlobalStyles />to a module-level constant so the style tag does not churn on re-renders. stylescan be a callback for theme access.- Can extend
MuiCssBaselinestyleOverridesif the app already usesCssBaseline.
sx vs styled(): differences agents should know
| Topic | sx | styled() style object |
|---|---|---|
Theme spacing shorthand (m, p, gap, …) | Yes | No. Use theme.spacing() in a function or plain CSS values. |
Meaning of numeric padding like 1 | Theme spacing unit | Pixels, not theme.spacing(1) |
Theme palette strings ('primary.main') | Yes | Use theme in a function |
To reuse sx logic inside styled(), use theme's unstable_sx (see styled()—Difference with the sx prop).
Imports and consistency
- In application code, prefer one-level imports from packages (for example
@mui/material/Button) to avoid pulling the entire barrel. - Use
sxfor system layout shortcuts (p,gap,mt, etc.) on MUI components; use component props only for behavior documented by that component.
Further reading (repo / site)
| Topic | Doc |
|---|---|
| Choosing strategy | How to customize |
sx reference | The sx prop |
styled() API | styled() |
| Theme per component | Themed components |
| System property mapping | System properties |
| State / class naming | Advanced—Class names (system styles) |
For MUI-specific class and state tables, see reference.md.