Storybook-HTML Tutorial – Part 4 – Handlebar Template Refactoring to Atomic Design

Previous Post

Some months now a year and some months passed since I have published the third part about Storybook-HTML with Handlbar Template Engine configuration. During this time, the very active Storybook Community released already the 5th 6th version. However, the new look and feel is a little bit different from version 3 to 5, but the core functionality stayed the same. Therefore, I think my tutorial content holds still some value, might helpful for some and the others out there.

I will continue the Landing Page tutorial by Jonas Duri and in this fourth part, we will refactor our Handlebar Templates to an Atomic Design structure. 😉

Small introduction into Atomic Design

Design and Developing User Interfaces is pretty complex tast. This kind of complexity can be reduced via a divide and conquer approach. According to Gall’s Law a break down to more simplistic system is the direction to go. As a result, we specify subproblems or subtask, which can be easily isolated, developed and tested. In a field of User Interface Engineering, that approach is also called Isolated Component Driven Development, see the talk by Norbert de Langen. Storybook provides the digital environment, while the Atomic Design methodology can help interdisciplinary teams to assign, define, specify such simple systems, subtasks, and subproblems. Furthermore, it describes the relationship of the component to the others.

Bits and pieces can be more than the sum of its parts. Various combinations of Atoms, Molecules, Organisms can build very different User Experiences. Image adapted from “Multiscreen UX Design” by Wolfram Nagel and also the source Chapter 4 of the Atomic Design Book by Brad Frost

The challenge for developers, designer, as well as for product managers is to define such bits and pieces. The Atomic Design goes from an abstract Atomic point of view to much more composed and concrete Page Design. If you have music background, then checkout the wonderful explanation of the Atomic Design method by Audrey Hacq based on classic music principles as metaphor. In the end, we are talking about hierarchical composite relationship between the user interfaces.

An Instagram Page translated into an Atomic Design structure. Image Source is the Chapter 2 of Atomic Design by Brad Frost

The Atomic Design structure enables interdisciplinary teams to find a very understandable ubiquitous language and boundaries specifications for User Interface discussions, like the more extensive Domain Driven Design method did for enterprise software development. Additionally, it holds some further benefits for the Designer and Developer collaboration (Don’t forget Conways Law ;-). If you are new to this topic please, then please check out Brad Frost’s book Atomic Design in advance. His website and his talks are very well done in my opinion.

Every methodology has its critics, which brings me to next section of Atomic Design issues.

Critics and Problems with Atomic Design

Some people ran into problems with Atomic Design methodology. Some argue that Atomic Design is a messy approach of describing the UI relationships. Others seemed to apply all(!) their User Interface code to an Atomic Design and pattern library approach in one step and failed. Some developers tried to to implement literally the hierarchical structure of Atomic Design in their code and failed.

In my opinion, these problems are all valid in relation with Atomic Design. In my experience, if you apply an approach to much – I would call it dogmatic – then even Atomic Design might cause your troubles. Therefore:

Don’t Take Atomic Design too literally

I had very good experiences with the Atomic Design, while I had requirements meetings with my interdisciplinary team and other stakeholders (management). It is a great interdisciplinary communication tool, very similar to the definition of an ubiquitous language. From a technical point of view, the code structure of your User Interfaces might differ from the Atomic Design structure. We know such specification differences from the Domain Driven Design (english / deutsch) field. Domain Driven Design is in that context pretty interesting for developers, because it distinguishes events in business logic events (e.g. a new order event) and technical events (e.g. JavaScript onLoad event). Such events should never be mixed up with each other.

Brad Frost talks about the trap of mixing up code structure with design structure. I highly recommend his talk The Technical Side of Design Systems

An additional problem will appear, if the developers mix up general UI Patterns with Product based User interfaces. Please have look, at the picture above. Atoms To Organisms might become a general UI Component in your pattern lab one day. Templates and Pages are based strongly on the context of the website or application (Reuse might happen rarely). Such strong context oriented specifications reminded me on the bounded context of DDD. Keep in eye on your code, that you separate such different context areas from each other (a very nice DDD example based on a ToDo App). In my opinion, Domain Driven Design might a way to heavy to apply to your project, but it can provide you an idea how to understand the principles of Atomic Design better. Atomic Design provided for me a specification structure and an ubiquitous language of User Interface, like DDD does for Enterprise Software Development projects.

