Front end strategy for products that scale

When I was originally introduced to css atomic code systems in 2013 and saw functional classes, my initial thoughts were:

Why would a sane human being use a lot of inline meaningless css class names to represent one component, when we can use one class name which has a meaning?

<div class="Bfc M-10">
    <a href="#" class="Fl-start Mend-10">
        <img src="thierry.jpg" alt="me" width="40" />
    </a>
    <div class="Bfc Fz-s">
        @thierrykoblentz 14 minutes ago
    </div>
</div>

Example: Bfc M-10 Fz-s Fl-start Mend-10
Source: Smashing magazine

Fast forward to 2016. I think I have figured out the answer. Now it makes perfect sense that in 2013 I simply wasn’t ready for this. The answer can be summed up into one word which happens to be the magic word of today’s startup world, and the word is “scale”.

The old school way

When writing css the traditional way, as we all learned it, for each new web site section or product feature that we design we write new css code. As the time goes by web sites and products grow, number and complexity of features increase, css piles up to the point it becomes unmanageable. This is where issues of scale culminate. At this point we need to figure out how to refactor css code in order to create a new system which will solve current scaling issues, prevent them from happening again in the future and set balance on a new level.

Today is exciting time to be in design and front end industry because technology offers opportunities to solve scaling issues in different ways and by using different approaches which can be combined in a way which creates balance and harmony.

Harry Roberts writes intelligent tips on writing css, advises people to avoid css selector nesting as much as possible and as a solution to scaling issues proposes Inuitcss, a system based on BEM namespace. This system offers consistency, but doesn’t solve problem of writing new css code for new web site sections or product features.

While I think that having base objects, components and elements for a front end project is a good thing, I personally feel that this approach would benefit from combining with utility classes which allow rapid prototyping or designing in browser without writing new css code. That is the gap which can be filled in with atomic systems.

Atomic

When we use a well rounded and documented system of functional aka utility classes we end up stop writing new css code and designing in html by adding classes to html elements. Now when we design new product feature we use existing utility classes to code it. This way we try to solve issues of scaling by not writing css which is very legitimate.

But, there is a flip side to this coin. By not writing new css code and inlining classes into html code we are moving code complexity from css to html. The new question arises: What is easier to manage in the long run, html or css? There is no straightforward answer, at least in my head.

Adam Morse created a css system of functional classes called Tachyons which allows us to design in browser. Fast. It is well documented with examples and demos, and hopefully here to stay.

Most of the front end frameworks have their own systems of utility classes that allow us to modify some properties of our project components. The most beautiful thing about Tachyons is that it allows us to modify all properties of any project component we might have in an organized fashion.

Merging BEM and functional worlds

Based on experience in coding web sites and web applications I came to a conclusion that combining BEM and functional css is doable and if used wisely these two systems don’t exclude, but complement each other.

For example, it is useful to initially set up BEM style objects and components for standard things such as typography scale, buttons, alerts, icons, lists etc. But as the project grows instead of modifying components with countless modifiers it’s useful to have utility classes which allow us to modify components on the fly without writing new css.

If we have a button component like below:

<a class="c-btn" href="#">Button</a>

and we decide that we need a button with large padding, we have the option to use BEM logic and extend button by adding modifier and write new css like this:

<a class="c-btn c-btn--lg" href="#">Button</a>
.c-btn--lg{
	padding-left: 2rem;
	padding-right: 2rem;
}

or we have the option to use functional css logic and apply global utility classes:

<a class="c-btn u-pl2 u-pr2" href="#">Button</a>
.u-pl2{
	padding-left: 2rem;
}

.u-pr2{
	padding-right: 2rem;
}

In BEM case we wrote css modifier which applies only to button component and we have cleaner html code.

In functional css case we reused global spacing utility classes which are not meant to be used exclusively with button component, but can be utilized across the entire project.

Coding products that scale in the real world

Facing coding of web products in the real world means not only setting up css framework, but accomplishing a set of startup goals, one of them is usually to set up a system that allows:

  • Scaling user interface in terms of making it easy to add new features and keep visual consistency
  • Scaling and optimizing css performance and modularity in terms of allowing developers to reuse, document and keep the code clean.
  • Scaling number of people, which usually means having a way to easily and quickly onboard new developers.

Startups usually need to test their ideas and products as fast as possible, so it is a good idea to use well known front end framework as a base. One of the most popular is Bootstrap. It is often accused of not being front end framework but a UI toolkit and that all the projects done in bootstrap look the same. These things stand if we use bootstrap as is, but if we customize it from the level of variables and use only components which are needed for our project, we will have something that can be called css framework which will allow us to onboard new people to the team quickly because of its familiarity. Bootstrap offers a set of basic objects and components which can be set up and customized quickly. It also has utility classes, but unfortunately these utilities offer customizing only some of the components sometimes.

To enable myself to rapidly prototype in browser I used to write custom utility classes in order to extend bootstrap. They worked well for me but not necessarily for others. I wrote these classes as I needed them. Each time I had to write documentation for them as well and to clarify to other team members what they were doing.

Tachyons arrived as a perfect companion to fill in this gap. I look at it as a system of utility classes which is consistent, extendable and well documented.

Of course, some work is required in order to customize Tachyons in a way it can be used as a complement to bootstrap.

One example is type scale. I prefer to define font sizes and spacing as bootstrap variables and then use these variables in tachyons:

_type-scale.scss

.u-f1 { font-size: $font-size-h1; }
.u-f2 { font-size: $font-size-h2; }
.u-f3 { font-size: $font-size-h3; }
.u-f4 { font-size: $font-size-lg; }
.u-f5 { font-size: $font-size-base; }
.u-f6 { font-size: $font-size-sm; }
.u-f7 { font-size: $font-size-xs; }

Breakpoints are second example. I’m very happy with bootstrap convention of marking screen and component sizes which is xs, sm, md, xl and xxl, and I tried to reuse it in Tachyons utilities, like this:

_text-transform.scss

.u-ttc { text-transform: capitalize; }
.u-ttl { text-transform: lowercase; }
.u-ttu { text-transform: uppercase; }
.u-ttn { text-transform: none; }

@include media-breakpoint-only(xs) {
  .u-ttc-xs { text-transform: capitalize; }
  .u-ttl-xs { text-transform: lowercase; }
  .u-ttu-xs { text-transform: uppercase; }
  .u-ttn-xs { text-transform: none; }
}

@include media-breakpoint-only(sm) { }
@include media-breakpoint-only(md) { }
@include media-breakpoint-only(lg) { }
@include media-breakpoint-only(xl) { }

At the end of the day we have a Front end coding system that combines standard bootstrap objects and components with Tachyons functional classes. Ideally this will allow us to take the best of both worlds. On one hand to have framework which gives us standard reusable components, and on the other hand to have ability to infinitely customize those components and design new ones without writing new css.

Conclusion

I believe there are more than a few people who combine component based css with functional based css when coding web applications. What we still need is a framework that is going to connect the two worlds out of the box.

What I have written above are mostly ramblings between the left and right hemisphere of my brain which are based on experience, other people’s work and common sense.

I fear the most from the last one. What is common sense to me does not necessarily translate to other people. If I’ve learned something from code, it is that if you do something in a very unique way you are either genius or a complete idiot. If we apply probability law on that statement, chances are much higher in favor of the second one.

Posted by Emil Milanov

Interface designer based in Novi Sad, Serbia. Running independent interface design studio at nlight.co and helping startups convert to product companies.

Emil Milanov