Files
how2ice 005cf56baf
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
init project
2025-12-12 14:26:25 +09:00

361 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# The sx prop
<p class="description">The sx prop is a shortcut for defining custom styles that have access to the theme.</p>
The `sx` prop lets you work with a superset of CSS that packages all of the style functions exposed in `@mui/system`.
You can specify any valid CSS using this prop, as well as many _theme-aware_ properties that are unique to MUI System.
## Basic example
The following demo illustrates how to work with the `sx` prop.
Note that not all of the values are valid CSS properties—that's because the `sx` keys are mapped to specific properties of the theme.
The rest of this document explores this concept in more detail.
{{"demo": "Example.js", "bg": true, "defaultCodeOpen": true}}
## Theme-aware properties
### Borders
The `border` property can only receive a number as a value.
It creates a solid black border using the number to define the width in pixels:
```jsx
<Box sx={{ border: 1 }} />
// equivalent to border: '1px solid black'
```
The `borderColor` property can receive a string, which represents the path in `theme.palette`:
```jsx
<Box sx={{ borderColor: 'primary.main' }} />
// equivalent to borderColor: theme => theme.palette.primary.main
```
The `borderRadius` property multiplies the value it receives by the `theme.shape.borderRadius` value (the default for this value is `4px`).
```jsx
<Box sx={{ borderRadius: 2 }} />
// equivalent to borderRadius: theme => 2 * theme.shape.borderRadius
```
Read more on the [Borders page](/system/borders/).
### Display
The `displayPrint` property allows you to specify a CSS `display` value that will only be applied when printing:
```jsx
<Box sx={{ displayPrint: 'none' }} /> // equivalent to '@media print': { display: 'none' }
```
Read more on the [Display page](/system/display/).
### Grid
The CSS Grid properties `gap`, `rowGap` and `columnGap` multiply the values they receive by the `theme.spacing` value (the default for the value is `8px`).
```jsx
<Box sx={{ gap: 2 }} />
// equivalent to gap: theme => theme.spacing(2)
```
Read more on the [Grid page](/system/grid/).
### Palette
The `color` and `backgroundColor` properties can receive a string, which represents the path in `theme.palette`:
```jsx
<Box sx={{ color: 'primary.main' }} />
// equivalent to color: theme => theme.palette.primary.main
```
The `backgroundColor` property is also available through its alias `bgcolor`:
```jsx
<Box sx={{ bgcolor: 'primary.main' }} />
// equivalent to backgroundColor: theme => theme.palette.primary.main
```
Read more on the [Palette page](/system/palette/).
### Positions
The `zIndex` property maps its value to the `theme.zIndex` value:
```jsx
<Box sx={{ zIndex: 'tooltip' }} />
// equivalent to zIndex: theme => theme.zIndex.tooltip
```
Read more on the [Positions page](/system/positions/).
### Shadows
The `boxShadow` property maps its value to the `theme.shadows` value:
```jsx
<Box sx={{ boxShadow: 1 }} />
// equivalent to boxShadow: theme => theme.shadows[1]
```
Read more on the [Shadows page](/system/shadows/).
### Sizing
The sizing properties `width`, `height`, `minHeight`, `maxHeight`, `minWidth`, and `maxWidth` use the following custom transform function for the value:
```js
function transform(value) {
return value <= 1 && value !== 0 ? `${value * 100}%` : value;
}
```
If the value is between (0, 1], it's converted to a percentage.
Otherwise, it is directly set on the CSS property:
```jsx
<Box sx={{ width: 1/2 }} /> // equivalent to width: '50%'
<Box sx={{ width: 20 }} /> // equivalent to width: '20px'
```
Read more on the [Sizing page](/system/sizing/).
### Spacing
The spacing properties `margin`, `padding`, and the corresponding longhand properties multiply the values they receive by the `theme.spacing` value (the default for the value is `8px`):
```jsx
<Box sx={{ margin: 2 }} />
// equivalent to margin: theme => theme.spacing(2)
```
The following aliases are available for the spacing properties:
| Prop | CSS property |
| :--- | :------------------------------ |
| `m` | `margin` |
| `mt` | `margin-top` |
| `mr` | `margin-right` |
| `mb` | `margin-bottom` |
| `ml` | `margin-left` |
| `mx` | `margin-left`, `margin-right` |
| `my` | `margin-top`, `margin-bottom` |
| `p` | `padding` |
| `pt` | `padding-top` |
| `pr` | `padding-right` |
| `pb` | `padding-bottom` |
| `pl` | `padding-left` |
| `px` | `padding-left`, `padding-right` |
| `py` | `padding-top`, `padding-bottom` |
Read more on the [Spacing page](/system/spacing/).
### Typography
The `fontFamily`, `fontSize`, `fontStyle`, `fontWeight` properties map their value to the `theme.typography` value:
```jsx
<Box sx={{ fontWeight: 'fontWeightLight' }} />
// equivalent to fontWeight: theme.typography.fontWeightLight
```
The same can be achieved by omitting the CSS property prefix `fontWeight`:
```jsx
<Box sx={{ fontWeight: 'light' }} />
// equivalent to fontWeight: theme.typography.fontWeightLight
```
There is an additional `typography` prop available, which sets all values defined in the specific `theme.typography` variant:
```jsx
<Box sx={{ typography: 'body1' }} />
// equivalent to { ...theme.typography.body1 }
```
Read more on the [Typography page](/system/typography/).
## Responsive values
All properties associated with the `sx` prop also support responsive values for specific breakpoints and container queries.
Read more on the [Usage page—Responsive values](/system/getting-started/usage/#responsive-values).
## Callback values
Use a callback when you need to get theme values that are objects:
```jsx
<Box
sx={(theme) => ({
...theme.typography.body,
color: theme.palette.primary.main,
})}
/>
```
:::info
Callback as a value has been deprecated.
Please use the callback as the entire value instead.
```diff
- sx={{ height: (theme) => theme.spacing(10) }}
+ sx={(theme) => ({ height: theme.spacing(10) })}
```
<br />
You can migrate the code using our codemod:
```bash
npx @mui/codemod@latest v6.0.0/sx-prop path/to/file-or-folder
```
:::
In TypeScript, to use custom theme properties with the `sx` prop callback, extend the `Theme` type from the `@mui/system` library using [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation):
```tsx
import * as React from 'react';
import Box from '@mui/material/Box';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { orange } from '@mui/material/colors';
declare module '@mui/system' {
interface Theme {
status: {
warning: string;
};
}
}
const theme = createTheme({
status: {
warning: orange[500],
},
});
export default function App() {
return (
<ThemeProvider theme={theme}>
<Box
sx={(theme) => ({
bgcolor: theme.status.warning,
})}
>
Example
</Box>
</ThemeProvider>
);
}
```
## Array values
Array types are useful when you want to partially override some styles in the former index:
```jsx
<Box
sx={[
{
'&:hover': {
color: 'red',
backgroundColor: 'white',
},
},
foo && {
'&:hover': { backgroundColor: 'grey' },
},
bar && {
'&:hover': { backgroundColor: 'yellow' },
},
]}
/>
```
When you hover on this element, `color: red; backgroundColor: white;` is applied.
If `foo: true`, then `color: red; backgroundColor: grey;` is applied when hovering.
If `bar: true`, then `color: red; backgroundColor: yellow;` is applied when hovering regardless of `foo` value, because the higher index of the array has higher specificity.
:::info
Each index can be an object or a callback.
:::
```jsx
<Box
sx={[
{ mr: 2, color: 'red' },
(theme) => ({
'&:hover': {
color: theme.palette.primary.main,
},
}),
]}
/>
```
## Passing the sx prop
If you want to receive the `sx` prop from a custom component and pass it down to another MUI System, we recommend this approach:
{{"demo": "PassingSxProp.js", "bg": true, "defaultCodeOpen": true}}
## Dynamic values
For highly dynamic CSS values, we recommend using inline CSS variables instead of passing an object with varying values to the `sx` prop on each render.
This approach avoids inserting unnecessary `style` tags into the DOM, which prevents potential performance issues when dealing with CSS properties that can hold a wide range of values that change frequently—for example, a color picker with live preview.
:::info
If you're having problems with your Content Security Policy while using inline styles with the `style` attribute, make sure you've enabled the [`style-src-attr` directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/style-src-attr).
Visit the [Content Security Policy guide](/material-ui/guides/content-security-policy/) for configuration details.
:::
{{"demo": "DynamicValues.js", "bg": true}}
## TypeScript usage
A frequent source of confusion with the `sx` prop is TypeScript's [type widening](https://mariusschulz.com/blog/literal-type-widening-in-typescript), which causes this example not to work as expected:
```ts
const style = {
flexDirection: 'column',
};
export default function App() {
return <Button sx={style}>Example</Button>;
}
// Type '{ flexDirection: string; }' is not assignable to type 'SxProps<Theme> | undefined'
// Type '{ flexDirection: string; }' is not assignable to type 'CSSSelectorObject<Theme>'
// Property 'flexDirection' is incompatible with index signature
// Type 'string' is not assignable to type 'SystemStyleObject<Theme>'
```
The problem is that the type of the `flexDirection` prop is inferred as `string`, which is too wide.
To fix this, you can cast the object/function passed to the `sx` prop to `const`:
```ts
const style = {
flexDirection: 'column',
} as const;
export default function App() {
return <Button sx={style}>Example</Button>;
}
```
Alternatively, you can pass the style object directly to the `sx` prop:
```ts
export default function App() {
return <Button sx={{ flexDirection: 'column' }}>Example</Button>;
}
```
## Performance
To learn more about the performance tradeoffs of the `sx` prop, check out [UsagePerformance tradeoffs](/system/getting-started/usage/#performance-tradeoffs).