Skip to content

Using CSS variables

Learn how to use CSS variables to customize Joy UI's components.

Theme object

The CssVarsProvider reads the theme input (or the default theme) and creates the CSS variables according to the theme structure. It also creates an object that refers to the generated CSS variables under theme.vars so that you can use them from the JavaScript theme object.

The theme.vars is available in all styling APIs that Joy UI offers:

  1. The styled function
<span class="token keyword">const</span> Div <span class="token operator">=</span> <span class="token function">styled</span><span class="token punctuation">(</span><span class="token string">'div'</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> theme <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token comment">// The result is 'var(--joy-palette-primary-500)'</span>
  <span class="token literal-property property">color</span><span class="token operator">:</span> theme<span class="token punctuation">.</span>vars<span class="token punctuation">.</span>palette<span class="token punctuation">.</span>primary<span class="token punctuation">[</span><span class="token number">500</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>
  1. The sx prop
<span class="token comment">// The result is 'var(--joy-shadow-sm)'</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Chip</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 parameter">theme</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">boxShadow</span><span class="token operator">:</span> theme<span class="token punctuation">.</span>vars<span class="token punctuation">.</span>shadow<span class="token punctuation">.</span>sm <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span>
  1. Style overrides (themed components)
<span class="token function">extendTheme</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">components</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">JoyButton</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token function-variable function">root</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> theme <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
        <span class="token comment">// The result is 'var(--joy-fontFamily-display)'</span>
        <span class="token literal-property property">fontFamily</span><span class="token operator">:</span> theme<span class="token punctuation">.</span>vars<span class="token punctuation">.</span>fontFamily<span class="token punctuation">.</span>display<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><span class="token punctuation">)</span><span class="token punctuation">;</span>
  1. The useTheme hook.

Alpha channel colors

Joy UI automatically generates the channel tokens (mainChannel, lightChannel and darkChannel) to be used with an opacity. You will find them in these palettes:

  • primary
  • neutral
  • danger
  • info
  • success
  • warning

You can combine the channel tokens with an opacity value like this:

<span class="token keyword">const</span> Div <span class="token operator">=</span> <span class="token function">styled</span><span class="token punctuation">(</span><span class="token string">'div'</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> theme <span class="token punctuation">}</span></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> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">rgba(</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>theme<span class="token punctuation">.</span>vars<span class="token punctuation">.</span>palette<span class="token punctuation">.</span>primary<span class="token punctuation">.</span>mainChannel<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> / 0.12)</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><span class="token punctuation">;</span>

Raw value

In some cases, you might want to use the raw value to create a new one. For example, you can create the inset shadow from the theme like this:

<span class="token keyword">const</span> Div <span class="token operator">=</span> <span class="token function">styled</span><span class="token punctuation">(</span><span class="token string">'div'</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> theme <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token comment">// Note that it's using `theme.shadow`, not `theme.vars.shadow`</span>
  <span class="token literal-property property">boxShadow</span><span class="token operator">:</span> theme<span class="token punctuation">.</span>shadow<span class="token punctuation">.</span>sm<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">,</span><span class="token regex-delimiter">/</span><span class="token regex-flags">g</span></span><span class="token punctuation">,</span> <span class="token string">', inset'</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>

sx prop

When using the short-hand syntax inside the sx prop, Joy UI will try to resolve the value from theme.vars.*. You can use the . notation to get the value of an object.

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Chip</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">border</span><span class="token operator">:</span> <span class="token string">'1px solid'</span><span class="token punctuation">,</span>

    <span class="token comment">// For color related properties, lookup from `theme.vars.palette`</span>
    <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">'neutral.800'</span><span class="token punctuation">,</span> <span class="token comment">// 'var(--joy-palette-neutral-800)'</span>
    <span class="token literal-property property">borderColor</span><span class="token operator">:</span> <span class="token string">'neutral.400'</span><span class="token punctuation">,</span> <span class="token comment">// 'var(--joy-palette-neutral-400)'</span>

    <span class="token comment">// lookup from `theme.vars.shadow`</span>
    <span class="token literal-property property">shadow</span><span class="token operator">:</span> <span class="token string">'sm'</span><span class="token punctuation">,</span> <span class="token comment">// 'var(--joy-shadow-sm)'</span>

    <span class="token comment">// lookup from `theme.vars.fontSize`</span>
    <span class="token literal-property property">fontSize</span><span class="token operator">:</span> <span class="token string">'sm'</span><span class="token punctuation">,</span> <span class="token comment">// 'var(--joy-fontSize-sm)'</span>
  <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
<span class="token punctuation">/></span></span>

Custom prefix

By default, the generated CSS variables are prefixed with joy. If you want to change the prefix to something else, provide the cssVarPrefix to the extendTheme:

<span class="token keyword">import</span> <span class="token punctuation">{</span> CssVarsProvider<span class="token punctuation">,</span> extendTheme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/joy/styles'</span><span class="token punctuation">;</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 punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CssVarsProvider</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 function">extendTheme</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">cssVarPrefix</span><span class="token operator">:</span> <span class="token string">'company'</span> <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 operator">...</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">CssVarsProvider</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

The generated CSS variables will be:

<span class="token deleted-sign deleted"><span class="token prefix deleted">-</span><span class="token line"> --joy-fontSize-md: 1rem;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line"> --company-fontSize-md: 1rem;</span></span>

Remove the prefix

Specify "" as a value to extendTheme({ cssVarPrefix: '' }).

The generated CSS variables will be:

<span class="token deleted-sign deleted"><span class="token prefix deleted">-</span><span class="token line"> --joy-fontSize-md: 1rem;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line"> --fontSize-md: 1rem;</span></span>