Skip to content

styled()

Utility for creating styled components.

Introduction

All the MUI components are styled with this 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).

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:

  1. It uses MUI's default theme if no theme is available in React context.
  2. It supports the theme's styleOverrides and variants to be applied, based on the name applied in the options (can be skipped).
  3. It adds support for the the sx prop (can be skipped).
  4. It adds by default the shouldForwardProp option (that can be overridden), taking into account all props used internally in the MUI components: ownerState, theme, sx, and as.

API

styled(Component, [options])(styles) => Component

Arguments

  1. Component: The component that will be wrapped.

  2. options (object [optional]):

    • options.shouldForwardProp ((prop: string) => bool [optional]): Indicates whether the prop should be forwarded to the Component.
    • options.label (string [optional]): The suffix of the style sheet. Useful for debugging.
    • options.name (string [optional]): The key used under theme.components for specifying styleOverrides and variants. Also used for generating the label.
    • options.slot (string [optional]): If Root, it automatically applies the theme's variants.
    • options.overridesResolver ((props: object, styles: Record<string, styles>) => styles [optional]): Function that returns styles based on the props and the theme.components[name].styleOverrides object.
    • options.skipVariantsResolver (bool): Disables the automatic resolver for the theme.components[name].variants.
    • options.skipSx (bool [optional]): Disables the sx prop on the component.
    • The other keys are forwarded to the options argument of emotion's styled([Component], [options]).
  3. 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

Styled div
Press Enter to start editing

Using the theme

Styled div with theme
Press Enter to start editing

Custom components

This example demonstrates how you can use the styled API to create custom components, with the same capabilities as the core components:

Primary
Secondary
Press Enter to start editing

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.

browser DevTools showing the rendered component

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 specific features, you can do it like this:

<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">const StyledComponent = styled('div', {}, {
</span><span class="token prefix unchanged"> </span><span class="token line">  name: 'MuiStyled',
</span><span class="token prefix unchanged"> </span><span class="token line">  slot: 'Root',
</span></span><span class="token deleted-sign deleted"><span class="token prefix deleted">-</span><span class="token line">  overridesResolver: (props, styles) => styles.root, // disables theme.components[name].styleOverrides
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  skipVariantsResolver: true, // disables theme.components[name].variants
</span><span class="token prefix inserted">+</span><span class="token line">  skipSx: true, // disables the sx prop
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">});</span></span>

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.

