Fundamentals

Reusing Styles

A guide to reusing styles, code de-duplication, and creating components.

Overview

As the styles grow, the class name combinations and the same design patterns appear over and over again in the code. To improve development efficiency and maintain design consistency, you should reuse or access them in some way.

Traditionally, we define components like .btn or .card by writing CSS rules. In Master CSS, we use config.components to abstract and make them more flexible.

export default {    components: {        btn: {            '': 'inline-flex font:semibold',             'sm': 'r:6 px:3x font:12 h:8x',             'md': 'r:6 px:4x font:14 h:10x',         }    }}

An abstract style consists of one or more syntaxes, you can provide a class name for this set of classes and reuse it anywhere.

Try making the viewport width smaller

/examples/responsive-button

You can even conditionally apply abstract styles via at-rules:

<button class="btn btn-md btn-sm@<sm">Submit</button>
Generated CSS
@layer base, theme, preset, components, general;@layer components {    .btn {        display: inline-flex    }    .btn-md {        border-radius: 0.375rem    }    .btn-md {        padding-left: 1rem;        padding-right: 1rem    }    .btn {        font-weight: 600    }    .btn-md {        font-size: 0.875rem    }    .btn-md {        height: 2.5rem    }    @media (width<52.125rem) {        .btn-sm\@\<sm {            border-radius: 0.375rem        }    }    @media (width<52.125rem) {        .btn-sm\@\<sm {            padding-left: 0.75rem;            padding-right: 0.75rem        }    }    @media (width<52.125rem) {        .btn-sm\@\<sm {            font-size: 0.75rem        }    }    @media (width<52.125rem) {        .btn-sm\@\<sm {            height: 2rem        }    }}

Creating components

Master CSS introduces a concise syntax system for defining abstract, reusable styles called components. These components encapsulate styling logic that can be applied directly to HTML elements, enabling consistent design patterns, improved maintainability, and scalable UI development across your project.

Add a style

Create an abstract style using Master CSS syntaxes.

export default {    components: {        btn: 'inline-flex h:10x'     }}

Apply the btn style to the button element:

<button class="btn">Submit</button>
Generated CSS
@layer base, theme, preset, components, general;@layer components {    .btn {        display: inline-flex    }    .btn {        height: 2.5rem    }}

Add a style with states

Create an abstract style with state selectors and conditional queries.

export default {    components: {        btn: 'outline:2|invert:focus outline-offset:2:focus'     }}

Try clicking the button to see the outline effect

<button class="btn">Submit</button>
Generated CSS
@layer base, theme, preset, components, general;@layer theme {    @media (prefers-color-scheme:light) {        :root {            --color-invert: oklch(0% 0 none)        }    }    @media (prefers-color-scheme:dark) {        :root {            --color-invert: oklch(100% 0 none)        }    }}@layer components {    .btn:focus {        outline: 0.125rem var(--color-invert) solid    }    .btn:focus {        outline-offset: 0.125rem    }}

Add styles in a nested structure

Create and manage a set of abstract styles in a nested structure. Rather than repeating the same style names over and over again, you can write one style inside another. Master CSS will automatically combine the outer style’s name with the inner style’s.

export default {    components: {        card: {             '': 'r:2x',             /* .card */             header: 'bb:1|black',    /* .card-header */             content: 'p:5x',        /* .card-content */             footer: 'bt:1|black',    /* .card-footer */         }     }}

Apply the components:

<div class="card">    <div class="card-header">…</div>    <div class="card-content">…</div>    <div class="card-footer">…</div></div>
Generated CSS
@layer base, theme, preset, components, general;@layer components {    .card {        border-radius: 0.5rem    }    .card-content {        padding: 1.25rem    }    .card-footer {        border-top: 0.0625rem oklch(0% 0 none) solid    }    .card-header {        border-bottom: 0.0625rem oklch(0% 0 none) solid    }}

The empty string '' represents an outer style, much like Sass's &.

Extend an existing style

Create a new abstract style by extending an existing style and adding additional syntax.

export default {    components: {        a: 'fg:black',        b: 'text:underline a'     }}

You can see that b inherits the text lime color of a:

ab
<span class="a">a</span><span class="b">b</span>
Generated CSS
@layer base, theme, preset, components, general;@layer components {    .b {        -webkit-text-decoration: underline;        text-decoration: underline    }    .a {        color: oklch(0% 0 none)    }    .b {        color: oklch(0% 0 none)    }}

Managing styles

As usual, you can split the styles into multiple files for management. When the project is small in scale, you don't necessarily have to insist on splitting style files.

styles
button.ts
card.ts
master.css.ts

Create button styles

Let's implement a rich button.

import type { Config } from '@master/css'export default {    components: {        btn: {            '': 'inline-flex items-center justify-center font:semibold outline-offset:-1',            'xs': 'r:4 px:2x font:12 h:6x',            'sm': 'r:6 px:3x font:12 h:8x',            'md': 'r:6 px:4x font:14 h:10x',            'lg': 'r:8 px:5x font:16 h:12x',            'xl': 'r:10 px:6x font:16 h:14x',        }    }} as Config

Extend them uniformly in the master.css.ts entry file.

import type { Config } from '@master/css'import button from './styles/button'export default {    extends: [        button    ]} as Config

To apply the button sizes.

<button class="btn btn-xs">Submit</button><button class="btn btn-sm">Submit</button><button class="btn btn-md">Submit</button><button class="btn btn-lg">Submit</button><button class="btn btn-xl">Submit</button>

To apply with rounded styles.

<button class="btn btn-md rounded">Submit</button>

To design a scalable style, you should ensure the single responsibility of class composition; otherwise, you may end up using a lot of !important to override rules or the @preset layer to lower default styles, ultimately leading to chaotic styles.

Create common variables and styles

We define variables and modes to create tokens supporting light/dark modes in advance. This not only simplifies template markup but also reduces CSS rule output.

import type { Config } from '@master/css'export default {    modes: {        light: {            color: {                'yellow-ring': '$color-black/.1',                'touch-yellow': '$color-yellow-30',                text: {                    'yellow-contrast': '$color-yellow-90'                }            }        },        dark: {            color: {                'yellow-ring': '$color-white/.3',                'touch-yellow': '$color-yellow-40',                text: {                    'yellow-contrast': '$color-yellow-95'                }            }        }    },    components: {        yellow: 'outline:1|yellow-ring bg:yellow fg:yellow-contrast',        touch: {            yellow: 'bg:touch-yellow:hover'        }    },} as Config
  • Variables
    • yellow-ring is an outline color that complements a yellow background.
    • touch-yellow is a background color on hover.
    • text-yellow-contrast is a contrasting color fine-tuned against a yellow background.
  • Components
    • .yellow sets a background, foreground and outline style for a yellow theme.
    • .yellow-touch sets a background, foreground and outline style for a yellow theme interaction.
<button class="btn btn-md yellow touch-yellow">Submit</button>

Summary

  • Moderately abstracting styles make design easier to manage and maintain consistency, but it doesn't mean that all styles should be abstracted.
  • Only abstract styles that have the potential for reuse, rather than naming them simply for brevity or naming's sake.
  • A good CSS structure combines abstract classes and utility classes — don’t get hung up on specific approaches.

  • Master UI


© 2025 Aoyue Design LLC.MIT License
Trademark Policy