UI Patterns != Components != HTML Templates

Brad Frost kinda advocates Atomic Design pretty often with their tooling Pattern Lab. Maybe due the naming of their Atomic Design toolkit people tend to mix up their UI Patterns with their UI Components. Nathan Curtis wrote a very nice article why this mix up of UI patterns with Components is problematic. Let’s recap the definition of a pattern:

– Pattern is a repeated decorative design
– Pattern is an arrangement or design regularly found in comparable objects.

see also

If you have an UI element or a HTML Code piece, which appears only one or two times, then it isn’t a pattern! It doesn’t belong to your reusable code of UI patterns. Take care of your Design principles, patterns, and component relationship. One-time components can be placed into an app-specific folder. You – as developer – are allowed to build your own code and folder structure based on your application and implementation needs.

Reusable code plus its UI Components are very difficult to produce in an appropriate manner. It needs usually several feedback loops until they fulfill your needs.

It might be an misunderstanding that Atomic Design should remove that complexity for you. That is completely impossible, Atomic Design can only help to bring that complex chaos in an appropriate order. In the best case scenario, it orders and structures your essential complexity and protects you from the pitfalls of accidental complexity.

One of the easiest things to get wrong is to create too many of these components, too early. It is tempting to create a Foundation Framework, with all of the common visuals that will be needed across all applications. However, experience tells us that it’s difficult, if not impossible, to guess what the components’ APIs should be before you have real-world usage of them, which results in a lot of churn in the early life of a component.

Quote about Shared Component Libraries by Cam Jackson in Micro Frontends Article

Which brings me to another mentioned shortcoming of Atomic Design. The interaction with Atoms, Molecules and Organisms become messy after a while. That problems reminds me on balance of API Design.

Striving for a Minimal API Surface

The Design of programmatic interface is a pretty complex and difficult process. Many developers are motivated to deliver high quality code from the beginning, even specifications are incomplete . The result is usually a pretty over engineered UI code, which should meet all edge cases and becomes daunting to refactor. The reality shows more is less in the beginning. My fetish and alter ego of rational thinking prevented me to accept this fact for years (see also re-usability fallacy). Principles around designing minimal API surfaces and Yagni felt pretty weird (and kinda esoteric) for me, but nowadays I enjoy these principles. The trap of over-engineering happens less and less for me. My code is more dirty in the beginning, becomes with its minor refactoring iterations more flexible for future changes. Those two statements below can help you to ease into Atomic Design.

It is completely ok to repeat yourself in code a few times. Every new deveration of an User Interface helps you to determine the abstraction more accurate. Check also if your are developing for a private (app-specific context) or standard context (corporate design system). Feedback loops and code refactorings shouldn’t make you feel bad. To write and implement complete specifications are very difficult. One strategy, could be annotations. New HTML templates or UI components can be annotated with a “Work in progress” badge as warning for the other team members, that the specification is still open for feedback and extension. Furthermore, developers know that the code can ran into errors. After a certain level of quality the component can enter a version management. Fresh and new code can be incrementally added to your projects. During this progress do frequent code reviews and get feedback as much as possible.

Furthermore, try to avoid inheritance of your components. You should compose and evaluate your patterns and namings very carefully. Following principles, like SOLID can help to protect you against running quickly into some common pitfalls. Please accept, that UI Engineering is not easy, it is actually a pretty complex task. Further highly recommended resources are:

Refactoring to Atomic Design

Your starting point might be a clean fresh web project or an already existing web project. For the last one, I highly recommend to do am interface inventory before starting refactoring. After some Atomic Design oriented Design-To-Code transformation, I figured out that the top2down approach worked better for my projects. During my first projects, I experimented also with direct development of button atoms and other form inputs… I kinda failed badly with my structure and had to learn this lesson the hard way.

