Fundamentals

Reusing Styles

A guide to reusing styles and code de-duplication.

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.

This guide also provides specialized solutions tailored for frameworks.


Abstracting 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 {
styles: {
btn: {
'': 'center-content inline-flex font:semibold outline-offset:-1',
'xs': 'font:12 h:6x px:2x px:3x.rounded r:4',
'sm': 'font:12 h:8x px:3x px:4x.rounded r:6',
'md': 'font:14 h:10x px:4x px:5x.rounded r:6',
'lg': 'font:16 h:12x px:5x px:6x.rounded r:8',
'xl': 'font:16 h:14x px:6x px:7x.rounded r:10'
}
}
} 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 the button sizes that are finely tuned for rounded styles.

<button class="btn btn-xs rounded ">Submit</button>
<button class="btn btn-sm rounded ">Submit</button>
<button class="btn btn-md rounded ">Submit</button>
<button class="btn btn-lg rounded ">Submit</button>
<button class="btn btn-xl 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 {
variables: {
yellow: {
ring: {
'@light': '$(black)/.1',
'@dark': '$(white)/.3'
}
},
touch: {
yellow: {
'@light': '$(yellow-30)',
'@dark': '$(yellow-40)'
}
},
text: {
'yellow-contrast': {
'@light': '$(yellow-90)',
'@dark': '$(yellow-95)'
}
}
},
styles: {
yellow: 'bg:yellow fg:yellow-contrast outline:1|yellow-ring',
touch: {
yellow: 'bg:touch-yellow:hover'
}
},
} as Config
<button class="btn btn-md yellow touch-yellow">Submit</button>

Componentization

In addition to styles, we provide a CSS-in-JS style utility, Master Styled, to help you create a component with classes in one line. It supports Vanilla js, React, and Vue.

🗂️ components
|-- 📄 Button.tsx
`-- 📄 Card.tsx
📄 master.css.ts

Create a button component

You can define type-safe styles and corresponding classes for style properties.

import styled from '@master/styled.react'
const sizes = {
xs: 'font:12 h:6x …',
sm: 'font:12 h:8x …',
md: 'font:14 h:10x …',
lg: 'font:16 h:12x …',
xl: 'font:16 h:14x …'
}
declare type Props = {
$size: keyof typeof sizes
disabled?: boolean
}
const Button = styled.button<Props>('inline-flex font:semibold', {
$size: sizes,
disabled: 'opacity:.5'
})
Button.defaultProps = {
$size: 'md'
}
export default Button

To use the button component.

<Button $size="sm" disabled>Submit</Button>

Rendered as:

<button class="inline-flex font:semibold font:12 h:8x opacity:.5">Submit</button>

However, if the component involves richer implementations such as loading, you should wrap it with a functional component.

Create a block-scoped component

styled operates on an element basis, unlike global styles mentioned above, and you can declare it within a functional component or at the top level.

Create a reusable section component specific to a marketing page.

import styled from '@master/styled.react'
export default function Page() {
const Section = styled.section`bg:slate-90 text:white p:15x|20x`
return (
<>
<section className="bg:slate-90 text:white p:15x|20x">...</section>
<section className="bg:slate-90 text:white p:15x|20x">...</section>
<Section>...</Section>
<Section>...</Section>
...
</>
)
}

This is useful for block-specific style reuse, rather than creating styles['home-section'] which may pollute global styles or cause name collisions.


Summary

Design Token
Colors

Customizing color variables or starting with the crafted palette.

© Aoyue Design LLC.