As a frontend architect, you need to understand the major trends in CSS writing together with a plan that will be consistent with the large scale.
One of the greatest things about this industry is that we can freely sit down with fellow developers and have a cup of coffee. That might not seem like a big deal, but let me tell you, it is! We work in an industry based on open standards, open-source software, open information, and open learning.
The tools and techniques we use may be changing at an incredibly fast pace, but working in such an open industry is the key reason we’re able to keep up with them. Now, this may surprise you, but there are other industries where you would never, ever sit down with a fellow practitioner to talk shop, unless they were paying you to do it.
In these industries, every piece of knowledge, every trick, every preset, every macro, every document, and every shortcut is up for sale, and the last thing you’d want to do is sit down with a potential competitor and freely trade that information.
Now compare this to the Web. We thrive on sharing knowledge. We publish blogs, record video tutorials, create public code repos, write on Stack Overflow, respond to questions on IRC, and distribute CodePens, Gists, Sassmeisters, JSbins, and Pastebin, all so that others can learn the things that we know.
Getting a cup of coffee and discussing your views on current web practices and new CSS frameworks is the most basic expression of how we share knowledge and how we learn in this industry.
So yeah! We work in an industry where inviting an associate out for a cup of coffee is not only acceptable but also a valuable practice! These cups of coffee can lead to learning new things, new business connections, new jobs, and even great friends. Suffice it to say, many years of talking shop over cups of coffee, beer, tea, or kombucha has led me to believe that the simple social interface of sharing a beverage is one of the greatest assets we have in this industry.
The great thing about having consistent caffeine- or alcohol-fueled conversations with other developers is that we always have a pulse on what people are excited about, and in what direction they are headed.
This is important to me not because I depend on others to know what to do next, but rather because I am able to validate the things I am learning and the discoveries I myself am making. Every year I look back at how my approach to CSS writing has evolved.
So whether my newest obsession is preprocessors, build tools, style guide–driven design, or component-based design systems, I’m always excited to find that others are coming to the exact same discoveries.
The CSS I am writing today looks nothing like what I was writing even three years ago.
After each site builds, I learn something new and try to apply that to my next project. It’s a very organic process of gathering the things I’ve learned with the things I’ve read and trying to apply an improved approach to the unique problems I face. Each iteration brings a marked improvement in my technique and my understanding of a scalable and maintainable design system.
Along with each iteration are the exciting conversations with various coworkers, industry colleagues, or random conference-goers. With each of those conversations, I’m consistently amazed that I was not the only person to have a euphoric epiphany about using data attributes, or opt-in styles to handle my component variations.
As a frontend architect, you might not need to know every tiny CSS bug in some obscure version of Opera mini, but you do need to understand the major trends in CSS and be able to put together a plan that will set your team up for success.
If you haven’t been keeping up on the current CSS writing trends, or your euphoric epiphanies aren’t coming as fast as you wish they would, try grabbing a few more cups of coffee with fellow developers or spend a bit more time doing the “social track” at your next conference.
But before you do that, read The following sections so you can get caught up on where we were in CSS a few years ago, why it didn’t work, and where we are now.
Specificity Wars and the Pains of Inheritance
It wasn’t that many years ago when we were still dealing with the 100% dynamic or 100% static markup that I described in the CSS Structure Article. Regardless of the side of the spectrum, we were on, the effect on our CSS writing was that we almost always started from a global scope and worked our way down, getting more specific with each new level of the cascade.
We’d start with general styles on each element, like our header and paragraph tags, and then apply specific styles to the elements inside of the various sections of our page:
<body>
<div class="main">
<h2>I'm a Header</h2>
</div>
<div id="sidebar">
<h2>I'm a Sidebar Header</h2>
</div>
</body>
<style>
h2 {
font-size: 24px;
color: red;
}
#sidebar h2 {
font-size: 20px;
background: red;
color: white;
}
</style>
Now every h2
is red, except for the sidebar where the h2
is white with a red background.
This concept was easy to understand and made a ton of sense if you were coming from a print background. Every time you put an h2
in the sidebar, it would be styled the same—well, that is until we came across a calendar widget in the sidebar that should be using the original header colors and no background.
But that’s OK! We could just add another class and overwrite the offending sidebar styles, right?
<body>
<div id="main">
<h2>I'm a Header</h2>
</div>
<div id="sidebar">
<h2>I'm a Sidebar Header</h2>
<div class="calendar">
<h2>I'm a Calendar Header</h2>
</div>
</div>
</body>
<style>
h2 {
font-size: 24px;
color: red;
}
#sidebar h2 {
font-size: 20px;
background: red;
color: white;
}
#sidebar .calendar h2 {
background: none;
color: red;
}
</style>
The issues with this approach are numerous:
Specificity
Whether you’re dealing with ID tags or just long selectors, overwriting a selector always requires some attention to the level of specificity.
Resetting colors
To get back to the original h2
color we have to specify it again, as well as overwrite the background.
Location dependence
Now our calendar styles are dependent on being in the sidebar. Move the calendar to the footer and the header size will change.
Multiple inheritance
This single h2
is now getting styles from three different sources. This means we can’t change the body or sidebar h2
without affecting the calendar.
Further nesting
The calendar widget might have other h2
inside of individual calendar entries. Those h2
will need an even more specific selector, and will now be dependent on four sources for their styles.
A Modern, Modular Approach
Our discussion of HTML Architect foreshadowed a few of the modern, modular tenets that the majority of frameworks are employing to deal with the problems we saw in the approach just described. While OOCSS, SMACSS, and BEM have differing opinions about the exact markup to use, each offers advice about how to write your CSS that will be valuable regardless of the approach you take.
Let’s take a quick look at a few of those key tenets and how they help solve the problems we had before.
OOCSS brings the idea of separating container from content, where we learn to stop using location as a style qualifier. There is nothing wrong with having a sidebar on your site, and styling that sidebar in whatever way you’d like, but the influence of those sidebar styles stops once you get down to the contents of the sidebar.
#sidebar h2
means that every h2
an element placed in the sidebar is going to have to either accept or fight off the styles applied by that selector. .my-sidebar-widget-heading means that a single heading in the sidebar can opt into that style, while other modules in the sidebar have headings that are left completely untouched.
SMACSS brings us the idea of separating our layout and our components into completely different folders, further dividing the role of the sidebar and the role of the calendar module. Now that we have defined the sidebar’s role to that of just layout, we don’t even allow element styles inside of that Sass partial.
If you are going to place something in the sidebar and want to have it styled, that element needs to be part of a component and defined in the component folder.
BEM, while not necessarily a CSS writing methodology, teaches us the value of having a single source of truth for every class used in our markup. Instead of classes that ebb and flow depending on their context or proximity to other selectors, each BEM class can be traced back to a single set of CSS properties unique to that selector:
<body>
<div class="main">
<h2 class="content__title">I'm a Header</h2>
</div>
<div class="sidebar">
<h2 class="content__title--reversed">I'm a Sidebar Header</h2>
<div class="calendar">
<h2 class="calendar__title">I'm a Calendar Header</h2>
</div>
</div>
</body>
<style>
/* Components folder */
.content__title {
font-size: 24px;
color: red;
}
.content__title--reversed {
font-size: 20px;
background: red;
color: white;
}
.calendar__title {
font-size: 20px;
color: red;
}
/* Layout folder */
.main {
float: left;
}
.sidebar {
float: right;
}
</style>
The issues we had with our original location-based styles are fixed:
Specificity
Changing your IDs to classes is a good start in stopping the specificity wars, and flattening every selector’s specificity to “1” allows us to stop using the specificity “winner” to determine the applied styles.
Resetting colors
Even better than lowering specificity is using a single selector to apply styles to each element. This way your module styles never have to fight with your sidebar or site-wide styles.
Location dependence
With no styles scoped to a single layout, we don’t have to worry about what happens to the calendar when we move it from the sidebar to the main section.
Multiple inheritance
With each of the three headings getting its own unique class, we are free to change any of them without fear of affecting the others. If you want to make changes across multiple selectors, look into preprocessor variables, mixins, or extends to handle that for you.
Further nesting
Even at the calendar level, we still haven’t applied a single style to our h2
elements. There’s no need to override base, sidebar, or calendar header styles before styling new h2
in our calendar module.
Other Principles to Help You Along the Way
Read more: CSS Techniques for maintaining the codebase at large scale in Frontend Architect