master-co / css

The CSS Language and Framework
https://css.master.co
MIT License
1.82k stars 41 forks source link

✨ Master CSS Variables #283

Closed 1aron closed 1 year ago

1aron commented 1 year ago

Currently we use config.values or config.rules[].values to implement global variables, but they are not flexible enough and can be assigned anywhere reliably.

✨ New configuration variables

Everything will make more sense by integrating any design tokens into the new concept of Master CSS Variables:

/** @type {import('@master/css').Config} */
export default {
    variables: {
        spacing: {
            x1: 16, // spacing-x1
            x2: 32, // spacing -x1
            ...
        },
        blue: {
            50: '#0000FF' // blue-50
        },
        shadow: {
            x1: 'rgb(0 0 0 / 3%) 0px 1px 2px' // shadow-x1
        }
    }
}

✨ New variable syntax

Previously $(variable) was used to simplify the native CSS functions var(--variable). To make the application more concise, we retain $(variable) as the syntax of Master CSS Variables.

Use the new function $(variable-xxx) to explicitly access any target variable from anywhere.

<div class="m:$(-spacing-x1)"></div>

Generated CSS:

.m\:\$\(-spacing-x1\) {
    margin: -1rem
}

In fact, m:$(spacing-x1) is equivalent to m:x1 because we've pre-assigned the spacing variable group to the margin rule:

export const config = {
    rules: {
        margin: {
            variables: ['spacing'],
            ...
        }
    }
}

Fallback

If the Master CSS variable cannot be found, it falls back to the native CSS variable.

<div class="text-align:$(not-found)">
.text-align\:\$\(not-found\) {
    text-align: var(--not-found)
}

Alias

You can use $() in the configuration to set an alias for another variable.

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

✨ Variables for different themes

config.colors currently supports different themes and is also a variable, we plan to merge it into config.variables.

export default {
    variables: {
        primary: { 
            '': '#ff0000', // default ( fallback )
            '@dark': '#ffffff', // dark mode
            '@light': '#000000' // light mode
        }
    }
}
<button class="bg:primary fg:primary border:primary accent:primary outline:primary">

🟠 It's based on N different themes, N corresponding CSS rules are generated with the same syntax. These rules cannot be reused across themes, meaning the CSS size will immediately grow with the number of themes.

.dark .bg\:primary { background-color: '#ffffff' }
.dark .fg\:primary { color: '#ffffff' }
.dark .border\:primary { border-color: '#ffffff' }
.dark .accent\:primary { accent-color: '#ffffff' }
.dark .outline\:primary { outline-color: '#ffffff' }
.light .bg\:primary { background-color: '#000000' }
.light .fg\:primary { color: '#000000' }
.light .border\:primary { border-color: '#000000' }
.light .accent\:primary { accent-color: '#000000' }
.light .outline\:primary { outline-color: '#000000' }
.bg\:primary { background-color: '#ff0000' }
.fg\:primary { color: '#ff0000' }
.border\:primary { border-color: '#ff0000' }
.accent\:primary { accent-color: '#ff0000' }
.outline\:primary { outline-color: '#ff0000' }

🟢 Generate CSS variables on demand based on syntax.

:root { --primary: 255 0 0 }
.dark { --primary: 255 255 255 }
.light { --primary: 0 0 0 }
.bg\:primary { background-color: rgb(var(--primary)) }
.fg\:primary { color: rgb(var(--primary)) }
.border\:primary { border-color: rgb(var(--primary)) }
.accent\:primary { accent-color: rgb(var(--primary)) }
.outline\:primary { outline-color: rgb(var(--primary)) }

This architecture will produce less CSS than previous versions.

1aron commented 1 year ago

🎉 Partially released in https://github.com/master-co/css/releases/tag/v2.0.0-beta.184

github-actions[bot] commented 1 year ago

:tada: This issue has been resolved in version 2.0.0-beta.192 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] commented 10 months ago

:tada: This issue has been resolved in version 2.0.0-rc.1 :tada:

The release is available on:

Your semantic-release bot :package::rocket: