Skip to content

Advanced (LEGACY)

This section covers more advanced usage of @mui/styles.

⚠️ @mui/styles is the legacy styling solution for Material UI. It depends on JSS as a styling solution, which is not used in the @mui/material anymore, deprecated in v5. If you don't want to have both Emotion & JSS in your bundle, please refer to the @mui/system documentation which is the recommended alternative.

⚠️ @mui/styles is not compatible with React.StrictMode or React 18.

Theming

Add a ThemeProvider to the top level of your app to pass a theme down the React component tree. Then, you can access the theme object in style functions.

This example creates a theme object for custom-built components. If you intend to use some of Material UI's components you need to provide a richer theme structure using the createTheme() method. Head to the theming section to learn how to build your custom Material UI theme.

<span class="token keyword">import</span> <span class="token punctuation">{</span> ThemeProvider <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> DeepChild <span class="token keyword">from</span> <span class="token string">'./my_components/DeepChild'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> theme <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">background</span><span class="token operator">:</span> <span class="token string">'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)'</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">Theming</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</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">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>theme<span class="token punctuation">}</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">DeepChild</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">ThemeProvider</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
Press Enter to start editing

Accessing the theme in a component

You might need to access the theme variables inside your React components.

useTheme hook

For use in function components:

<span class="token keyword">import</span> <span class="token punctuation">{</span> useTheme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">DeepChild</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> theme <span class="token operator">=</span> <span class="token function">useTheme</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">spacing </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>theme<span class="token punctuation">.</span>spacing<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
spacing 8px
Press Enter to start editing

withTheme HOC

For use in class or function components:

<span class="token keyword">import</span> <span class="token punctuation">{</span> withTheme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">DeepChildRaw</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">spacing </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>props<span class="token punctuation">.</span>theme<span class="token punctuation">.</span>spacing<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> DeepChild <span class="token operator">=</span> <span class="token function">withTheme</span><span class="token punctuation">(</span>DeepChildRaw<span class="token punctuation">)</span><span class="token punctuation">;</span>
spacing 8px

Theme nesting

You can nest multiple theme providers. This can be really useful when dealing with different areas of your application that have distinct appearance from each other.

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>outerTheme<span class="token punctuation">}</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">Child1</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">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>innerTheme<span class="token punctuation">}</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">Child2</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">ThemeProvider</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">ThemeProvider</span></span><span class="token punctuation">></span></span>


The inner theme will override the outer theme. You can extend the outer theme by providing a function:

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ThemeProvider</span></span> <span class="token attr-name">theme</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> <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">Child1</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">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token parameter">outerTheme</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">darkMode</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token operator">...</span>outerTheme <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 tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Child2</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">ThemeProvider</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">ThemeProvider</span></span><span class="token punctuation">></span></span>

Overriding styles - classes prop

The makeStyles (hook generator) and withStyles (HOC) APIs allow the creation of multiple style rules per style sheet. Each style rule has its own class name. The class names are provided to the component with the classes variable. This is particularly useful when styling nested elements in a component.

<span class="token comment">// A style sheet</span>
<span class="token keyword">const</span> useStyles <span class="token operator">=</span> <span class="token function">makeStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// a style rule</span>
  <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// a nested style rule</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">Nested</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> classes <span class="token operator">=</span> <span class="token function">useStyles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">.</span>root<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
      <span class="token punctuation">{</span><span class="token comment">/* 'jss1' */</span><span class="token punctuation">}</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">.</span>label<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* 'jss2' nested */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">Parent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Nested</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

However, the class names are often non-deterministic. How can a parent component override the style of a nested element?

withStyles

This is the simplest case. The wrapped component accepts a classes prop, it simply merges the class names provided with the style sheet.

<span class="token keyword">const</span> Nested <span class="token operator">=</span> <span class="token function">withStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// a style rule</span>
  <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// a nested style rule</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> classes <span class="token punctuation">}</span></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>button</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">.</span>root<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">.</span>label<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* 'jss2 my-label' Nested*/</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">Parent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Nested</span></span> <span class="token attr-name">classes</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">label</span><span class="token operator">:</span> <span class="token string">'my-label'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

makeStyles

The hook API requires a bit more work. You have to forward the parent props to the hook as a first argument.

<span class="token keyword">const</span> useStyles <span class="token operator">=</span> <span class="token function">makeStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// a style rule</span>
  <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// a nested style rule</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">Nested</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> classes <span class="token operator">=</span> <span class="token function">useStyles</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">.</span>root<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">.</span>label<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token comment">/* 'jss2 my-label' nested */</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">Parent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Nested</span></span> <span class="token attr-name">classes</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">label</span><span class="token operator">:</span> <span class="token string">'my-label'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

JSS plugins

JSS uses plugins to extend its core, allowing you to cherry-pick the features you need, and only pay the performance overhead for what you are using.

Not all the plugins are available in Material UI by default. The following (which is a subset of jss-preset-default) are included:

Of course, you are free to use additional plugins. Here is an example with the jss-rtl plugin.

<span class="token keyword">import</span> <span class="token punctuation">{</span> create <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'jss'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> StylesProvider<span class="token punctuation">,</span> jssPreset <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> rtl <span class="token keyword">from</span> <span class="token string">'jss-rtl'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> jss <span class="token operator">=</span> <span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token operator">...</span><span class="token function">jssPreset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>plugins<span class="token punctuation">,</span> <span class="token function">rtl</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 keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">StylesProvider</span></span> <span class="token attr-name">jss</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>jss<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token operator">...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">StylesProvider</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

String templates

If you prefer CSS syntax over JSS, you can use the jss-plugin-template plugin.

<span class="token keyword">const</span> useStyles <span class="token operator">=</span> <span class="token function">makeStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
    background: linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%);
    border-radius: 3px;
    font-size: 16px;
    border: 0;
    color: white;
    height: 48px;
    padding: 0 30px;
    box-shadow: 0 3px 5px 2px rgba(255, 105, 135, 0.3);
  </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

Note that this doesn't support selectors, or nested rules.

CSS injection order

It's really important to understand how the CSS specificity is calculated by the browser, as it's one of the key elements to know when overriding styles. You are encouraged to read this MDN paragraph: How is specificity calculated?

By default, the style tags are injected last in the <head> element of the page. They gain more specificity than any other style tags on your page e.g. CSS modules, styled components.

injectFirst

The StylesProvider component has an injectFirst prop to inject the style tags first in the head (less priority):

<span class="token keyword">import</span> <span class="token punctuation">{</span> StylesProvider <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</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">StylesProvider</span></span> <span class="token attr-name">injectFirst</span><span class="token punctuation">></span></span>
  <span class="token punctuation">{</span><span class="token comment">/* Your component tree.
      Styled components can override Material UI's styles. */</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">StylesProvider</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>

makeStyles / withStyles / styled

The injection of style tags happens in the same order as the makeStyles / withStyles / styled invocations. For instance the color red wins in this case:

<span class="token keyword">import</span> clsx <span class="token keyword">from</span> <span class="token string">'clsx'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> makeStyles <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> useStylesBase <span class="token operator">=</span> <span class="token function">makeStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">'blue'</span><span class="token punctuation">,</span> <span class="token comment">// 🔵</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 keyword">const</span> useStyles <span class="token operator">=</span> <span class="token function">makeStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">'red'</span><span class="token punctuation">,</span> <span class="token comment">// 🔴</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 keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">MyComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// Order doesn't matter</span>
  <span class="token keyword">const</span> classes <span class="token operator">=</span> <span class="token function">useStyles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> classesBase <span class="token operator">=</span> <span class="token function">useStylesBase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// Order doesn't matter</span>
  <span class="token keyword">const</span> className <span class="token operator">=</span> <span class="token function">clsx</span><span class="token punctuation">(</span>classes<span class="token punctuation">.</span>root<span class="token punctuation">,</span> classesBase<span class="token punctuation">.</span>root<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// color: red 🔴 wins.</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>className<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

The hook call order and the class name concatenation order don't matter.

insertionPoint

JSS provides a mechanism to control this situation. By adding an insertionPoint within the HTML you can control the order that the CSS rules are applied to your components.

HTML comment

The simplest approach is to add an HTML comment to the <head> that determines where JSS will inject the styles:

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
  <span class="token comment">&lt;!-- jss-insertion-point --></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>...<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> create <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'jss'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> StylesProvider<span class="token punctuation">,</span> jssPreset <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> jss <span class="token operator">=</span> <span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token operator">...</span><span class="token function">jssPreset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token comment">// Define a custom insertion point that JSS will look for when injecting the styles into the DOM.</span>
  <span class="token literal-property property">insertionPoint</span><span class="token operator">:</span> <span class="token string">'jss-insertion-point'</span><span class="token punctuation">,</span>
<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> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">StylesProvider</span></span> <span class="token attr-name">jss</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>jss<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token operator">...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">StylesProvider</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Other HTML elements

Create React App strips HTML comments when creating the production build. To get around this issue, you can provide a DOM element (other than a comment) as the JSS insertion point, for example, a <noscript> element:

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>noscript</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>jss-insertion-point<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>...<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> create <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'jss'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> StylesProvider<span class="token punctuation">,</span> jssPreset <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> jss <span class="token operator">=</span> <span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token operator">...</span><span class="token function">jssPreset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token comment">// Define a custom insertion point that JSS will look for when injecting the styles into the DOM.</span>
  <span class="token literal-property property">insertionPoint</span><span class="token operator">:</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'jss-insertion-point'</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 keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">StylesProvider</span></span> <span class="token attr-name">jss</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>jss<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token operator">...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">StylesProvider</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

JS createComment

codesandbox.io prevents access to the <head> element. To get around this issue, you can use the JavaScript document.createComment() API:

<span class="token keyword">import</span> <span class="token punctuation">{</span> create <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'jss'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> StylesProvider<span class="token punctuation">,</span> jssPreset <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> styleNode <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createComment</span><span class="token punctuation">(</span><span class="token string">'jss-insertion-point'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">insertBefore</span><span class="token punctuation">(</span>styleNode<span class="token punctuation">,</span> document<span class="token punctuation">.</span>head<span class="token punctuation">.</span>firstChild<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> jss <span class="token operator">=</span> <span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token operator">...</span><span class="token function">jssPreset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token comment">// Define a custom insertion point that JSS will look for when injecting the styles into the DOM.</span>
  <span class="token literal-property property">insertionPoint</span><span class="token operator">:</span> <span class="token string">'jss-insertion-point'</span><span class="token punctuation">,</span>
<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> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">StylesProvider</span></span> <span class="token attr-name">jss</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>jss<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token operator">...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">StylesProvider</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Server-side rendering

This example returns a string of HTML and inlines the critical CSS required, right before it's used:

<span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> ReactDOMServer <span class="token keyword">from</span> <span class="token string">'react-dom/server'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> ServerStyleSheets <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> sheets <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ServerStyleSheets</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">const</span> html <span class="token operator">=</span> ReactDOMServer<span class="token punctuation">.</span><span class="token function">renderToString</span><span class="token punctuation">(</span>sheets<span class="token punctuation">.</span><span class="token function">collect</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">App</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> css <span class="token operator">=</span> sheets<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
&lt;!DOCTYPE html>
&lt;html>
  &lt;head>
    &lt;style id="jss-server-side"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>css<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/style>
  &lt;/head>
  &lt;body>
    &lt;div id="root"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>html<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/div>
  &lt;/body>
&lt;/html>
  </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

You can follow the server side guide for a more detailed example, or read the ServerStyleSheets API documentation.

CSS prefixing

Be aware that some CSS features require an additional postprocessing step that adds vendor-specific prefixes. These prefixes are automatically added to the client thanks to jss-plugin-vendor-prefixer.

The CSS served on this documentation is processed with autoprefixer. You can use the documentation implementation as inspiration. Be aware that it has an implication with the performance of the page. It's a must-do for static pages, but it needs to be put in balance with not doing anything when rendering dynamic pages.

Gatsby

There is an official Gatsby plugin that enables server-side rendering for @mui/styles. Refer to the plugin's page for setup and usage instructions.

Refer to this example Gatsby project for an usage example.

Next.js

You need to have a custom pages/_document.js, then copy this logic to inject the server-side rendered styles into the <head> element.

Refer to this example project for an up-to-date usage example.

Class names

The class names are generated by the class name generator.

Default

By default, the class names generated by @mui/styles are non-deterministic; you can't rely on them to stay the same. Let's take the following style as an example:

<span class="token keyword">const</span> useStyles <span class="token operator">=</span> <span class="token function">makeStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">opacity</span><span class="token operator">:</span> <span class="token number">1</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>

This will generate a class name such as makeStyles-root-123.

You have to use the classes prop of a component to override the styles. The non-deterministic nature of the class names enables style isolation.

  • In development, the class name is: .makeStyles-root-123, following this logic:
<span class="token keyword">const</span> sheetName <span class="token operator">=</span> <span class="token string">'makeStyles'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> ruleName <span class="token operator">=</span> <span class="token string">'root'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> identifier <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> className <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>sheetName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>ruleName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>identifier<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
  • In production, the class name is: .jss123, following this logic:
<span class="token keyword">const</span> productionPrefix <span class="token operator">=</span> <span class="token string">'jss'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> identifier <span class="token operator">=</span> <span class="token number">123</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> className <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>productionPrefix<span class="token interpolation-punctuation punctuation">}</span></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>identifier<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>

However, when the following conditions are met, the class names are deterministic:

  • Only one theme provider is used (No theme nesting)
  • The style sheet has a name that starts with Mui (all Material UI components).
  • The disableGlobal option of the class name generator is false (the default).

Global CSS

jss-plugin-global

The jss-plugin-global plugin is installed in the default preset. You can use it to define global class names.

Press Enter to start editing

Hybrid

You can also combine JSS generated class names with global ones.

Press Enter to start editing

CSS prefixes

JSS uses feature detection to apply the correct prefixes. Don't be surprised if you can't see a specific prefix in the latest version of Chrome. Your browser probably doesn't need it.

TypeScript usage

Using withStyles in TypeScript can be a little tricky, but there are some utilities to make the experience as painless as possible.

Using createStyles to defeat type widening

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

<span class="token keyword">const</span> styles <span class="token operator">=</span> <span class="token punctuation">{</span>
  root<span class="token operator">:</span> <span class="token punctuation">{</span>
    display<span class="token operator">:</span> <span class="token string">'flex'</span><span class="token punctuation">,</span>
    flexDirection<span class="token operator">:</span> <span class="token string">'column'</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 function">withStyles</span><span class="token punctuation">(</span>styles<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//         ^^^^^^</span>
<span class="token comment">//         Types of property 'flexDirection' are incompatible.</span>
<span class="token comment">//           Type 'string' is not assignable to type '"-moz-initial" | "inherit" | "initial" | "revert" | "unset" | "column" | "column-reverse" | "row"...'.</span>

The problem is that the type of the flexDirection prop is inferred as string, which is too wide. To fix this, you can pass the styles object directly to withStyles:

<span class="token function">withStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  root<span class="token operator">:</span> <span class="token punctuation">{</span>
    display<span class="token operator">:</span> <span class="token string">'flex'</span><span class="token punctuation">,</span>
    flexDirection<span class="token operator">:</span> <span class="token string">'column'</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>

However type widening rears its ugly head once more if you try to make the styles depend on the theme:

<span class="token function">withStyles</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">{</span> palette<span class="token punctuation">,</span> spacing <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  root<span class="token operator">:</span> <span class="token punctuation">{</span>
    display<span class="token operator">:</span> <span class="token string">'flex'</span><span class="token punctuation">,</span>
    flexDirection<span class="token operator">:</span> <span class="token string">'column'</span><span class="token punctuation">,</span>
    padding<span class="token operator">:</span> spacing<span class="token punctuation">.</span>unit<span class="token punctuation">,</span>
    backgroundColor<span class="token operator">:</span> palette<span class="token punctuation">.</span>background<span class="token punctuation">.</span>default<span class="token punctuation">,</span>
    color<span class="token operator">:</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 class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

This is because TypeScript widens the return types of function expressions.

Because of this, using the createStyles helper function to construct your style rules object is recommended:

<span class="token comment">// Non-dependent styles</span>
<span class="token keyword">const</span> styles <span class="token operator">=</span> <span class="token function">createStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  root<span class="token operator">:</span> <span class="token punctuation">{</span>
    display<span class="token operator">:</span> <span class="token string">'flex'</span><span class="token punctuation">,</span>
    flexDirection<span class="token operator">:</span> <span class="token string">'column'</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 comment">// Theme-dependent styles</span>
<span class="token keyword">const</span> <span class="token function-variable function">styles</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> palette<span class="token punctuation">,</span> spacing <span class="token punctuation">}</span><span class="token operator">:</span> Theme<span class="token punctuation">)</span> <span class="token operator">=></span>
  <span class="token function">createStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    root<span class="token operator">:</span> <span class="token punctuation">{</span>
      display<span class="token operator">:</span> <span class="token string">'flex'</span><span class="token punctuation">,</span>
      flexDirection<span class="token operator">:</span> <span class="token string">'column'</span><span class="token punctuation">,</span>
      padding<span class="token operator">:</span> spacing<span class="token punctuation">.</span>unit<span class="token punctuation">,</span>
      backgroundColor<span class="token operator">:</span> palette<span class="token punctuation">.</span>background<span class="token punctuation">.</span>default<span class="token punctuation">,</span>
      color<span class="token operator">:</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 class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

createStyles is just the identity function; it doesn't "do anything" at runtime, just helps guide type inference at compile time.

Media queries

withStyles allows a styles object with top level media-queries like so:

<span class="token keyword">const</span> styles <span class="token operator">=</span> <span class="token function">createStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  root<span class="token operator">:</span> <span class="token punctuation">{</span>
    minHeight<span class="token operator">:</span> <span class="token string">'100vh'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token string-property property">'@media (min-width: 960px)'</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    root<span class="token operator">:</span> <span class="token punctuation">{</span>
      display<span class="token operator">:</span> <span class="token string">'flex'</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>

To allow these styles to pass TypeScript however, the definitions have to be unambiguous concerning the names for CSS classes and actual CSS property names. Due to this, class names that are equal to CSS properties should be avoided.

<span class="token comment">// error because TypeScript thinks `@media (min-width: 960px)` is a class name</span>
<span class="token comment">// and `content` is the CSS property</span>
<span class="token keyword">const</span> ambiguousStyles <span class="token operator">=</span> <span class="token function">createStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  content<span class="token operator">:</span> <span class="token punctuation">{</span>
    minHeight<span class="token operator">:</span> <span class="token string">'100vh'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token string-property property">'@media (min-width: 960px)'</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    content<span class="token operator">:</span> <span class="token punctuation">{</span>
      display<span class="token operator">:</span> <span class="token string">'flex'</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 comment">// works just fine</span>
<span class="token keyword">const</span> ambiguousStyles <span class="token operator">=</span> <span class="token function">createStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  contentClass<span class="token operator">:</span> <span class="token punctuation">{</span>
    minHeight<span class="token operator">:</span> <span class="token string">'100vh'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token string-property property">'@media (min-width: 960px)'</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    contentClass<span class="token operator">:</span> <span class="token punctuation">{</span>
      display<span class="token operator">:</span> <span class="token string">'flex'</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>

Augmenting your props using WithStyles

Since a component decorated with withStyles(styles) gets a special classes prop injected, you will want to define its props accordingly:

<span class="token keyword">const</span> <span class="token function-variable function">styles</span> <span class="token operator">=</span> <span class="token punctuation">(</span>theme<span class="token operator">:</span> Theme<span class="token punctuation">)</span> <span class="token operator">=></span>
  <span class="token function">createStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    root<span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token comment">/* ... */</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    paper<span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token comment">/* ... */</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    button<span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token comment">/* ... */</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 keyword">interface</span> <span class="token class-name">Props</span> <span class="token punctuation">{</span>
  <span class="token comment">// non-style props</span>
  foo<span class="token operator">:</span> number<span class="token punctuation">;</span>
  bar<span class="token operator">:</span> boolean<span class="token punctuation">;</span>
  <span class="token comment">// injected style props</span>
  classes<span class="token operator">:</span> <span class="token punctuation">{</span>
    root<span class="token operator">:</span> string<span class="token punctuation">;</span>
    paper<span class="token operator">:</span> string<span class="token punctuation">;</span>
    button<span class="token operator">:</span> string<span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

However this isn't very DRY because it requires you to maintain the class names ('root', 'paper', 'button', ...) in two different places. We provide a type operator WithStyles to help with this, so that you can just write:

<span class="token keyword">import</span> <span class="token punctuation">{</span> createStyles<span class="token punctuation">,</span> WithStyles <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">styles</span> <span class="token operator">=</span> <span class="token punctuation">(</span>theme<span class="token operator">:</span> Theme<span class="token punctuation">)</span> <span class="token operator">=></span>
  <span class="token function">createStyles</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    root<span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token comment">/* ... */</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    paper<span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token comment">/* ... */</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    button<span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token comment">/* ... */</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 keyword">interface</span> <span class="token class-name">Props</span> <span class="token keyword">extends</span> <span class="token class-name">WithStyles</span><span class="token operator">&lt;</span><span class="token keyword">typeof</span> styles<span class="token operator">></span> <span class="token punctuation">{</span>
  foo<span class="token operator">:</span> number<span class="token punctuation">;</span>
  bar<span class="token operator">:</span> boolean<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Decorating components

Applying withStyles(styles) as a function works as expected:

<span class="token keyword">const</span> DecoratedSFC <span class="token operator">=</span> <span class="token function">withStyles</span><span class="token punctuation">(</span>styles<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">{</span> text<span class="token punctuation">,</span> type<span class="token punctuation">,</span> color<span class="token punctuation">,</span> classes <span class="token punctuation">}</span><span class="token operator">:</span> Props<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">Typography</span></span> <span class="token attr-name">variant</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>type<span class="token punctuation">}</span></span> <span class="token attr-name">color</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>color<span class="token punctuation">}</span></span> <span class="token attr-name">classes</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
    <span class="token punctuation">{</span>text<span class="token punctuation">}</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Typography</span></span><span class="token punctuation">></span></span>
<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> DecoratedClass <span class="token operator">=</span> <span class="token function">withStyles</span><span class="token punctuation">(</span>styles<span class="token punctuation">)</span><span class="token punctuation">(</span>
  <span class="token keyword">class</span> <span class="token class-name">extends</span> React<span class="token punctuation">.</span>Component<span class="token operator">&lt;</span>Props<span class="token operator">></span> <span class="token punctuation">{</span>
    <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token punctuation">{</span> text<span class="token punctuation">,</span> type<span class="token punctuation">,</span> color<span class="token punctuation">,</span> classes <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">;</span>
      <span class="token keyword">return</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">Typography</span></span> <span class="token attr-name">variant</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>type<span class="token punctuation">}</span></span> <span class="token attr-name">color</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>color<span class="token punctuation">}</span></span> <span class="token attr-name">classes</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>classes<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
          <span class="token punctuation">{</span>text<span class="token punctuation">}</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Typography</span></span><span class="token punctuation">></span></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>

Unfortunately due to a current limitation of TypeScript decorators, withStyles(styles) can't be used as a decorator in TypeScript.