<span class="token keyword">import</span> <span class="token punctuation">{</span> createStyled<span class="token punctuation">,</span> createTheme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/system'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> defaultTheme <span class="token operator">=</span> <span class="token function">createTheme</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token comment">// your custom theme values</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> styled <span class="token operator">=</span> <span class="token function">createStyled</span><span class="token punctuation">(</span><span class="token punctuation">{</span> defaultTheme <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> styled<span class="token punctuation">;</span>

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 of the MUI components.

Therefore, you will notice the following differences:

sx provides more shortcuts than styled

With styled:

<span class="token keyword">const</span> MyStyledButton <span class="token operator">=</span> <span class="token function">styled</span><span class="token punctuation">(</span><span class="token string">'button'</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">mx</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// ❌ don't use this! This shortcut is only provided by the `sx` prop</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

With sx:

<span class="token keyword">import</span> Button <span class="token keyword">from</span> <span class="token string">'@mui/material/Button'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">MyStyledButton</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Button</span></span>
    <span class="token attr-name">sx</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>
      <span class="token literal-property property">mx</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// ✔️ this shortcut is specific to the `sx` prop,</span>
    <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
  <span class="token punctuation">></span></span>
    <span class="token punctuation">{</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Button</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

The style definition varies slightly

With styled:

<span class="token keyword">const</span> MyStyledButton <span class="token operator">=</span> <span class="token function">styled</span><span class="token punctuation">(</span><span class="token string">'button'</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">padding</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// means "1px", NOT "theme.spacing(1)"</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

With sx:

<span class="token keyword">import</span> Button <span class="token keyword">from</span> <span class="token string">'@mui/material/Button'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">MyStyledButton</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Button</span></span>
    <span class="token attr-name">sx</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>
      <span class="token literal-property property">padding</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// means "theme.spacing(1)", NOT "1px"</span>
    <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
  <span class="token punctuation">></span></span>
    <span class="token punctuation">{</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Button</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

Patterns for how to use props differ

With styled:

<span class="token keyword">const</span> MyStyledButton <span class="token operator">=</span> <span class="token function">styled</span><span class="token punctuation">(</span><span class="token string">'button'</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">backgroundColor</span><span class="token operator">:</span> props<span class="token punctuation">.</span>myBackgroundColor<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

With sx:

<span class="token keyword">import</span> Button <span class="token keyword">from</span> <span class="token string">'@mui/material/Button'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">MyStyledButton</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Button</span></span> <span class="token attr-name">sx</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">backgroundColor</span><span class="token operator">:</span> props<span class="token punctuation">.</span>myCustomColor <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Button</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

Parameter when using function are different for each field

With styled (not recommended):

<span class="token comment">// You may find this syntax in the wild, but for code readability</span>
<span class="token comment">// we recommend using only one top-level function</span>
<span class="token keyword">const</span> MyStyledButtonPropsPerField <span class="token operator">=</span> <span class="token function">styled</span><span class="token punctuation">(</span><span class="token string">'button'</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token function-variable function">backgroundColor</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> props<span class="token punctuation">.</span>myBackgroundColor<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

With sx:

<span class="token keyword">import</span> Button <span class="token keyword">from</span> <span class="token string">'@mui/material/Button'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> lighten <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'polished'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">MyStyledButton</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Button</span></span>
    <span class="token attr-name">sx</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token function-variable function">backgroundColor</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">theme</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">lighten</span><span class="token punctuation">(</span><span class="token number">0.2</span><span class="token punctuation">,</span> theme<span class="token punctuation">.</span>palette<span class="token punctuation">.</span>primary<span class="token punctuation">.</span>main<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
  <span class="token punctuation">></span></span>
    <span class="token punctuation">{</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Button</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Note: for direct theme access without modification, you can also use a shortcut by providing the key as a string</span>
<span class="token keyword">const</span> <span class="token function-variable function">MyStyledButton</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Button</span></span> <span class="token attr-name">sx</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">backgroundColor</span><span class="token operator">:</span> <span class="token string">'primary.main'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Button</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

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:

Styled div with theme
Press Enter to start editing

The overhead added by using the unstable_sx utility is the same as if you were to use the sx prop on the component.

Note: You can use unstable_sx outside of the styled() utility, too; e.g., for defining variants in your custom theme.

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.

<span class="token keyword">import</span> styled <span class="token keyword">from</span> <span class="token string">'@emotion/styled'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> Child <span class="token operator">=</span> styled<span class="token punctuation">.</span>div<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
  color: red;
</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

<span class="token keyword">const</span> Parent <span class="token operator">=</span> styled<span class="token punctuation">.</span>div<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
  </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>Child<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> {
    color: green;
  }
</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

<span class="token function">render</span><span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Parent</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Child</span></span><span class="token punctuation">></span></span>Green because <span class="token constant">I</span> am inside a Parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Child</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Parent</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Child</span></span><span class="token punctuation">></span></span>Red because <span class="token constant">I</span> am not inside a Parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Child</span></span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

With MUI'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.

<span class="token function">npm</span> <span class="token function">install</span> @emotion/babel-plugin

Then, configure the plugin to know about the MUI version of the styled() utility:

babel.config.js

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token operator">...</span>
  <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span>
    <span class="token punctuation">[</span>
      <span class="token string">"@emotion"</span><span class="token punctuation">,</span>
      <span class="token punctuation">{</span>
        <span class="token literal-property property">importMap</span><span class="token operator">:</span> <span class="token punctuation">{</span>
          <span class="token string-property property">"@mui/system"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
            <span class="token literal-property property">styled</span><span class="token operator">:</span> <span class="token punctuation">{</span>
              <span class="token literal-property property">canonicalImport</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"@emotion/styled"</span><span class="token punctuation">,</span> <span class="token string">"default"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
              <span class="token literal-property property">styledBaseImport</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"@mui/system"</span><span class="token punctuation">,</span> <span class="token string">"styled"</span><span class="token punctuation">]</span>
            <span class="token punctuation">}</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
          <span class="token string-property property">"@mui/material/styles"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
            <span class="token literal-property property">styled</span><span class="token operator">:</span> <span class="token punctuation">{</span>
              <span class="token literal-property property">canonicalImport</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"@emotion/styled"</span><span class="token punctuation">,</span> <span class="token string">"default"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
              <span class="token literal-property property">styledBaseImport</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"@mui/material/styles"</span><span class="token punctuation">,</span> <span class="token string">"styled"</span><span class="token punctuation">]</span>
            <span class="token punctuation">}</span>
          <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
  <span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

Now you should be able to use components as your selectors!