• Status: accepted
  • Deciders: devs
  • Date: 2020-05-26

Context and Problem Statement

We're building websites and web applications that share a common design system with reusable components. How do we write CSS styles in a way that is performant and safe?

Decision Drivers

  • Should be performant, with code splitting, caching and minimal runtime overhead.
  • Needs to have easy access to our design system constants. These should optimally be shared with JS logic.
  • Should be type-safe to catch issues when refactoring.
  • Reusable components should be closed, not accepting arbitrary styles/classes.
  • We want a pattern for responsive props with atomic layout components.

Considered Options

Decision Outcome

Chosen option: Treat, because it combines the best of both worlds from CSS-in-JS and CSS modules.
We'll create shared components that have responsive props, but are otherwise closed for modifications. Theme variables are defined in a shared library with TypeScript.
// Good:
<Box padding"small" />
<Box padding={{xs: 'small', md: 'medium'}} />
<Input large />
<Text preset="heading3" as="p" />
// Bad:
<Box className={customLayout} />
<Input style={{ height: 50, padding: 16 }} />
<Text className={styles.heading} />

Positive Consequences

  • Treat is statically extracted at build time, so it has minimal runtime.
  • Styles load in parallel with JS, also when code splitting.
  • Styles are written in TypeScript which gives us type safety when referring to shared variables, styles and helpers.
  • Styles are in special files, separate from markup and components giving us clear separation with good visibility into the rendered markup.
  • We can pull in responsive layout component patterns from Braid, which gives us a good base to lay out components and pages.

Negative Consequences

  • We are choosing a pretty new framework, so it may 1) have bugs or issues, 2) be an obstacle for new developers or 3) be discontinued.
  • When we're generating responsive styles at build time we need to be mindful at how many variations we allow (eg media queries, columns, whitespace), since they can easily bloat our CSS with unused styles.

Pros and Cons of other Options

CSS Modules with SASS/PostCSS

  • Good, because it builds on top of standard CSS syntax which everyone knows.
  • Good, because it has no runtime.
  • Good, because it is separate from markup.
  • Bad, because it is messy to generate advanced styles in a CSS-based language.
  • Bad, because it's not type safe.

Styled Components

  • Good, because it's the industry leader in CSS-in-JS.
  • Good, because it allows rendering pages with no redundant styles.
  • Good, because it has excellent developer experience, making it easy to implement dynamic styles based on theme/props.
  • Bad, because it's runtime may significantly affect site performance.
  • Bad, because it hides the markup which may cause accessibility issues.
Last modified 1yr ago