Why We Gave Up on the Idea of Using Styled System to Create Components

Alex
Quarkly
Published in
4 min readJun 16, 2020

Hi everyone! My name is Alex. I’m one of the founders and lead developer at Quarkly. In this post, I’d like to share with you how the concept of atomic CSS, which we follow, together with the disadvantages of styled-system functionality (and rebass in particular) inspired us to create our own tool that we call Atomize.

A Few Words About Us

Our Quarkly project is a mix of a graphic editor (like Figma and Sketch) and website builder (similar to Webflow), complemented by features of traditional IDE. We’ll be sure to elaborate on Quarkly in a separate post, as there is plenty to tell and show, but today we’ll focus on the details of the Atomize tool.

Atomize is the heart of the whole project, as it allows us to solve tasks that would be difficult or even impossible to handle using styled-system and rebass. At the very least, the latter solution is much less elegant.

If you don’t have time to read the entire post now, check out a brief description of Atomize on our GitHub.

How It All Started

When we got down to developing this tool, our team’s task was to give users the opportunity to code on two components, but without the need to have a separate CSS file. This was to keep the code as minimalistic as possible while retaining all CSS features in contrast to inline styles.

The task was far from ground-breaking and, at first sight, could be easily solved with the help of styled-system (and rebass). But its functionality turned out to be limited for us. Or rather, we ran into the following problems:

  • inconvenient breakpoints
  • no option to write styles for hover, focus, and other behaviors
  • mechanism for working with themes wasn’t as flexible as we needed

Briefly About Atomize

Here are the key Atomize features:

  • option to use variables from the theme in composite CSS properties
  • support for hover and any other pseudo-classes
  • short aliases for each property (like in emmet)
  • opportunity to set styles for a specific breakpoint, all while keeping the markup readable
  • minimalistic interface

That being said, Atomize is intended for two main purposes:

  • creation of components that support atomic CSS and themes
  • creation of widgets for the interactive editing in the Quarkly project

Atomize. A User Manual

Before you start working with Atomize, you need to set up dependencies:

Atomize serves as a wrapper around a styled-component and has a similar API. Just call the method using the name of the required element:

As a result, we get the React component that can take any CSS in the form of properties.

To make it easier to use, we developed the system of alias properties. For example, bgc === backgroundColor.

To see the full list of properties and aliases, follow this link.

Plus, we added the mechanism of inheritance in React:

Themes

This, I think, should be explained in more detail.

Quarkly themes are based on CSS variables. The key feature of Quarkly themes is that variables from themes can be reused both in props and themes. You don’t need to use additional abstractions, like template functions, and no additional editing is needed by the user.

To use variables from a theme, just describe the property in the theme and call this property using the prefix “ — “.

The variables can be used both in JSX:

(The color #04080C is available through the — colors-dark property)

And in the theme itself:

(We reused a variable from the colors by including it in the borders theme)

The shorter syntax is used for colors in the JSX markup:

Themes have breakpoints for working with media expressions.

Any property can be prefixed with a breakpoint key name.

You can find the source code here.

Effects

The main difference between Atomize and the styled system is the “effects”.

What are they and why do you need them?

Well, imagine you create a Button component, change its color and border and then… you realize you don’t know how to assign styles to hover, focus, etc. This is where effects come to the rescue.

When creating a component, just transfer an object with the configuration:

The key is the prefix in the name of the property, and the value is a CSS selector. This is the same way we implemented pseudo-classes.

Now, if you specify the hover prefix for any CSS property, it will be applied to a certain effect. For example, when you mouse over it:

You can also combine effects with media expressions:

A Few Examples

Let’s build several interesting components to illustrate the features I’ve described above.

Here are two examples:

Everybody loves Pokémon, don’t they? :)

Wait! There’s More

The second purpose of Atomize, as I mentioned above, is to create widgets in Quarkly based on custom React components.

All you have to do is wrap your component in Atomize and describe its configuration so that Quarkly can understand which properties can be interactively edited:

The configuration fields for the component look like this:

  • effects — defines browser pseudo-classes (hover, focus, etc.)
  • description — component description that will appear when you mouse over its name
  • propInfo — configuration of controls that will be displayed on the right panel (Props tab)

How to specify the props to be displayed on the right panel (Props tab):

Possible control options:

  • input
  • select
  • color
  • font
  • shadow
  • transition
  • transform
  • filter
  • background
  • checkbox-icon
  • radio-icon
  • radio-group
  • checkbox

One more example, where we’ve added our custom component to the system and can now edit it interactively:

Yay! You’ve made it to the end :) Thanks for reading!

--

--

Alex
Quarkly
Editor for

Hi, I’m Alex — a co-founder and a chief developer at Quarkly.io 🖐