Responsive theming with Material UI's sx prop
Use Material UI's sx prop for theme-aware, breakpoint-responsive styles without leaving your component file.
08 Dec 2025, 16:08 UTC

The problem: hardcoded values break dark mode
You are building a Material UI card that needs different padding on tablets and a background color that follows the active theme. Writing a CSS module means jumping between files for a one-off style. Hardcoding hex values breaks when the user switches to dark mode. Material UI's sx prop solves this by letting you write theme-aware, breakpoint-responsive styles directly on the component.
What sx does
The sx prop accepts a plain object or a function that receives the MUI theme. Inside the object, you can reference theme tokens such as primary.main, background.paper, or spacing units instead of raw pixels. MUI resolves these at render time.
<Box
sx={
bgcolor: 'background.paper',
color: 'text.primary',
p: 2,
borderRadius: 2,
}
>
Content
</Box>
Here p: 2 means two theme spacing units, not 2px. The actual pixel value depends on the theme's spacing factor.
Responsive breakpoints inside sx
You can conditionally apply styles by viewport width using MUI breakpoint keys: xs, sm, md, lg, and xl. Two common syntaxes work:
- Object syntax: nested breakpoint keys override base styles.
- Array syntax: a mobile-first array maps values to breakpoints in order.
sx={
p: 1,
sm: { p: 2 },
md: { p: 3 },
}
sx={
p: [1, 2, 3], // xs, sm, md+
}
Worked example: a responsive card
This example assumes MUI v5 or v6. It renders a card whose background and text color follow the theme, with padding that increases on medium viewports and up. If you are on MUI v4 or migrating to v6, check the official migration guide because the sx signature and TypeScript types changed.
import { Box, Card, CardContent, Typography, ThemeProvider, createTheme } from '@mui/material';
const theme = createTheme({ palette: { mode: 'dark' } });
export default function FeatureCard() {
return (
Responsive card
);
}
The md: { p: 4 } rule applies only at the md breakpoint and above. Because the color and background reference theme tokens, the card adapts automatically when the theme changes.
Trade-offs and limitations
- Bundle size:
sxstyles are generated at runtime. Heavy use across many components can increase JavaScript bundle size compared to static CSS. - Debugging: Styles are injected dynamically and may not appear in static CSS exports or server-rendered HTML without correct hydration.
- Specificity: Combining
sxwithclassNameor CSS modules can create specificity conflicts. Inline styles fromsxusually win, which can make overrides harder to predict. - SSR: If
ThemeProvideris not hydrated correctly, the initial HTML may omitsxstyles, causing a layout shift on first load.
Verify the result
| Check | Where to run | Expected result | Risk if skipped |
|---|---|---|---|
| Inspect resolved inline styles | Browser React DevTools, Elements tab | style attribute contains resolved theme values |
Theme tokens not applied; dark mode looks wrong |
| Assert inline style presence | Test file with @testing-library/react | Root element has expected style attributes | Regression in theme-aware styling goes undetected |
| Inspect server HTML | Node SSR render output | sx styles present in initial markup |
Layout shift or flash of unstyled content |
Use sx when a style depends on theme tokens or breakpoints and is unlikely to be reused elsewhere. Extract to styled() or CSS modules when you need reusable classes, complex animations, or static stylesheets. Always confirm token resolution in DevTools, and check server-rendered output if your app uses SSR.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.