Customization

Creating Variables

A guide to using variables to implement design tokens.

Overview

In Master CSS, variables are used to manage tokens in the design system, such as colors, font families, breakpoints, etc., even based on different theme modes.

import { variables } from '@master/css'
export default {
variables: {
'font-family': {
sans: 'Inter'
},
screen: { desktop: 1280 },
spacing: { sm: 10 },
primary: '
#000000
'
}
}

Apply custom variables using ambiguous shorthand:

<div class="font:sans max-w:screen-desktop m:sm bg:primary"></div>

Design tokens are a fundamental part of design systems and are crucial for maintaining design consistency and efficiency in projects, especially in larger organizations or projects with complex design requirements. They help bridge the gap between design and development, promoting collaboration and ensuring a cohesive user experience.


Fonts

By default, Master provides three font family variables, sans, serif, and mono, to facilitate your use as fallbacks when adding custom fonts.

Add fonts

Customize your font tokens by defining variables. For example, add Inter as the general font and Fira Code as the code font.

import { variables } from '@master/css'
export default {
variables: {
'font-family': {
sans: ['Inter', ...variables['font-family'].sans],
mono: ['Fira Code', ...variables['font-family'].mono]
}
}
}

Apply the defined font-family variables. For example, presetting the global fonts in <body>:

<body class="font:sans font:mono_:where(code,pre) font-feature:'salt'"></body>

Don't forget to add the font faces.


Colors

Each color in the default color palette has a hue range from 5 to 95, which you can choose from as your brand's primary color.

indigo
5#f0f1fe
10#e9ecfe
20#c8cdfe
30#939eff
40#7e81fe
50#7068ff
60#5b4cfd
70#4e39ed
80#4732d2
90#3623a3
95#26176c

For example, inherit from indigo:

import { variables } from '@master/css'
/** @type {import('@master/css').Config} */
export default {
variables: {
primary: variables.indigo
}
}

Apply them using the relevant syntax:

<div class="bg:primary-5 fg:primary-60"></div>

Add a color

Add the primary color using #000, rgb(0 0 0), or hsl(0 0% 0%).

export default {
variables: {
primary: '
#000
'
}
}

Apply it using color-related syntax and even change the opacity.

<div class="fg:primary bg:primary/.5"></div>
Generated CSS
.bg\:primary\/\.5 {
background-color: rgb(0 0 0/.5)
}
.fg\:primary {
color: rgb(0 0 0)
}

If a color is used only once in all markups, you can optionally not abstract it into a token.

<button class="bg:
#ceb195
"
>
Milk Tea</button>

Variables only support rgb and hsl, in the future, they will be compatible with all native CSS functions, such as rgba, hsla, lab, and others. #346

Add a color with opacity

Add color variables with opacity using #00000080, rgb(0 0 0/.5), or hsl(0 0% 0%/.5).

export default {
variables: {
primary: 'rgb(0 0 0/0.5)'
}
}

Apply it using color-related syntax like fg:.

<div class="fg:primary"></div>
Generated CSS
.fg\:primary {
color: rgb(0 0 0 / .5)
}

Color variables with opacity cannot use /alpha to change the opacity.

<div class="fg:primary/.5"></div>

Add a color alias

Create an alias for a color to link its value to an existing color.

export default {
variables: {
secondary: '$(blue-60)'
}
}

Apply it using color-related syntax.

<div class="fg:secondary"></div>
Generated CSS
.fg\:secondary {
color: rgb(37 99 253)
}

For example, say you have multiple color variables referencing the same color token. If that color needs updating, you would only need to update the source instead of manually updating every instance of the color.

Add a color alias with opacity

Create an alias for a color with opacity to link its value to an existing color.

export default {
variables: {
primary: '$(black)/.5', // <─┐
secondary: '$(primary)/.5' // ──┘ linked to primary
}
}

Apply it using color-related syntax like fg:.

<div class="bg:primary fg:secondary"></div>
Generated CSS
.bg\:primary {
background-color: rgb(0 0 0 / .5)
}
.fg\:secondary {
color: rgb(0 0 0 / .25)
}

As shown above, creating an alias secondary linked to an existing alias primary with opacity /.5 is possible, and the opacity will be multiplied 0.5 * 0.5 = 0.25.