Since you are building reusable UI elements and code for a middle to long-term context. Please keep in mind, that a wrong abstraction can harm more than copy&paste code. You are supposed to find and assign an abstraction only for your repetitive patterns! Please check if patterns are more app specific or if they are used in a wider context (and must be e.g. themable). For all other things you could run very fast into the trap of technical debt due chosen inappropriate abstractions too early. Timing plays always a bigger role than I am conceding. (Maybe Defensive Coding Styles and Low Tech idealism can be the rescue)

Let’s start code refactoring

For this tutorial I keep ongoing to top2down approach for the coding examples. All the code is located within the component folder. The numeric prefixes are for a better ordered listing.

All UI templates can be very easily created. It follows mostly the structure. You can use markdown files for component documentation (it might work with other styleguide systems too), then you can add json files for the data model (similar to mock data). At the end you have the template file itself. At the moment, the file format is html, but we will change it later to handlebars.js templates. Some code snippet as an example.

Refactoring to Pages

Since we have only one site, which makes it pretty straightforward us.

Refactoring templates to organisms

However, I followed the above principles an moved the files into a very basic Atomic Design structure. You can see it in that commit 4d7d8bd.

Unfortunately, the external loaded CSS Styles of Font Awesome and the IBM Font styles weren’t loaded into storybook. I had to import these files globally at the .storybook folder withing the preview-head.html file. The content of the file can be observed here in commit fc998b7.

If I would really building a Landing Page, then I would stop here with the abstraction. The API design of an atomic and molecular UI component can be pretty complicated and complex process (see the Minimal Surface API Area talk) . A Landing Page with a few repetitive “Icon-” and “Text” Links” is usually not enough for defining a atomic element.

The Molecule structure

Nevermind, I will split those 3 handlebar organisms elements into molecule and atomic elements only for storybook demonstrating purposes.

The refactoring of molecule templates is not so much of code refactoring. The storybook stories are looking like this:

An example of a refactored Handlebar template looks like this:

The end result in Storybook reveals a problem with our CSS Styles. Currently, our (S)CSS is strongly coupled on our HTML structure. Such a tight coupling of structure and style can be easily identified by a Styleguide Driven Development methodology.

Tight Coupling of CSS on HTML structure is causing styling problems

Now, you might say: “Stop Florian, I think that isn’t a problem of my code. It is more a problem of your weird development methodology! Only your tool is causing the problem!” In the case of a one-pager website, you might be right, but if you really want to reuse the UI elements in other projects, than you will run into limitations with this CSS Code very fast. Exactly due such tight coupling issues of HTML with CSS, I encourage you learn at least on these principles BEM, SMACCS, OOCSS, Atomic CSS. For bigger projects the architectural conventions like ITCSS were introduced to the web community. You can choose whatever you like, but please stick to one of it and don’t mix incompatible conventions with each other.

For now, I just will apply some minimal BEM conventions to the (S)CSS file. If you want to start writing cleaner CSS, check these two great websites MaintainableCSS and CSS Guidelines. If you are more a talk person, then Andy Bell is a great speaker in that context. The final code for the molecules refactoring is committed into af0d12f and 1a563b4.

The Atomic Elements structure

After the molecules refactoring, i created the links as atomic elements and added some “Knobs” Interaction to it. The code looks like this and feel free to play around with it.

Atomic Elements Playground on Storybook

Dealing with Layout and Page Templates within Webpack

Within the code you can observe the Context Object as argument for the Handlebar Template. The Context Object takes over the role as a data model, which the Handlebar Template Renderer injects into the HTML code (see commit b5b63fe). If you want to include a complete external json file for the page data, then we have to create a (nested) json file and connect it with our general Webpack Buildscript:

After extending our webpack configuration, please open our Landingpage and see how you can access the page data for our Handlebar Templates:

The commands “npm run start“, “npm run build“, and “npm run storybook” still work as supposed to do. For the ending, I will do some template code clean ups, which you can explore in these commits 1f0bfc7, fcaee1f. 468d9ca.

Now we are more or less done with our refactoring. I am convinced that active practice strengthen your learnings, therefore feel free to split and compose the newsletter section in atoms and molecule templates. For some more ambitious readers, I suggest to experiment with Design Tokens and apply some composite CSS layout practices described by Heydon Pickering.

If you have questions or run into problem, then please leave a comment below. I will try my best to help.

Previous Post Share Post :

More Posts