a series of interviews on BEM methodology MENU

Hi Jof

Thank you for accepting to share your experiences and opinions about BEM.

Let's start from you: in your website I read that you are an entrepreneur and an engineer. Nuclear robotics and Russian spacecrafts, then motorsport cars and fuel injection systems, and now you are at your umpteenth internet startup. But at the same time you are a software/front-end developer, a designer and a speaker too. Can you tell me briefly about you? Do you still get your hands dirty, with HTML/JS/CSS or you're more in a leading role?

As you say I've been involved with quite a lot of different things over the years, but since about 2006 it's been coding all the way. That said, it's really only in the last 4 or 5 - since we did our YC startup - that I've started doing web app development full time.

When I started out I mostly used JavaScript framework Backbone.js along with CoffeeScript, Stylus and Jade. However, these technologies don't lend themselves to building complex app so in early 2014 I switched to React, ES6 and SCSS.

Now, let's go straight to the "root cause" of this interview: a few days ago you replied with this statement “BEM definitely promotes more CSS. We've moved away from it for that reason” to one of my tweets (in which I was quoting someone complaining about the "intrinsic" problems of BEM).

Your response was absolutely surprising for me, I mean it in a good way. I have never thought that one could write too much CSS (at least not on purpose). But what you were saying is that BEM itself was promoting a certain CSS bloat, and for this reason you have decided to steer away from it.

Can you explain me more about it? What do you mean exactly?

As I mention, we use React and a key concept in building React apps is breaking down the app into small stateless components. We saw an opportunity to improve maintainability by breaking the SCSS into one file per component. Within each file we used a modified BEM naming scheme with underscores and titlecase. For instance a component called MyButton might contain block classes such as MyButton_label and MyButton_icon. In order to specify the button be blue or red or whatever we'd send through a prop like 'theme="primary"' which would then be rendered as, for instance, the class MyButton_label__primary.

By namespacing it to the component like we can be fairly sure it won't be overriden - at least by accident. We can reuse the component and expect it to look the same everywhere (provided we have no globs styles, use rems etc). Like with all BEM, however, the naming scheme is only a contract; if someone insists on overriding the scoping with something like .MyWrapper .MyButton_label {color: red} then there's not much you can do about it apart from code review.

Now the question comes; how do you give that button its height, color and hover transitions? Likely you'll probably use a global SCSS constant or mixin, but that's where the problems start. Rather than having generic classes you can apply to any component that needs it you're now outputting those lines everywhere the mixin is used; i.e. you start to add extra CSS into the compiled assets which wouldn't have been the case if you were composing within the class name such as class="title primary float-left clear-both fast-hover" etc. Worse still, your build tools don't know if that CSS is ever used so it'll shove it in the compiled assets regardless.

For us, all this mixin and constants abuse caused our compiled CSS to balloo to over 10,000 queries. Not only does this cause a performance hit loading and rendering the document but also older versions of IE can't even parse that many queries from one file. Furthermore, we found it too easy to violate the contract of "don't use parent component selectors to override those of their children" (as per the example with MyWrapper above) which created a huge ball of CSS spaghetti.

The solution was to move to CSS Modules with PostCSS and SCSS, using a mix of composing within the SCSS files themselves (usually for things like hover effects and transitions) and importing styles (usually for theming - e.g. colors) into the JS file (for example, like in react-css-themr). The build tools then chain all the class names together for you. In addition to solving the above problems it vastly improve compile and hot reload times since the build system only has to modify a very small part of the code.

But I still don't get the "writing too much CSS with BEM" in what you say. Isn't the sum of the (S)CSS written the same, at the end? It's only split in more smaller files! Or you actually end up writing less CSS code because this approach (breaking down the app into small components) encourages the re-usability of the components? But in that case I would say the problem is not in BEM, but in how the application is designed. What do you think?

It is not the same, no. At least not for large projects with many components. CSS modules have the opportunity to be vastly smaller in terms of compiled CSS. Have a look at this gist - it might make things clearer.

And that's just using one mixin. Can you imagine how much CSS is compiled out when including multiple mixins within one block versus CSS Modules? In fact, you find that as you built out an application you start to spot reuse opportunities that actually *shrink* the compiled assets when using CSS modules. Who wouldn't want that? :)

Of course, now that I've said all this I should come clean and say that it's not exactly how we do it in practice ;) Instead we use a mix of CSS Modules and styled wrapper components. So rather than doing

<div className={ classes.title }>
  My Title
</div>

.title {
  composes: h1 from 'typography';
}

We actually do stuff more like:

<Title>
  My Title
</Title>

Where the style is within the Title component and the children (i.e. `My Title`) inherit those properties such as font-weight, font-size etc. This could be a very long discussion - especially as our approach is a bit odd/specific and possibly not useful generically - so instead I'll just point you to Styled Components and react-css-themr so you can explore further.

