styled()
Utility for creating styled components.
Introduction
All Material UI components are styled with the styled() utility.
This utility is built on top of the styled() module of @mui/styled-engine and provides additional features.
Import path
You can use the utility coming from the @mui/system package, or if you are using @mui/material, you can import it from @mui/material/styles.
The difference is in the default theme that is used (if no theme is available in the React context).
import { styled } from '@mui/system';
// If you are using @mui/material
import { styled } from '@mui/material/styles';
What problems does it solve?
The utility can be used as a replacement for emotion's or styled-components' styled() utility. It aims to solve the same problem, but also provides the following benefits:
- It uses a default
themeif no theme is available in React context. - It supports the theme's
styleOverridesandvariantsto be applied, based on thenameapplied in the options (can be skipped). - It adds support for the the
sxprop (can be skipped). - It adds by default the
shouldForwardPropoption (that can be overridden), taking into account:ownerState,theme,sx, andas.
API
styled(Component, [options])(styles) => Component
Arguments
Component: The component that will be wrapped.options(object [optional]):options.shouldForwardProp((prop: string) => bool[optional]): Indicates whether thepropshould be forwarded to theComponent.options.label(string [optional]): The suffix of the style sheet. Useful for debugging.options.name(string [optional]): The key used undertheme.componentsfor specifyingstyleOverridesandvariants. Also used for generating thelabel.options.slot(string [optional]): IfRoot, it automatically applies the theme'svariants.options.overridesResolver((props: object, styles: Record<string, styles>) => styles [optional]): Function that returns styles based on the props and thetheme.components[name].styleOverridesobject.options.skipVariantsResolver(bool): Disables the automatic resolver for thetheme.components[name].variants.options.skipSx(bool [optional]): Disables thesxprop on the component.- The other keys are forwarded to the
optionsargument of emotion'sstyled([Component], [options]).
styles(object |({ ...props, theme }) => object[optional]): A styles object or a function returning a styles object. The function receives the theme and component's props in an object which is its single argument.
Returns
Component: The new component created.
Basic usage
Custom components
This example demonstrates how you can use the styled API to create custom components, with the same capabilities as the core components:
If you inspect this element with the browser DevTools in development mode, you will notice that the class of the component now ends with the MyThemeComponent-root, which comes from the name and slot options that were provided.
In addition to this, the color, sx, and variant props are not propagated to the generated div element.
Removing features
If you would like to remove some of the MUI System specific features, you can do it like this:
const StyledComponent = styled('div', {}, {
name: 'MuiStyled',
slot: 'Root',
- overridesResolver: (props, styles) => styles.root, // disables theme.components[name].styleOverrides
+ skipVariantsResolver: true, // disables theme.components[name].variants
+ skipSx: true, // disables the sx prop
});
Create custom styled() utility
If you want to have a different default theme for the styled() utility, you can create your own version of it, using the createStyled() utility.
import { createStyled, createTheme } from '@mui/system';
const defaultTheme = createTheme({
// your custom theme values
});
const styled = createStyled({ defaultTheme });
export default styled;
Difference with the sx prop
The styled function is an extension of the styled utility provided by the underlying style library used – either Emotion or styled-components.
It is guaranteed that it will produce the same output as the styled function coming from the style library for the same input.
The sx prop, on the other hand, is a new way of styling your components, focused on fast customization. styled is a function, while sx is a prop available on the components created with styled.
Therefore, you will notice the following differences:
sx provides more shortcuts than styled
With styled:
const MyStyledButton = styled('button')({
mx: 1, // ❌ don't use this! This shortcut is only provided by the `sx` prop
});
With sx:
import Button from '@mui/material/Button';
const MyStyledButton = (props) => (
<Button
sx={{
mx: 1, // ✔️ this shortcut is specific to the `sx` prop,
}}
>
{props.children}
</Button>
);
The style definition varies slightly
With styled:
const MyStyledButton = styled('button')({
padding: 1, // means "1px", NOT "theme.spacing(1)"
});
With sx:
import Button from '@mui/material/Button';
const MyStyledButton = (props) => (
<Button
sx={{
padding: 1, // means "theme.spacing(1)", NOT "1px"
}}
>
{props.children}
</Button>
);
Patterns for how to use props differ
With styled:
const MyStyledButton = styled('button')((props) => ({
backgroundColor: props.myBackgroundColor,
}));
With sx:
import Button from '@mui/material/Button';
const MyStyledButton = (props) => (
<Button sx={{ backgroundColor: props.myCustomColor }}>{props.children}</Button>
);
Parameter when using function are different for each field
With styled (not recommended):
// You may find this syntax in the wild, but for code readability
// we recommend using only one top-level function
const MyStyledButtonPropsPerField = styled('button')({
backgroundColor: (props) => props.myBackgroundColor,
});
With sx:
import Button from '@mui/material/Button';
import { lighten } from 'polished';
const MyStyledButton = (props) => (
<Button
sx={{ backgroundColor: (theme) => lighten(0.2, theme.palette.primary.main) }}
>
{props.children}
</Button>
);
// Note: for direct theme access without modification, you can also use a shortcut by providing the key as a string
const MyStyledButton = (props) => (
<Button sx={{ backgroundColor: 'primary.main' }}>{props.children}</Button>
);
How can I use the sx syntax with the styled() utility?
If you prefer the sx syntax and want to use it in both the sx prop and the styled() utility, you can use the unstable_sx utility from the theme:
The overhead added by using the unstable_sx utility is the same as if you were to use the sx prop on the component.
How to use components selector API
If you've ever used the styled() API of either emotion or styled-components, you should have been able to use components as selectors.
import styled from '@emotion/styled';
const Child = styled.div`
color: red;
`;
const Parent = styled.div`
${Child} {
color: green;
}
`;
render(
<div>
<Parent>
<Child>Green because I am inside a Parent</Child>
</Parent>
<Child>Red because I am not inside a Parent</Child>
</div>,
);
With MUI System's styled() utility, you can use components as selectors, too. When using @mui/styled-engine-sc (styled-components), nothing needs to be done. When using @mui/styled-engine (emotion), the default engine, there are a few steps you should perform:
First, you should install @emotion/babel-plugin.
npm install @emotion/babel-plugin
Then, configure the plugin to know about the Material UI version of the styled() utility:
babel.config.js
module.exports = {
...
plugins: [
[
"@emotion",
{
importMap: {
"@mui/system": {
styled: {
canonicalImport: ["@emotion/styled", "default"],
styledBaseImport: ["@mui/system", "styled"]
}
},
"@mui/material": {
styled: {
canonicalImport: ["@emotion/styled", "default"],
styledBaseImport: ["@mui/material", "styled"]
}
},
"@mui/material/styles": {
styled: {
canonicalImport: ["@emotion/styled", "default"],
styledBaseImport: ["@mui/material/styles", "styled"]
}
}
}
}
]
]
};
Now you should be able to use components as your selectors!