apps/public-docsite-v9/src/Concepts/Theming.mdx
import { Meta, Source } from '@storybook/addon-docs/blocks';
<Meta title="Concepts/Developer/Theming" />The Fluent UI Theme is represented by a set of tokens. Each token resolves to a single value which can be assigned to a CSS property.
const exampleTheme = {
borderRadiusSmall: '2px',
//...
colorNeutralForeground2: '#424242',
};
You can browse all the available tokens in Theme section of the docs.
No matter what theme is used, the component styles are always the same. The only way to change the component styling is through theme tokens which can be used in style values.
Those tokens are resolved to CSS variables. The FluentProvider component is responsible for setting the values of the CSS variables in DOM and changing them when the theme changes. When the theme is switched, only the variables are changed, all styles remain the same.
Place a <FluentProvider /> at the root of your app and pass a theme to the theme prop. The provider will render a div and set all tokens as CSS variables on that element. The provider also propagates CSS variables to React portals created with Portal component.
import { FluentProvider, teamsLightTheme } from '@fluentui/react-components';
export const AppRoot = ({children}) => (
<FluentProvider theme={teamsLightTheme}>
{children}
</FluentProvider>,
);
Import tokens to style a component using makeStyles
import { tokens } from '@fluentui/react-components';
const useStyles = makeStyles({
root: { display: 'flex' },
rootPrimary: { color: tokens.colorNeutralForeground3 },
});
export Component = props => {
const classes = useStyles();
return <div className={mergeClasses('ui-component', classes.root, props.primary && classes.rootPrimary)} />;
}
For more details, see Styling components.
⚠ Never use theme CSS variables directly! The CSS variables implementation of the theme is internal to the library. We might eventually decide to change the variable names, hash them or even use direct values instead of some variables. Always use the tokens to access the theme.
Fluent UI currently exports following themes:
webLightTheme)webDarkTheme)teamsLightTheme)teamsDarkTheme)teamsHighContrastTheme)⚠ Do not use High Contrast themes! All Fluent UI components support Windows High Contrast mode automatically regardless of the active theme. Windows high contrast mode is the recommended high contrast platform for all customers using Fluent UI.
Hardcoded High Contrast themes are considered legacy, to be used only in applications which explicitly support those.
Applications can customize a theme in multiple ways.
The brand ramp is a color ramp going from dark to light colors:
A theme is derived from a brand ramp. To use a theme with a custom brand ramp, instead of importing a predefined theme, you can use theme factory functions.
The following factory functions are available:
createLightTheme()createDarkTheme()createTeamsDarkTheme()createHighContrastTheme()import { BrandVariants, createLightTheme, createDarkTheme } from '@fluentui/react-components';
const customBrandRamp: BrandVariants = {
10: '#008',
//...
160: '#88F',
};
export const customLightTheme = createLightTheme(customBrandRamp);
export const customDarkTheme = createDarkTheme(customBrandRamp);
⚠️ If the existing tokens do not fulfill your needs, you should talk to your designer instead of overriding tokens.
A theme is a flat object containing { [token name]: CSS value } pairs. You can copy the object and overwrite any tokens you wish.
import { webLightTheme, Theme } from '@fluentui/react-components';
export const customLightTheme: Theme = {
...webLightTheme,
colorNeutralForeground1: '#555', // overriden token
};
It's often useful for an app to extend the base set of tokens from Fluent UI. This process will help consuming teams or libraries add more tokens, but sharing them is outside the scope of this doc.
⚠ Warning that adding more tokens adds more CSS variables which can effect run time performance as each DOM Node carries all the tokens.
import { makeStyles, themeToTokensObject, webLightTheme, FluentProvider, Theme } from '@fluentui/react-components';
// You can pass your own custom tokens to a theme and pass that to the provider.
type CustomTheme = Theme & {
tokenA: string;
tokenB: string;
tokenC: string;
};
const customTheme: CustomTheme = { ...webLightTheme, tokenA: 'red', tokenB: 'blue', tokenC: 'green' };
function App() {
return <FluentProvider theme={customTheme}></FluentProvider>;
}
// ...
// You can construct a custom tokens object by yourself.
const customTokens: Record<keyof CustomTheme, string> = {
...tokens,
tokenA: `var(--tokenA)`,
tokenB: `var(--tokenB)`,
tokenC: `var(--tokenC)`,
};
// You can alternatively use the themeToTokensObject function to construct the custom tokens object.
// Note: If you do it via the themeToTokensObject you might see a negative effect on tree-shaking since bundles won't know the shape of the output.
const alternativeCustomTokens = themeToTokensObject(customTheme);
// You can then use this custom tokens object inside your styles.
const useStyles = makeStyles({
base: {
color: customTokens.tokenA,
backgroundColor: customTokens.tokenB,
outlineColor: customTokens.tokenC,
},
});