Helpful UI: What We Learned Creating an Internal Standard for CSS
In 2015, Helpful Human had a number of front-end web projects being worked on by developers of varying backgrounds and experience. We quickly found ourselves tripping over one another’s work and determined that we needed to implement some standards if we were going to become more efficient and stay out of severe technical debt.
After reviewing several existing standards for CSS, we opted to take (what we felt were) the best parts of BEM, CSStyle and SMACSS, and generate our own internal standard. Shortly thereafter, we decided to extend on this standard with a framework for Stylus that we called, “Helpful UI”. Our library acted as a mixture of standard enforcement (via custom “tag” functions) and various mix-ins to hopefully speed up development.
How did it work out?
We created the standard to make it easier for all of our developers to understand another developer’s intent …but restricted ourselves with our naming conventions.
We created the standard to make it easier to onboard new developers …but had too many rules that only added complexity.
We created a custom framework with “tag” functions to enforce our standard …but it added extra efforts, keystrokes, compilation time and made debugging a nightmare. (Who needs the “Find” function anyway?)
We created a custom framework with a reset sheet and mix-ins to make development faster …no, wait, this actually worked out mostly ok. The main drawback here is that we added another dependency to our pipeline, preventing us from spinning up even the most basic projects quickly.
So, what are the takeaways?
First off, I’m still glad we went through the experience. It taught us a lot about our assumptions on tooling and how easily tooling can become more of a burden if you’re not careful. Trying to create a standard also taught us the importance of considering the potential consequences. Had we kept our standard simpler, it would have been much easier to onboard new developers and use day-to-day.
What’s next?
Helpful UI has more or less gone by the wayside for now and Helpful Human is in need of a new standard. Recently, I decided to take another stab at defining an updated standard for our team by expanding upon the aforementioned BEM. My reason for choosing BEM as the basis lies largely in its brevity and minimal set of selector types.
What are the newly proposed patterns?
The new standard for Helpful Human breaks down to 3 types of selectors, much like BEM. These are “Component”, “Element”, and “Trait”.
Components are the first selector type and act as a namespace for their related Elements and Traits. Components should be a noun that represents a single slice of visual functionality and are PascalCase’d with no dashes. Components can be nested in other components and can even alter child component behavior as needed.
Elements are the individual pieces that make up a component. They are always prefixed with their parent Component’s name followed by a dash. Both Components and Elements are written using PascalCase.
Traits act as an adjective or adverb on either a Component or Element. It is recommended that Traits are always compound classes that augment or extend the behavior of a Component or Element. You can immediately identify a Trait, as its written in camelCase.
What about the Helpful UI library?
It’s still floating around on our Github and exists in some of our older projects. Whether or not we’ll revisit it is currently up in the air. If we do, its purpose will be reworked to be entirely utilitarian — focusing on only including functionality that enhances our team’s ability to deliver while posing as little risk as possible to debugging.
How does this solve our problems?
- Aside from dashes and casing, we can name things however we need to name them, while avoiding namespace collision.
- Reading classes is easy and you can get a clear understanding of its purpose just by looking at it.
- Unlike our old standard that had 5 types of selectors, the new proposal only has 3. This makes it far easier to explain to whoever we need to work with.
- We are no longer reliant on a framework or tag functions to help enforce our standards. We can easily apply our standards in vanilla CSS and be just fine.
Final Thoughts
Though the first attempt at our own standard didn’t solve the problems we hoped it would, it did set us on the right path to figuring out what we actually needed. Many might see the abandonment of our original concept as a failure, but, given what we learned from our mistakes, I see it as a major victory on the road to creating better experiences for both the end user, and ourselves.