Yes, I see your point and I totally get the benefits of using CSS Modules (this morning I was looking at the slides of the talk that Josh Johnston presented at CSS Conf AU this year, At Least 6 Ways to Win with CSS Modules, and clearly there are big wins there). But I can't stop thinking that when in a project you end up with "15,000 LOC style file and 7,000+ selectors", as you experienced first hand, there is no technology or methodology that can protect you: this is a developers' "failure" (no offence intended, I imagine I've been one of these developers in my career).

Also, how much of this neatness of CSS Modules is due to the fact that the developers using it are somehow very "zen" in their coding, naturally? Being early adopters probably means also that they put a lot of care and thinking in "how to do it properly". Don't you think that the early adopters of BEM achieved the same neatness and cleanness, and then things simply evolved and becoming mainstream reached developers less "zen" in their approach (and in some cases went out of hand, clearly)? Don't you think that when CSS Modules will become mainstream, you'll see the same distortions and bad practices as above?

Yes, it is developer failure to a degree but it's more the failure of the processes and tools. In mass production manufacturing environments, for example, the tools/parts that the assembly workers use are often designed in a way that allows assembly in one specific direction only. This enables the workers to achieve flow and high productivity whilst almost guaranteeing against assembly errors.

Our app had something like 700,000 LOC added over 3 years and was iterated rapidly. To build at that scale and speed successfully you need - like in manufacturing - tools and procedures that strongly discourage bad behaviour yet still enable rapid iteration and foster developer flow. For instance, you could be the best JS developer in the world but if you're not using tools like static type checking, immutable data structures, const/let etc in a project of that size you're going to start tripping over pretty quick. So I strongly disagree with your suggestion that "there is no technology or methodology that can protect you".

Sure, you can indeed screw up with CSS modules if you don't, for instance, heavily use composes - precisely in the same way you can screw up with React if you don't reuse components and use mixins instead of HOCs, etc. But the difference is you have to put in effort to build extra components and effort not to use composes or styled components. By analogy how much easier is it to type <p> in HTML versus "<div class="someClass">"? BEM with SCSS and one-file-per-component, meanwhile, not only encourages SCSS mixins but doing so is the path of least resistance meaning people are much more likely to abuse it.

My opinion is that if you use CSS modules and styled components well not only do you give yourself a more robust environment but you don't actually need the loose contract of BEM at all.

OK, so you see more the tools in terms of not only what they allow you to do but also and mainly what they prevent you from doing. Now I understand :)

One last question, and then I'll let you go. You've been very kind to reply to my questions, I don't want to take up too much of your time.

In the recent years, I've seen the rise of the role of "CSS developer" as a distinct figure in a development team, with specific competences, skills and responsibilities. Often is also called a "CSS architect", because he needs to take in account the overall architecture of the CSS codebase (defining naming strategies, enforcing files structure and organisation, considering scalability and maintenance issues, etc.). Today being a CSS developer or a JS developer means having two completely different jobs.

Before it was more part of a generic "front-end developer" role, but now that CSS and JS have started to lose their boundaries I can't imagine what the future will be for us (currently I am one of them). If you had a crystal ball and you could foresee the future, what do you think will happen in the next one or two years? CSS developers will move to a more generic UI developer role? Will be absorbed in a hybrid CSS+JS developer's role? Will completely disappear? I know it's hard to guess, but just to have your perception of where we are going in the future. And you know, just to prepare myself... :)

Good question. I think it's more how people define themselves, how teams are structured, how big the companies are and how well individuals adapt. Some teams might have a combined skill set with a "CSS architect"-sized hole that needs filling in which case such a role makes sense. In other teams you might already have the "CSS architect" role covered by a designer who's also a pretty good CSS developer... Or a frontend developer who's particularly fastidious about application of design standards.

On the opposite side of things, if you're a really good CSS dev who's also pretty good at JS and an unbeatable "pure" JS job was offered then you'd probably find a way of adapting to that role and leave the CSS behind.

For my part, when hiring, I've found that frontend developers with an eye for design capable of building consistent, high quality, robust user experiences with quality maintainable code are exceedingly rare. These people are hugely important in early stage companies and worth their weight in gold; the right one can be worth two specialised CSS/JS developers in my opinion.

Personally I'm not interested in working for anyone else these days, but if I were I'd hone my design skills a bit further and present myself in that light in order to get a job with a startup. I'm not sure that approach would work very well at a large company like Facebook though... your mileage may vary.

Well, very good response too!

That's it. Thank Jof for your time and for sharing your thoughts about BEM and the future of CSS development.

And good luck for your new startup project, BOTS. Can you tell us a little about it, and when we will be able to try it?

Thanks :)

BOTS is an IDE for building, deploying, iterating and maintaining time-saving web services automations. It is developer-focussed with tools such as a data browser, persisted variables and replay debugging. You can use it to rapidly build things like automated GitHub flows; uptime monitoring and autoscaling; authenticated Slack commands; weekly metrics email and much more.

We're looking for more Alpha users now, so do register your interest at bots.sh or @ me @jofarnold. Say that Cristiano sent you ;)