Add color shades

Sets multiple shades for a single color.

export default {
variables: {
primary: {
'': '
#1192e8
'
, // primary
10: '
#e5f6ff
'
, // primary-10
20: '
#bae6ff
'
, // primary-20
}
}
}

Apply it using color-related syntax like fill:.

<svg class="fill:primary-20 ">20</svg>

Add colors based on modes

Add color variables in different theme modes.

export default {
variables: {
primary: {
'': '
#ff0000
'
, // There is usually no need to give a fallback.
'@light': '
#fff
'
,
'@dark': '
#000
'
}
}
}

Using modes for variables, you can access a single source of truth and simplify the markup.

<html class="light">
<body class="bg:
#fff
@light
bg:
#000
@dark
"
>
</body>
<body class="bg:primary"></body>
</html>
Generated CSS
:root {
--primary: 255 0 0
}
.light,
:root {
--primary: 255 255 255
}
.dark {
--primary: 0 0 0
}
.bg\:primary {
background-color: rgb(var(--primary))
}

By default, theme variables drive inheritance by adding .light or .dark to the parent element.

Override default colors

Access the same key as the preset to override default colors, like blue-5 ~ blue-95.

export default {
variables: {
blue: '
#4589ff
'
}
}

Use app-* to avoid conflicts with defaults and keep blue-* colors consistent.

export default {
variables: {
app: {
blue: '
#4589ff
'
// app-blue
}
}
}

Apply custom colors for the current application.

<div class="fg:app-blue"></div>
Generated CSS
.fg\:app-blue {
color: rgb(69 137 255)
}

Screens and Breakpoints

The screen in the variable is a reserved section. In addition to being used as a property value token screen-*, it also serves as a responsive breakpoint @*.

Apply default screen variables using any syntax, such as width and max-width.

<div class="w:screen-sm max-w:screen-lg"></div>

Conditionally apply styles using default screen variables as responsive breakpoints.

<div class="font:24 font:32@sm font:48@md"></div>

The responsive breakpoints can be flexibly used with operators, see the responsive design documentation.

Add a screen size

Add your screen size by defining variables.

export default {
variables: {
screen: {
desktop: 1280 // screen-desktop
}
}
}

Apply the defined screen variables anywhere:

<div class="max-w:screen-desktop mx:auto"></div>
Generated CSS
.mx\:auto {
margin-left: auto;
margin-right: auto
}
.max-w\:screen-desktop {
max-width: 80rem
}

And it can be used as a responsive breakpoint:

<div class="font:24 font:48@desktop"></div>
Generated CSS
.font\:24 {
font-size: 1.5rem
}
@media (min-width:1280px) {
.font\:48\@desktop {
font-size: 3rem
}
}

Spacing and Sizing

The spacing and sizing system is constructed using a base unit of 4 pixels. For visual consistency, you can use the multiplier unit x to apply spacing with the same scale.

<div class="m:1x">4px, margin: 0.25rem</div>
<div class="p:2x">8px, padding: 0.5rem</div>
<div class="w:8x">32px, width: 2rem</div>
<div class="gap:3x">12px, gap: 0.75rem</div>
<div class="size:6x">24px, width: 1.5rem; height: 1.5rem</div>

It's no longer necessary to define the spacing scale one by one as in the traditional way.

export default {
variables: {
spacing: {
'1x': 4,
'2x': 8,
...,
'100x': 400
}
}
}

For other intermediate values, 0, 1, 2, ..., we tend to use unitless tokens:

<div class="m:0">0px, margin: 0rem</div>
<div class="p:1">1px, padding: 0.0625rem</div>
<div class="w:2">2px, width: 0.125rem</div>

Add a spacing

Customize your spacing variables, in xs~xl.

export default {
variables: {
spacing: {
md: 20
}
}
}

Apply the defined spacing variables using the inherited syntaxes like margin-top and padding.

<div class="mt:md p:md"></div>

Do not use numerical values as tokens.

export default {
variables: {
spacing: {
1: 4,
2: 8
}
}
}

It can be confused with the unitless values.

Getting Started
Introduction to Master CSS

The CSS language and framework for rapidly building modern and high-performance websites.

© Aoyue Design LLC.