Introduction
Before now, many organizations relied heavily on libraries such as bootstrap and Material UI for building web interfaces.
But with the advent of improved tooling, many teams are rolling out their own design systems — Style guide and component libraries. Thus leading to the unprecedented rise in popularity of component based design system.
Component-based design system involves splitting our UI into isolated micro-components; based on a design constraint. This makes our UI more maintainable since each micro-component can easily be managed and extended.
Although, this is exciting, rolling out your own system can be very challenging.
However, libraries such as Tachynos — a functional CSS library and Styled system are very effective tools for this purpose.
In this article, we would be learning about Styled system; a utility first styling library that works in tandem with css-in-js libraries such as Styled-components or Emotion.
Let’s learn more about it in the next section.
Getting started with Styled System
Styled system is a collection of utility functions that adds styled props to our components. These styled props are synonymous to utility classes in Tailwind CSS.
Each styled function exposes a collection of styled props which are used to style our components based on values in a design system.
This enables us to work within the constraint of our design system leading to cleaner and more consistent code.
Also, out of the box, Styled system provides a rich API; that provides functions for most CSS properties. These functions provides a constrained set of props used to style our components.
However, we can create our design system as a theme object and provide it using a ThemeProvider component.
Let’s elaborate on these with some codes samples.
Note: style system requires a css-in-Js library. In this article, we are using Styled-components.
First, we create a reusable component. And add to it the needed styled functions as seen below:
In the code above we add the color utility to the Card component. This exposes the bg and color styled props to this component.
These can then be used to style the Card component as seen below:
Styled system is simply a collection of styled props provided by different styled functions such as shown in the table below:
Styled Functions and Exposed Styled Props
Color
- color, bg
Background
- backgroundImage, backgroundPosition, backgroundRepeat
Flex
- All flexbox properties e.g justifyContent, alignItems etc
Grid
- All CSS grid properties e.g gridGap, girdColumn, gridRow etc
Position
- zIndex, position, top, bottom, right, left
Shadow
- textShadow, boxShadow
A complete utility list can be found in the reference table.
In Styled system a styled function exposes a specific group of styled props. Thus enabling, us to create isolated reusable micro-components. Below are some examples:
- A Shadow component:
- A Header component
- A Flex container
- A Grid container
Also, we can create a single powerful component by using the compose utility. This allows us to add multiply styled functions to a component.
Let’s add more styled functions to our Card component with the compose utility.
kindly consider the code below:
Now we can use it together with our Header and Shadow micro-components as seen below:
Building our design system:
Styled system provides a theme object shaped based on the theme specification of system-ui.
The theme object is a general-purpose format for storing design system style values and scales. And It is not coupled with the style system implementation.
Also, the styled system theme object design pattern follows the idea of scales.
Scales enables us to defined custom values for different CSS styled properties in our design constrain. Examples of scales are typographic scales, e.g font-size, line-height etc, a color object, and a spacing scale for margin and padding.
Let’s elaborate on the above with some codes samples:
The theme object above contains different scales — as its properties.
Each scale has a key that corresponds to the CSS property they are used for. However, these keys follow a plural convention; hence, the keys: fontSizes, fontWeights, colors, borders, lineHeights, etc.
The radii key — which represents border-radius and the space key — which holds the scales for margin and padding are exceptions to this naming convention.
There are different ways to create scales but the common pattern is to use arrays for ordinal values such as the space scale — that is margin and padding and an object for colors as seen in our theme object.
We can use the values from our theme as seen below:
From the code above we see that styled system allows us to use bootstrap-like shorthand syntax such as p, mx, and my.
The styles above translates to this:
Although, the style system theme object follows the key-scale naming convention, it allows us to define the organization of the scales. E.g the theme object expects a colors object. However, we decide if this colors object is flat, deeply nested, or functionally generated based on user input. In our example above the colors object contains nested arrays which enables us to specify different shades of whites and blacks.
Also, the scale-based design pattern ensures that we create a consistent styling system and provides us with a shorthand syntax for responsive styles.
To see this in action, follow the steps below to setup a demo app:
- Clone the React-stater repository by running:
This react-stater app is bootstrapped using create-react-app. I have removed the unnecessary files. Also, I have added a theme.js file that contains the codes of our theme object above.
- Enter your project directory and install dependencies by running:
- Start the dev-server by running:
Once the dev-server starts, you can view the app at http://localhost:3000/.
- Now we can start creating micro-components. Create a components folder in the src folder and create the following files in it:
- Flex.js with the code below:
- Text.js with the code below:
We can now build our layout using these micro-components and apply the styles from our themes using the patterns discussed above.
- Our App.js should look like this:
Most of the code should look familiar. Styled system provides our theme to our micro-components by nesting them in the ThemeProvider from the css-in-js library in use — styled-components in this case.
Notice the usage of our theme’s color names such as success and info as our background color.
Also, notice we specified the fontSize using responsive styles.
Instead of manually writing media queries responsive styles is a powerful way of managing responsive typography and layout.
Try resizing the browser to see the responsive typography styles in action.
Play with code or get full code from this repository.
Conclusion
We can say that styled system brings Atomic CSS to css-in-js while allowing us to create micro-components, styled using our own design system.
Also, we can write plain CSS using the CSS module and create variants for micro-components such as Buttons or Cards using the variants API.
The main package is a composition of several smaller packages which can be installed independently.
Lastly, styled system is a low-level framework-agnostic utility first styling library. Consequently, it can be used with React, Angular, or Vue.
Popular libraries such as Rebass and Theme UI are implemented with styled system thus it has a fairly huge ecosystem.
This is currently my favourite tool for building UI and a must-try for every developer.