Customizing Colors
A guide to adding custom color tokens and aliases.
Overview
Master CSS uses variables to define color tokens, allowing you to access a single source of truth for colors directly within your template markup. This not only improves the readability of your templates but also prevents unused CSS variables from being included in the final output, leading to cleaner and more efficient CSS.
Using default 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.
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'export default { variables: { primary: variables.indigo }}
Apply them using the color-realted syntax:
<div class="bg:primary-5 fg:primary-60">…</div>
Using color modes
You can also use variable modes to define colors for different themes, such as light and dark modes. As your styles grow, arbitrarily applying @dark
or @light
in template markup can make it difficult to maintain consistency in your design system's color tokens.
<div class="fg:white@dark fg:black@light"><div class="fg:neutral">
Basic usage
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
@layer base, theme, preset, components, general;@layer general { .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
@layer base, theme, preset, components, general;@layer general { .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)' /* secondary */ }}
Apply it using color-related syntax.
<div class="fg:secondary">…</div>
Generated CSS
@layer base, theme, preset, components, general;@layer general { .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
@layer base, theme, preset, components, general;@layer general { .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', // usually not required '@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:primary">…</body></html>
Generated CSS
@layer base, theme, preset, components, general;@layer theme { :root { --primary: 255 0 0 } .light { --primary: 255 255 255 } .dark { --primary: 0 0 0 }}@layer general { .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
@layer base, theme, preset, components, general;@layer general { .fg\:app-blue { color: rgb(69 137 255) }}
Customizing primitive colors
Add a primitive color to the base variables group.
export default { variables: { primary: '#000' }}
Apply the custom color:
<p class="bg:primary"></p>
Customizing text colors
Add a color to the text variables group.
export default { variables: { text: { primary: '#000' } }}
Apply the custom color:
<p class="fg:primary"></p>
Apply a text color
Apply the defined text-*
variables using the inherited rules color
, text-decoration-color
, text-decoration
, text-fill-color
, caret-color
.
<html class="light"> <body class="fg:neutral"></body> <body class="fg:text-neutral">equals</body> <body class="fg:$(text-neutral)">equals</body></html>
We set the foreground color of elements using fg:color
rather than the text-specific text:color
.
<p class="text:pink">text-fill-color properity</p>
Apply text color to any syntax
Besides inheriting the above rules, you can use text-*
to access global text color variables in other syntax.
<svg class="stroke:text-light"></svg>
Escape inherited text colors
Use $(blue)
to apply variables.blue
instead of variables.text.blue
.
<p class="fg:$(blue)">…</p>
Customizing frame colors
Add a color to the frame variables group.
export default { variables: { light: { '@light': '$(slate-60)/.2', '@dark': '$(gray-30)/.2' } }}
Apply a frame color
Apply the defined frame-*
variables using the inherited rules border-top-color
, border-bottom-color
, border-left-color
, border-right-color
, border-x-color
, border-y-color
, border-color
, border-top
, border-bottom
, border-left
, border-right
, border-x
, border-y
, border
, outline-color
, outline
.
<div class="outline:neutral"></div> <div class="outline:frame-neutral">equals</div><div class="outline:$(frame-neutral)">equals</div>