The Essential Guide to Material-UI Styled Components (MUI v5)

Material-UI version 5 made the styled API one of two primary component styling APIs. Unfortunately, the complexity of styled componenents in Material-UI increased exponentially. For example, now developers must decide:

  • Should I use the styled API that wraps emotion?
  • Should I use the styled API that wraps styled-components?
  • Should I use styled components directly in Material-UI?
  • Should I import @mui/styled-engine, @mui/styled-engine-sc, @mui/system, or @mui/material/styles?
  • Which of the seven new options should I pass as options to styled? For reference, the typing is styled(Component, [options])(styles) => Component.

My goal with this guide is to aid the 90% of developers who want a simple setup for using Styled Components with MUI. I will include links to resources that go beyond the scope of the setup demonstrated in this article.

If you are debating using styled components vs the sx prop, the short answer is that styled components are meant to be created and exported for reuse all throughout your app. The sx prop is a quicker styling method that is intended to replace local classes and inline styling. In reality, they can both accomplish the same goals and in my opinion it comes down to developer preference.

There is a Code Sandbox with full React code in the Resources section.

The Essential Guide to Material-UI Styled Components

Which Styled Component Import and API to Use?

Most developers should use the MUI-recommended approach, which is the styled() API that wraps emotion.

  • This avoids having to configure package.json dependencies and tsconfig.json.
  • The styling syntax is identical and the MUI documentation directs users to the same guide for both emotion and styled-components.

Here is the simplest import for the styled() emotion wrapper: import { styled } from "@mui/system";

If you do want to switch completely to styled-components instead of emotion, here’s the MUI guide. Your actual styling code will be identical.

Material-UI Styled Paper Component Example

I created a simple styled Paper component that wraps a button.

MUI Paper Styled Component
MUI Paper Styled Component

Here’s the code, I will discuss it below. Also notice StyledPaper and StyledPaper2 show the two different valid syntaxes for Styled Components in Material-UI.

import * as React from "react";
import Paper from "@mui/material/Paper";
import Button from "@mui/material/Button";
import { styled } from "@mui/system";

//notice the syntax
const StyledPaper = styled(Paper, {
  name: "StyledPaper",
  slot: "Wrapper"
})({
  color: "#6B8068",
  //backgroundImage: `url("https://picsum.photos/200/300")`,
  backgroundColor: "silver",
  margin: "auto",
  borderRadius: 2,
  height: 300,
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  ".MuiButton-root": { color: "#FF0000" }
});

//Tick mark syntax also works
const StyledPaper2 = styled(Paper, {
  name: "StyledPaper2",
  slot: "Wrapper"
})`
  color: red;
  height: 300px;
  background-image: url("https://picsum.photos/200/300");
`;

export default function StyledPaperExample() {
  return (
    <StyledPaper>
      <Button variant="outlined">Text</Button>
    </StyledPaper>
    //<StyledPaper2>
    // Text
    //</StyledPaper2>
  );
}

The StyledPaper component uses JavaScript syntax that looks like JSS. The StyledPaper2 component uses CSS syntax wrapped in ticks.

This Styled Component had several interesting features:

  • background color
  • background image
  • flex
  • nested selector

Take note of the slight difference in syntax between the two methods. For example, the traditional styled component syntax for background image is shown in StyledPaper2: background-image. But it also works to pass backgroundImage as a field name in an object using JavaScript syntax.

Nested selectors are as simple in the MUI styled API as they are in the sx API. Simply pass the targeted selector and the value: ".MuiButton-root": { color: "#FF0000" }.

An important feature of the styled() API is that it allows direct access to the theme. I could have set color with the following code: color: ${theme.palette.primary.main};. This is available in both the JSS and CSS syntaxes above. To access the theme, pass the theme to the styled component.

Styled Component Options

If you want to read about each option, see the docs here. If not, here’s a quick overview:

  • Two of the props disable other ‘normal’ MUI component features (sx prop and the ability to create variants)
  • Three of the options are used for labeling or naming your component in the DOM or style sheet.
  • The remaining two options deal with forwarding props to the underlying component

I expect most devs won’t need to pass any options. However, the shouldForwardProp option may be useful when you need to control exactly how passed props interact with the underlying component.

In my example above, I used name and slot component to change the CSS class name generated for my component. It was pretty cool!

Styled Components DOM CSS name
Styled Components DOM CSS name

Resources

Code Sandbox Link

Material-UI Styled Documentation

Here’s how to add hover to a Material-UI Button using styled-components.

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.