How to build your CSS for success

Dávid Kocsis
Emarsys Craftlab
Published in
8 min readNov 18, 2020

--

When I joined the company a couple of years ago, the UI team was finishing a redesign process of our product. I was impressed by how they managed to make it happen on this enormous product in a relatively short time. I knew for sure that there were no rules, no guidelines, no conventions, nothing whatsoever before the makeover. It was similar to the world of Mad Max.
Years passed by and we’ve already finished our second redesign on a product thrice as big by now in almost the same amount of time.

So, after four years and two redesigns later, I want to share my findings on writing CSS that lasts and functions as a guideline for any of your future brand changes as well.

THE TEAM

One of the most important things you need is a dedicated group of people who share the same passion, vision, and knowledge to build up a system from the ground up. According to my previous experiences, CSS is usually a public and shared resource between multiple teams, but I’ve rarely seen any of them work on a large scale.

The majority of developers have some experience with style sheets, but only a small portion of them actually care about it and don’t consider it as a pain in the rear. I know full-stack teams are looking good on paper, but not dedicating people is the very thing that can make life so much harder later on.

Writing a good CSS is hard and letting anyone participate in the process will raise serious problems; there will be differences in solutions, teams will not be sure whether a styling for an element or a component exists or not, a collision between selectors, etc.
Assigning one specific team is going to solve all the above problems and more. It will require a lot of effort and hard work in the beginning, but as time passes, it will all pay off.

I would always recommend forming a team early in the project just for the planning of site build and styling. It’s a crucial step to take and as fundamental as graphics design or database architecture.

Our team is called Design System and we have four developers, two designers, and a project manager. However, I am sure that it can also work on a smaller scale.

CENTRALIZATION

First of all, you need some kind of storage for all your resources and you should also create a project for it where you can track changes, receive bug reports and feature requests. That’s how you can make sure that everything in the codebase is there for a reason, so there won’t be any confusion around them. It’s similar to a zen garden.

Centralization shouldn’t just happen inside the project, but in the organization as well. As I mentioned above, there should be a dedicated team behind the scenes and no changes should be made without their approval.

Moreover, it will lead to easier resource sharing. For example, you can utilize variables in the whole project and change them whenever you want without leaving the repository once. Being able to see everything at once can help you avoid duplications or inconsistencies and makes decision making simpler. In later stages of the project it will consume a lot more time and effort to build up this kind of system, so make sure to set it up as early as possible.

We have a repository called ui-framework-service where we store all the CSS and JS files, icons and guidelines. We also provide the opportunity to other teams to contribute by creating a pull request that we must review before merging.

METHODOLOGY

Have you ever heard of specificity? If you haven’t, read more of it as things can go really wild from here on.

Specificity means how strong a CSS selector is. You don’t want strong selectors because they are really hard to override and when you try to make a stronger rule, there is a big chance your code becomes just harder and harder to understand as time passes.

If you want to represent the strength of an element in numbers, use the method below:

Specificity calculator at https://specificity.keegan.st/

However, in reality what you really don’t want is variable specificity across the project. First, let me show you a really bad example:

You have the below HTML:<div class="profile">
<img class="avatar">
<div class="name">John Doe</div>
<a href="...">Go to profile</a>
</div>
A CSS for it would be:.profile { ... } // Specificity: 0, 0, 1, 0
.profile .avatar { ... } // Specificity: 0, 0, 2, 0
.profile .name { ... } // Specificity: 0, 0, 2, 0
.profile a { ... } // Specificity: 0, 0, 1, 1

The problem with the code above is that using a .profile class before every element to namespace them won’t help equalize our specificity and pushes the baseline even higher. Besides, you have three different selector strength.

In case another team in the company wants .profile to look different in their application’s context, but doesn’t let the UI team know, can lead to major problems. They don’t care about generating CSS only to solve this matter, so they are going to use inline styles as an easy solution. Then, a year has passed and they’ve already done it on several occasions, so you have basically two choices; change the code everywhere or create a stricter rule than the inline style. Unfortunately, in your stylesheet the only solution you have is to use the code below:

