Skip to main content
Ben Nadel at cf.Objective() 2012 (Minneapolis, MN) with: Alec Irwin
Ben Nadel at cf.Objective() 2012 (Minneapolis, MN) with: Alec Irwin

Considering BEM - Block Element Modifier - CSS And Bounded Contexts

By
Published in Comments (1)

CAUTION: I am very new to BEM and this post should be considered as coming from the perspective of a beginner.

While I am certainly a BEM - Block Element Modifier - novice, from what I have done so far, I rather enjoy the approach it takes to organizing CSS. The one hurdle that I keep coming across, however, is the requirement to create globally-unique Block names within an application. While many CSS blocks may be globally relevant to an application, I think that an application's user interface (UI) can be divided up into bounded contents; and, that it's OK to have a BEM Block defined within the scope of a bounded context.

The advantages of having globally-unique Block names are obvious: there's zero chance for confusion as to what CSS influences what HTML markup; and, it's rather easy to find the relevant CSS with a text-search of your code-base. But, the use of globally-unique Block names doesn't feel like it will scale well (in my mind) because it forces you to create arbitrarily long Block names simply for the sake of uniqueness.

With the concept of a "bounded context" we can scope Block names to a particular area of an application - an area in which a particular Block name has an agreed upon mental model. Take for example, a "primary navigation" Block:

.c-primary-nav {}

If your application happens to have to have several different layouts, the semantics of "primary navigation" may be completely different from layout to layout. As such, you have two choices: you can try to create globally-unique Block names:

.c-standard-primary-nav {}
.c-alternate-primary-nav {}

... or, you can try to make one primary navigation a "modified" version of the other one:

.c-primary-nav {}
.c-primary-nav--alternate {}

To me, the first choice doesn't sit well - emotionally - since we have to make wonky names not because they are meaningful, but because they are unique. And, the second choice feels like a non-starter. One of the biggest mistakes that web developers make is thinking that two things are related simply because, at some point in time, they look or sound similar. A primary navigation Block in two unrelated layouts are as closely related as a commuter train and a toy train. When you try to phrase it using the "is a" domain modeling terminology, the problem becomes obvious: "the alternate layout primary navigation IS A type of standard layout primary navigation." It's hard to even parse this sentence because it doesn't make much sense.

An alternative approach that I've been noodling on would be to allow names to be locally-unique - local to a particular bounded context. Doing so would require some nesting in the CSS architecture:

.bc-primary-layout .c-primary-nav {}
.bc-alternate-layout .c-primary-nav {}

Here, I'm using the prefix "bc" to stand for "bounded context". This application has two bounded contexts: primary-layout and alternate-layout. And, each of these bounded contexts can have their own mental model for Blocks like "primary navigation" and "search form" and "modal window."

Now, the problem with the use of bounded contexts in BEM is that it introduces flexibility. And, with flexibility you can easily shoot yourself in the foot. The biggest threat is that there's nothing preventing you from having nested bounded contexts. And, with nested comes accidental inheritance.

But, with a little discipline, I think problems can be avoided. For example, if a Block has local meaning in nested contexts, you have to do one of two things: you either make the nested Block a modified version of the first block; or, you take the Block in the outer context and you move its definition to a sibling context where cascading it no longer an issue.

To me, the use of bounded contexts provides us with the organizational advantages of BEM CSS but removes some of the constraints imposed by the traditionally flat selector space. Of course, this adds some complexity and may require refactoring as different bounded contexts come to light. It remains to be seen as to whether or not the advantages of local semantics outweigh the costs of maintenance.

Epilogue

The more I noodle on this, the more I think that in order for this to be helpful, the bounded context names would have to be globally-unique. And, shouldn't rely on nesting. Meaning, they can be structurally nested in the DOM (Document Object Model), but should not have be nested in the CSS (since they are globally-unique).

Reader Comments

15,902 Comments

@All,

The more I think about this, the more I think maybe this is a not a great idea :)

I think what I am reacting to is that it's really hard to come up with unique names for things that look similar but are NOT the same thing (ie, they are not variations of the same component).

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel