Pular para o conteúdo

The sx prop

A propriedade `sx` é um atalho para definir o estilo personalizado com acesso ao tema.

The property is a superset of CSS that packages all the style functions that are exposed in @mui/system. Você pode especificar qualquer CSS válido usando este propriedade.

Example

Sessions
98.3 K
+18.77%
vs. last week
import * as React from 'react';
import { Box, ThemeProvider, createTheme } from '@mui/system';

const theme = createTheme({
  palette: {
    background: {
      paper: '#fff',
    },
    text: {
      primary: '#173A5E',
      secondary: '#46505A',
    },
    action: {
      active: '#001E3C',
    },
    success: {
      dark: '#009688',
    },
  },
});

export default function Example() {
  return (
    <ThemeProvider theme={theme}>
      <Box
        sx={{
          bgcolor: 'background.paper',
          boxShadow: 1,
          borderRadius: 2,
          p: 2,
          minWidth: 300,
        }}
      >
        <Box sx={{ color: 'text.secondary' }}>Sessions</Box>
        <Box sx={{ color: 'text.primary', fontSize: 34, fontWeight: 'medium' }}>
          98.3 K
        </Box>
        <Box
          sx={{
            color: 'success.dark',
            display: 'inline',
            fontWeight: 'bold',
            mx: 0.5,
            fontSize: 14,
          }}
        >
          +18.77%
        </Box>
        <Box sx={{ color: 'text.secondary', display: 'inline', fontSize: 14 }}>
          vs. last week
        </Box>
      </Box>
    </ThemeProvider>
  );
}

No exemplo acima, você pode notar que alguns dos valores não são propriedades válidas do CSS. Isso porque as teclas sx são mapeadas para propriedades específicas do tema. Nas seções a seguir, você aprenderá como diferentes propriedades sx são mapeadas para partes específicas do tema.

Theme aware properties

Borders

The border property can receive only a number as a value. It creates a solid black border using the number as the width.

<Box sx={{ border: 1 }} />
// equivalente à border: '1px solid black'

A propriedade borderColor pode receber uma string, que representa o caminho no theme.palette.

<Box sx={{ borderColor: 'primary.main' }} />
// equivalente à borderColor: theme => theme.palette.primary.main

As propriedades borderRadius multiplicam o valor recebido pelo valor theme.shape.borderRadius (o padrão para o valor é 4px).

<Box sx={{ borderRadius: 2 }} />
// equivalente à borderRadius: theme => 2 * theme.shape.borderRadius

Head to the borders page for more details.

Display

A propriedade displayPrint permite que você especifique o valor de display, que será aplicado somente para impressão.

<Box sx={{ displayPrint: 'none' }} /> // equivalent to '@media print': { display: 'none' }

Head to the display page for more details.

Grid

The grid CSS properties gap, rowGap and columnGap multiply the values they receive by the theme.spacing value (the default for the value is 8px).

<Box sx={{ gap: 2 }} />
// equivalent to gap: theme => theme.spacing(2)

Head to the grid page for more details.

Palette

As propriedades color e backgroundColor podem receber uma string, que representa o caminho no theme.palette.

<Box sx={{ color: 'primary.main' }} />
// equivalent to color: theme => theme.palette.primary.main

The backgroundColor property is also available trough its alias bgcolor.

<Box sx={{ bgcolor: 'primary.main' }} />
// equivalent to backgroundColor: theme => theme.palette.primary.main

Head to the palette page for more details.

Positions

The zIndex property maps its value to the theme.zIndex value.

<Box sx={{ zIndex: 'tooltip' }} />
// equivalent to zIndex: theme => theme.zIndex.tooltip

Head to the positions page for more details.

Shadows

The boxShadow property maps its value to the theme.shadows value.

<Box sx={{ boxShadow: 1 }} />
// equivalent to boxShadow: theme => theme.shadows[1]

Head to the shadows page for more details.

Sizing

As propriedades de dimensionamento: with, height, minHeight, maxHeight, minWidth e maxWidth estão usando a seguinte função de transformação personalizada para o valor:

