JavaScript Christmas

Wrap up your CSS with Stitches!

A 4 minute read written by
Geir Sagberg
15.12.2020

Previous postNext post

Have you ever struggled with CSS? Have you found it hard to structure a large CSS codebase, even when using methodologies like BEM or OOCSS? Have you tried using CSS-in-JS solutions, but struggled with the setup or lack of typing? Or maybe you've used Tailwind, but find the initial bundle size intimidating, or the tooling to reduce it too complex?

Stitches is a new CSS-in-JS library from Modulz and Christian Alfoni, creator of Cerebral and Overmind. It promises "Near-zero runtime, server-side rendering, multi-variant support, and best-in-class developer experience."

We'll take a look at what this means, and how Stitches compares to existing CSS-in-JS solutions like Styled Components, Emotion and Material UI.

Getting started

Stitches provides two separate libraries, @stitches/core for framework-agnostic functionality, and @stitches/react which is similar to Styled Components for React.

@stitches/core

Stitches can be used without any specific view framework, and provides us with several benefits, for example:

  • Type safe CSS
  • Minimal CSS size due to atomic classes
  • Custom token support

We'll take a look at each one of these.

Type safe CSS

Here is a very simple example using nothing but @stitches/core:

import { createCss } from '@stitches/core'

const css = createCss({})

const root = css({
  background: 'lightblue',
  padding: '1rem',
})

const content = css({
  paddingLeft: '1rem',
})

document.getElementById('app')!.innerHTML = `
<div class="${root}">
  <h1>Hello Stitches!</h1>
  <div class="${content}">Time to make some styles!</div>
</div>
`

When using a modern editor like VS Code, we can get full autocompletion of CSS properties with Stitches:

CSS Autocompletion

No more mistyped CSS properties!

Atomic classes

The above example renders into:

<main id="app">
  <div
    class="_initial_pl_hmLUax _initial_pb_hCFMjp _initial_pr_gPZsxG _initial_pt_dbpDZB _initial_bc_hdHkoT"
  >
    <h1>Hello Stitches!</h1>
    <div class="_initial_pl_hmLUax">Time to make some styles!</div>
  </div>
</main>

What are all these classes? Let's take a look:

._initial_pl_hmLUax {
  padding-left: 1rem;
}
._initial_pb_hCFMjp {
  padding-bottom: 1rem;
}
._initial_pr_gPZsxG {
  padding-right: 1rem;
}
._initial_pt_dbpDZB {
  padding-top: 1rem;
}
._initial_bc_hdHkoT {
  background-color: lightblue;
}

Stitches splits up our styles into separate atomic classes; this is useful because components with the same style only need a single class definition per property, e.g. _initial_pl_hmLUax, which maps to padding-left: 1rem, is used both for our root and content classes!

Atomic classes means less CSS, which makes our page load faster. This is a good thing.

Custom tokens

Even the simplest web page needs some kind of overall look and feel, which might be as simple as a preferred font and color palette, or a full theme with customized components, predefined margin sizes and all the bells and whistles.

To avoid having to repeat yourself with your selected colors or sizes, Stitches lets you define custom tokens:

CSS Custom Tokens

Here we can see we have defined a couple of colors, primaryText and primaryBlue. Notice how these actually show up with autocompletion when we define the classes! This also works for the other kinds of tokens like sizes, radii and many more.

Themes

Stitches also provides an easy way to create themes with your existing tokens:

const darkTheme = css.theme({
  colors: {
    primaryBlue: '#191970',
    primaryText: '#E0E0E0',
  },
})

document.getElementById('app')!.innerHTML = `
<div class="${darkTheme} ${root}">
  <h1>Hello Stitches!</h1>
  <div class="${content}">Time to make some styles!</div>
</div>
`

Here we create a new class darkTheme, which will override the colors for our custom tokens, generated using CSS variables:

._initial_c_bcBPUO {
  color: var(--colors-primaryText);
}
._initial_bc_iPJCVe {
  background-color: var(--colors-primaryBlue);
}
:root {
  --colors-primaryBlue: #0198e1;
  --colors-primaryText: #404040;
}
/* darkTheme */
.theme-0 {
  --colors-primaryBlue: #191970;
  --colors-primaryText: #e0e0e0;
}

While Stitches does all these things behind the covers, the end result as a developer is very intuitive and easy to use!

@stitches/react

React is pretty popular, to say the least. To make it easier to build styleable, reusable components with React, there are several great styling libraries like Styled Components, Chakra UI and Material UI.

Stitches provides a simple alternative to these, and can be used either with only @stitches/core as shown above, or with @stitches/react for a more component-based approach.

Let's look at an example:

import { createStyled } from '@stitches/react'
import { render } from 'react-dom'

const { styled } = createStyled({
  tokens: {
    colors: {
      $primary: 'darkblue',
      $brightText: '#eee',
    },
    radii: {
      $rounded: '8px',
    },
    space: {
      $medium: '1rem',
    },
  },
})

const Button = styled('button', {
  backgroundColor: '$primary',
  color: '$brightText',
  borderRadius: '$rounded',
  padding: '$medium 2rem',
})

const App = () => (
  <main>
    <Button>Click me!</Button>
  </main>
)

render(<App />, document.getElementById('react'))

Here we create a styled config using some custom tokens for colors, padding and border radius. To make the usage of the tokens more obvious, we prefix them with $.

One cool thing to notice is that we can mix and match tokens with regular units, as in padding: '$medium 2rem'.

Once we have our config, we can very easily create styled versions of components, for example the native button DOM element.

Variants

To build a complete design system or component library, we probably want several variants of each component, for example a small, medium and big button. Thankfully, Stitches makes this very easy:

Component variants

Here we have defined three size variants, each with their custom padding and font size. The result is a custom Button component with a strongly typed property size that can be one of large, medium or small. You will even get an error if you try to set a size that doesn't exist!

Final words

Stitches is a fresh breath in the ever-growing ecosystem of CSS and React components. Personally I find it extremely pleasing to work with, and would recommend everyone to try it out!

To find out more, check out stitches.dev, or install it right now with npm install @stitches/core @stitches/react and start making your own performant, responsive design system today!

Read the next post

Read more outside the calendar

Bekk