Skip to content
CSS-in-JS framework for building approachable design systems.
TypeScript JavaScript
Branch: master
Clone or download

README.md

glaze

CSS-in-JS framework for building approachable design systems.

npm Language grade: JavaScript Travis (.com)

💡 Motivation

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.

🚀 Key features

  • 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 or px for defining horizontal padding

🚧 In development

  • Responsive values defined as an array
  • Pseudo-class support

📚 Usage

  1. Install the package and its peer dependencies:

    npm install glaze treat react-treat
  2. Define a theme, preferably by overriding the default tokens:

    /* theme.treat.js */
    
    import { createTheme, defaultTheme } from 'glaze';
    
    export default createTheme({
      ...defaultTheme,
    
      // Customization
      scales: {
        ...defaultTheme.scales,
        color: {
          red: '#f8485e',
        },
      },
    });
  3. 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>;
    }
  4. 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>
      );
    }
  5. Please refer to the treat documentation for:

    • Setting up static style extraction and server-side rendering
    • Applying a selector-based globalStyle

🤔 How it works

The sx function maps themed values to statically generated class names. If that fails, an inline style gets applied as a fallback.

Rule handling

  1. Transform each alias to its corresponding CSS property name or custom shorthand
  2. Resolve values from the scales available
    • CSS properties associated with a custom shorthand are resolved one by one

Example

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:

  1. { px: 4 }
  2. { paddingX: 4 }, after transforming aliases
  3. { paddingLeft: 4, paddingRight: 4 }, after unfolding custom shorthands
  4. { paddingLeft: '1rem', paddingRight: '1rem' }, after applying resolvers

Contributors

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!

You can’t perform that action at this time.