HTML:<div class="profile" style="background: red;"> // 1, 0, 0, 0
<img class="avatar">
<div class="name" style="color: red;">John Doe</div>
<a href="...">Go to profile</a>
</div>
CSS:.profile {
background: green !important; // 1, 0, 0, 1, 0
}
.profile .name {
color: green !important; // 1, 0, 0, 2, 0
}

You had to make it !important to beat the specificity of an inline style. That’s why centralization or proper communication is a critical factor here.

Using BEM or some other methodology will make your team’s life easier.

Now, let me show you a good example using BEM methodology:

You have the same HTML structure:<div class="profile">
<img class="profile__avatar">
<div class="profile__name">John Doe</div>
<a href="..." class="profile__link">Go to profile</a>
</div>
CSS:.profile { ... } // 0, 0, 1, 0
.profile__avatar { ... } // 0, 0, 1, 0
.profile__name { ... } // 0, 0, 1, 0
.profile__link { ... } // 0, 0, 1, 0

As you can see, you have been able to keep the namespacing along with selectors of the same strength.

If another team wants to change something, consider giving them a modifier class for their use case.

<div class="profile profile--context">
<img class="profile__avatar">
<div class="profile__name profile__name--context">John Doe</div>
<a href="..." class="profile__link">Go to profile</a>
</div>
CSS:.profile--context { ... } // 0, 0, 1, 0
.profile__name--context { ... } // 0, 0, 1, 0

So here we go, the same functionality in a more CSS-friendly way.

To sum it up, it doesn’t matter what you use until it keeps things straightforward and uniformizes specificity.

COMMUNICATION

In the beginning, you will be pretty sceptical, believe me I was, too. For me, it felt like we had day-long meetings without doing any “real” work.

However, it turned out that I was wrong. Coding is the easy part most of the time, it gets way harder when you have to do the planning and communicate regarding what you want to do or what changes you have made.

If you have a design system and want to change something, then it changes everywhere, so there is a possibility of breaking something for another team without them knowing what really happened to their page. It’s an extra round for the issue to land at your team and it also means wasted time. So, find a way to inform your colleagues about these kind of changes. It can be a simple e-mail like “We gonna change our input fields’ size, please report any issues regarding this to us.” or a public changelog, just make it easy enough to find.

Another example is that you want to create a modal window because the UX team hates native JS alerts. You should always start with planning, collecting use cases and speaking with other teams/developers that you are going to create something for them to make use of.

It’s very important that other teams also tell if they want to make changes related to the modal window’s styling or structure because every unspoken word leads to confusion and bugs. This kind of communication also needs a channel or a platform. Talking about us, it’s mostly happening on Slack, and after we decided on if it’s a valid feature request or bug, we always make a task from it on Jira, so everyone can track its status.

Most of the time you are collecting feedback from customers, but don’t forget about the developers, either. If you are working on a design system then it’s really important to listen or ask questions from other developers, because they are the ones who will use your framework. You can get a lot of feedback on a simple meeting or by collaborating with any team that is implementing interfaces. You are doing this to reduce the time needed to make an application and don’t forget that time also means money.

COMPONENTS

I’m pretty sure you’ve already met this term. They are similar LEGOs. You can build a lot of awesome things by using them.

Some of our components

If an HTML structure with the same styling appears in multiple places, you should always consider making a component from it. Reusing code inside the project is an efficient way to keep your codebase clean. The most common components are buttons, form elements and cards.

Furthermore, it’s essential to document them to let all the developers and designers know what are their possibilities and what they can be built from.

Currently, there are around a hundred CSS components in our framework and we came to the point where you need a really good reason if you want to ask for a new one.

The Emarsys Design System landing page

FINAL WORDS

As you can see, building a good CSS is not just about knowing the difference between flex and grid display. Those are things that you can always iterate later on. Writing a successful CSS starts with a team that creates a system, communicates it properly, collects feedback and sticks with a methodology they feel comfortable with.

The real magic isn’t just in the .css files, but all around them.

Thank you for reading!

--

--