CSS-in-JS framework for building approachable design systems.
When styling HTML elements, quite a few approaches may come to mind, including:
- Utility-first/Atomic CSS, as implemented by Tailwind CSS, StyleSheet and CSS-Zero
- Fully static, but customizable upfront
- Embraces reusability with no duplicated rules
- Constraint-based layouts, popularized by Theme UI
- Highly dynamic, thankfully to Emotion
- One-off styles can be defined naturally
Baking the benefits outlined above into a single package, glaze was born.
- Simple API inspired by inline styles
- Near-zero runtime built upon treat
- Personalizable design tokens inherited from Tailwind CSS and Theme UI
- Composable property aliases and shorthands mapped to scales
- E.g.
paddingX
orpx
for defining horizontal padding
- E.g.
- Responsive values defined as an array
- Pseudo-class support
-
Install the package and its peer dependencies:
npm install glaze treat react-treat
-
Define a theme, preferably by overriding the default tokens:
/* theme.treat.js */ import { createTheme, defaultTokens } from 'glaze'; export default createTheme({ ...defaultTokens, // Customization scales: { ...defaultTokens.scales, color: { red: '#f8485e', }, }, });
-
Apply the theme through
ThemeProvider
:π A Gatsby plugin is available for this task.
import { ThemeProvider } from 'glaze'; import theme from './theme.treat'; export default function Layout({ children }) { return <ThemeProvider theme={theme}>{children}</ThemeProvider>; }
-
Style elements with the
sx
function:import { useStyling } from 'glaze'; export default function Component() { const sx = useStyling(); return ( <p className={sx({ px: 4, // Sets padding-left and padding-right to 1rem color: 'white', bg: 'red', // Sets background to #f8485e })} > Hello, world! </p> ); }
-
Please refer to the treat documentation for:
- Setting up static style extraction and server-side rendering
- Applying a selector-based
globalStyle
- The
sx
function maps themed values to statically generated class names- If that fails, the style gets injected dynamically through the CSSOM
- Dynamic styles which are not in use by any component get removed
- Transform each alias to its corresponding CSS property name or custom shorthand
- Resolve values from the scales available
- CSS properties associated with a custom shorthand are resolved one by one
Given the theme below:
import { createTheme } from 'glaze';
export default createTheme({
scales: {
spacing: { 4: '1rem' },
},
shorthands: {
paddingX: ['paddingLeft', 'paddingRight'],
},
aliases: {
px: 'paddingX',
},
resolvers: {
paddingLeft: 'spacing',
paddingRight: 'spacing',
},
});
An sx
parameter is matched to CSS rules as follows:
{ px: 4 }
{ paddingX: 4 }
, after transforming aliases{ paddingLeft: 4, paddingRight: 4 }
, after unfolding custom shorthands{ paddingLeft: '1rem', paddingRight: '1rem' }
, after applying resolvers
Thanks goes to these wonderful people (emoji key):
KristΓ³f PoduszlΓ³ π§ π» π π‘ π€ π |
Jess Telford π |
This project follows the all-contributors specification. Contributions of any kind welcome!