Introducing Cell Atoms & Molecules

Scalable API-Driven-Development with Sass

Edmund Reed
Valtech Design
5 min readDec 4, 2019

--

Cell is a library I have developed to help with styling UI components using Sass. This article will be a short introduction into a couple of concepts that (if you are familiar with Sass) should feel familiar. These concepts are called Cell Atoms and Cell Molecules.

Cell Atoms

A Cell Atom is a single CSS property that outputs two different values that will be applied to an element based on some passed context. In this case, context could mean things like the presence of certain modifiers/pseudo-states, or whether or not the element/some parent element is hovered etc. This is mostly useful when toggling properties based on some event or interaction.

An example might be using the display property to hide/show an element. Whether or not the value of the display property is none or something like block will depend on the context or condition in question. In plain Sass, this might look something like:

…which would show the element when it has the active class. If we wanted to show the element when a specific parent had the active class instead, this might look something like:

We can represent this example using some CSS-in-JS API, which might look something like:

API taken from the Lucid library

…here we can see how in the JavaScript example we just define one display property, with the value being dynamic. This value would be re-evaluated every time the context object changes, with the element being re-painted accordingly.

In the Sass example, given the cascading nature of CSS (and the lack of dynamism), we define multiple display properties in a cascading fashion, and let the battle of specificity determine the rest. As Sass has functions, we could think to circumvent this by creating a custom context function to mimic the CSS-in-JS behaviour, something like:

However, this could never work — this could only ever compile to a single CSS rule (using whatever value is evaluated at compile time). Sass could evaluate context('.someParent.active', block, none) just once before it is sent to the client, and hence only create a single CSS rule; whereas JavaScript could evaluate context.someParent.active ? 'block' : 'none' on the fly.

The best we could do would be having separate Mixins for each property of interest. This Mixin would be known as a Cell Atom. If using Using Cell and the display Atom, the above example could be reduced to:

…which as you can see is now very similar to the CSS-in-JS version, leaving us with less code that is just as readable. This could now, under-the-hood, output however many CSS properties in however many rules we like. The above code would be syntactic sugar for:

…and indeed, every instance of a Cell Atom would be represented under-the-hood in a similar fashion to the above (with the context that is passed to the Atom being forwarded down to the context Mixin).

This concept is useful for certain cases where specific contexts call for just a single CSS property to be modified, with the hide/show example being the most common use-case I could think of. If you needed to apply multiple CSS properties to an element based on some passed context/condition, you should use the context Mixin.

Of course, you may be thinking that having separate Mixins for every property is overkill, and you’d be right, given that there are, what, like 800 CSS properties? However most CSS properties shouldn’t be used this way — only properties that affect the layout/functionality (and even then, only when the single property controls a single behaviour, such as hide/show). As such, Cell currently just comes with Atoms for display, position and visibility properties.

Cell Molecules

A Cell Molecule is essentially just a regular Sass Mixin that outputs one or more CSS rules based on some passed context/condition to achieve a single specific outcome. The goal is to abstract recurring patterns into composable Mixins, improving the clarity and maintainability of your Sass codebase. No CSS properties or values are passed when using (calling) Cell Molecules, unlike Cell Atoms.

This is quite similar in principle to the Bourbon Sass library (the difference being that a Cell Molecule takes a context input and will output multiple context-driven rules). Taking the previous hide/show example, this could be abstracted into a Cell Molecule and used like so:

…essentially telling Cell “Hide this element unless the passed condition is met, in which case show it”. The required functionality (i.e. applying none or block values) would he handled under-the-hood by the hypothetical show Mixin. The above would be syntactic sugar for:

…equivalent (in principle) to this earlier vanilla Sass example that we saw:

There is no real hard-set way to qualify some CSS-set as a Cell Molecule; it can be any abstract and recurring pattern that requires a default state that changes based on some context.

Cell Molecules are just a philosophy/concept; there is currently no Cell Molecules library or anything

Visit the Cell Wiki for more information regarding the Cell library

Conclusion

Whilst Cell Atoms and Molecules serve different purposes, the ultimate aim of both is to keep styles more composable. By using Cell and identifying the Atoms and Molecules within your codebase (or predicting/anticipating them if creating a new project/feature) you can ensure that your codebase is more concise and semantic, and less riddled with various CSS properties that will no doubt be slapped on in no real order.

Taking a look at the various examples from this article side-by-side we can get a better understanding of the motivations behind these concepts (remember that all these examples achieve the same thing):

In many cases you would need to consider whether there is a need to create a Molecule for something — in the above example where the Molecule only affects a single CSS property it may be more pragmatic to stick with using the display Atom.

--

--

Edmund Reed
Valtech Design

Design Systems Architect 🎨 UI•UX designer & developer 💻 I take front-end thought experiments too far 🧪 @valtech 💙