function transform(value) {
  return value <= 1 ? `${value * 100}%` : value;
}

If the value is between [0, 1], it's converted to percent. Otherwise, it is directly set on the CSS property.

<Box sx={{ width: 1/2 }} /> // equivalente a width: '50%'
<Box sx={{ width: 20 }} /> // equivalente a width: '20px'

Head to the sizing page for more details.

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).

<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

Head to the spacing page for more details.

Typography

As propriedades fontFamily, fontSize, fontStyle, fontWeight mapeiam seus valores para o valor de theme.typography.

<Box sx={{ fontWeight: 'fontWeightLight' }} />
//equivalente à fontWeight: theme.typography.fontWeightLight

The same can be achieved by omitting the CSS property prefix fontWeight.

<Box sx={{ fontWeight: 'light' }} />
//equivalente à fontWeight: theme.typography.fontWeightLight

There is additional typography prop available, which sets all values defined in the specific theme.typography variant.

<Box sx={{ typography: 'body1' }} />
// equivalent to { ...theme.typography.body1 }

Head to the typography page for more details.

Responsive values

All properties as part of the sx prop also have a support for defining different values for specific breakpoints. For more details on this, take a look at the Responsive values section.

Callback values

Each property in the sx prop can receive a function callback as a value. This is useful when you want to use the theme for calculating some value.

<Box sx={{ height: (theme) => theme.spacing(10) }} />

sx can also receive a callback when you need to get theme values that are object:

<Box
  sx={(theme) => ({
    ...theme.typography.body,
    color: theme.palette.primary.main,
  })}
/>

Array values

Array type is useful when you want to partially override some styles in the former index:

<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, the color: red; backgroundColor: grey; is applied when hover.

If bar: true, the color: red; backgroundColor: yellow; is applied when hover regardless of foo value, because the higher index of the array has higher specificity.

Note: Each index can be an object or callback

<Box
  sx={[
    { mr: 2, color: 'red' },
    (theme) => ({
      '&:hover': {
        color: theme.palette.primary.main,
      },
    }),
  ]}
/>

Passing sx prop

If you want to receive sx prop from your component and pass it down to MUI's component, we recommend this approach:

  • import * as React from 'react';
    import ListItem from '@mui/material/ListItem';
    import FormLabel from '@mui/material/FormLabel';
    import { SxProps, Theme } from '@mui/material/styles';
    
    interface ListHeaderProps {
      children: React.ReactNode;
      sx?: SxProps<Theme>;
    }
    
    const ListHeader = ({ sx = [], children }: ListHeaderProps) => (
      <ListItem
        sx={[
          {
            width: 'auto',
            textDecoration: 'underline',
          },
          // You cannot spread `sx` directly because `SxProps` (typeof sx) can be an array.
          ...(Array.isArray(sx) ? sx : [sx]),
        ]}
      >
        <FormLabel sx={{ color: 'inherit' }}>{children}</FormLabel>
      </ListItem>
    );
    
    export default function PassingSxProp() {
      return (
        <ListHeader
          sx={(theme) => ({
            color: 'info.main',
            ...theme.typography.overline,
          })}
        >
          Header
        </ListHeader>
      );
    }

    TypeScript usage

    A frequent source of confusion with the sx prop is TypeScript's type widening, which causes this example not to work as expected:

    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:

    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:

    export default function App() {
      return <Button sx={{ flexDirection: 'column' }}>Example</Button>;
    }
    

    fill callback gives theme type as any

    Since sx can be an array type, there is a conflict in type of Array.fill and CSS's fill property when define value as a callback. As a workaround, you can explicitly define the theme like this:

    import { Theme } from '@mui/material/styles';
    
    <Box
      sx={{
        fill: (theme: Theme) => theme.palette.primary.main,
      }}
    />;
    

    Let us know or submit a PR if you have a proper way to fix this issue. 🙏

    Performance

    If you are interested in the performance tradeoff, you can find more details here.