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:
- 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>
- 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"><</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>
- 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>
- 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"><</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"><</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"></</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>