Skip to content

styled()

Utility for creating styled components.

Introduction

All the Material-UI components are styled with this styled() utility. This utility is built on top of the styled() module of @material-ui/styled-engine and provides additional features.

Import path

You can use the utility coming from the @material-ui/system package, or if you are using @material-ui/core, you can import it from @material-ui/core/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 Material-UI'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 shouldForwardProp option that is taking into account all props used internally in the Material-UI components (can be overridden).

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 styleOverrides & 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]).

Returns

Component: The new component created.

Basic usage

Styled div
import * as React from 'react';
import { styled } from '@material-ui/system';

const MyComponent = styled('div')({
  color: 'darkslategray',
  backgroundColor: 'aliceblue',
  padding: 8,
  borderRadius: 4,
});

export default function BasicUsage() {
  return <MyComponent>Styled div</MyComponent>;
}

Using the theme

Styled div with theme
import * as React from 'react';
import { styled, createTheme, ThemeProvider } from '@material-ui/system';

const customTheme = createTheme({
  palette: {
    primary: {
      main: '#1976d2',
      contrastText: 'white',
    },
  },
});

const MyThemeComponent = styled('div')(({ theme }) => ({
  color: theme.palette.primary.contrastText,
  backgroundColor: theme.palette.primary.main,
  padding: theme.spacing(1),
  borderRadius: theme.shape.borderRadius,
}));

export default function ThemeUsage() {
  return (
    <ThemeProvider theme={customTheme}>
      <MyThemeComponent>Styled div with theme</MyThemeComponent>
    </ThemeProvider>
  );
}

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
import * as React from 'react';
import { styled, createTheme, ThemeProvider } from '@material-ui/system';

const customTheme = createTheme({
  components: {
    MyThemeComponent: {
      styleOverrides: {
        root: {
          color: 'darkslategray',
        },
        primary: {
          color: 'darkblue',
        },
        secondary: {
          color: 'darkred',
          backgroundColor: 'pink',
        },
      },
      variants: [
        {
          props: { variant: 'dashed', color: 'primary' },
          style: {
            border: '1px dashed darkblue',
          },
        },
        {
          props: { variant: 'dashed', color: 'secondary' },
          style: {
            border: '1px dashed darkred',
          },
        },
      ],
    },
  },
});

const MyThemeComponent = styled('div', {
  // Configure which props should be forwarded on DOM
  shouldForwardProp: (prop) => prop !== 'color' && prop !== 'variant',
  name: 'MyThemeComponent',
  slot: 'Root',
  // We are specifying here how the styleOverrides are being applied based on props
  overridesResolver: (props, styles) => ({
    ...styles.root,
    ...(props.color === 'primary' && styles.primary),
    ...(props.color === 'secondary' && styles.secondary),
  }),
})(({ theme }) => ({
  backgroundColor: 'aliceblue',
  padding: theme.spacing(1),
}));

export default function UsingOptions() {
  return (
    <ThemeProvider theme={customTheme}>
      <MyThemeComponent sx={{ m: 1 }} color="primary" variant="dashed">
        Primary
      </MyThemeComponent>
      <MyThemeComponent sx={{ m: 1 }} color="secondary">
        Secondary
      </MyThemeComponent>
    </ThemeProvider>
  );
}

If you inspect this element with the browser DevTools, you will notice that the class of the component now ends with the MyTestComponent-root, which comes from the name and slot options that were provided. In addition to this, the color and variant props are not propagated to the generated div element.

Developer tools showing the rendered component

Removing features

If you would like to remove some of the Material-UI 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 '@material-ui/system';

const defaultTheme = createTheme({
  // your custom theme values
});

const styled = createStyled({ defaultTheme });

export default styled;