4

I recently started using BEM methodology and I'm confused about class inheritance, or rather - when we talk about BEM - some use cases of modifiers.

Let's look at this example, I have a simple element with few children

.b-content { width: 100%; }
.b-content__image { display: block; }
.b-content__date {  font-size: 14px; }
.b-content__title { font-size: 30px; }
.b-content__text { font-size: 16px; }

Now I want to reuse my .b-content block with slightly different styles, so I use modifier .m-compact and now I'm not sure what approach is the right one (in BEM).

Whether I should append modifier class to all elements (which I find more valid according to documentation):

.b-content.m-compact { width: 50%; }
.b-content__image.m-compact { display: none; }
.b-content__date.m-compact { font-size: 12px; }
.b-content__title.m-compact { font-size: 24px; }
.b-content__text.m-compact { font-size: 14px; }

or should I append modifier only to the parent element:

.b-content.m-compact { width: 50%; }
.b-content.m-compact .b-content__image { display: none; }
.b-content.m-compact .b-content__date { font-size: 12px; }
.b-content.m-compact .b-content__title { font-size: 24px; }
.b-content.m-compact .b-content__text { font-size: 14px; }

I find this second method more logical, you know, since I'm writing cascading styles and in real world if I want to write e-mail to 10 people, I would write one and just add more recipients, but on the other hand I realize BEM is practically non-cascading approach.

So what should I use and why?

mdr
  • 421
  • 1
  • 6
  • 14
  • This question is either too broad, opinion based or requires discussion and so is off-topic for Stack Overflow. If you have a specific, answerable, programming issue, please provide full details. – Paulie_D Jul 18 '16 at 14:31

2 Answers2

2

As you point out in the last lines of your question, when doing BEM you should avoid cascading so, as a corollary to this, you don't have to repeat the modifier where it isn't needed.

For your Modifier I'd write something like this:

.b-content--m-compact {
  width: 50%;
}

In your example the Block and the Modifier set only the width, so this is a limited use case. In general it comes handy to use some kind of CSS preprocess to ease the code writing, e.g. in SASS:

.my-block
  width: 100%
  color: red
  &--modifier
    @extend .my-block
    border: 1px solid red

which will results in:

.my-block, .my-block--modifier {
  width: 100%;
  color: red;
}
.my-block--modifier {
  border: 1px solid red;
}
kaosmos
  • 558
  • 9
  • 23
  • Actually the modifier doesn't set only width of the container, it also sets font-size and display of its children. Anyway your example with preprocessors seems like a solution to my problem, however I can't use it in my recent project because of other colleagues and company internal routines. So I start to realize my problem is in absence of preprocessors and my company... – mdr Jul 19 '16 at 06:58
  • ok @madr, now I got a better grip on your point. Your use of the Modifier is a mix between traditional CSS (with a stress of the Cascading) and BEM. You shouldn't define Element as descendant/child of something else but as a "standalone" class. Harry Roberts of [CSS Wizardry](http://csswizardry.com/) have a nice article on this: http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/ I hope this makes sense. – kaosmos Jul 19 '16 at 11:04
  • also, @madr, if you are the only one who writes CSS you can use SASS on your own, even if it is not a tool used company-wide. I did this for some time, until I obtained to adopt SASS in the company workflow I simply committed the resulting CSS. – kaosmos Jul 19 '16 at 12:51
1

Modifier in BEM looks like this: .block_modName_modValue

You can add additional class - but it's not BEM. And also modifiers have a name and value.

Block in BEM set namespace

So you set default styles for blocks and all unique(that can be changed) place in css with modifiers. This way your styles don't messed up.

To do this you need:

  1. Place common styles in block styles(.portfolio)
  2. Place unique style(with modifiers) like this.(portfolio_theme_list)

In css you don't need to separate this(preprocessor will be needed).

.portfolio {
    /* common styles */

    &_theme_list {

    /* modifiers style */
    }
}

In BEM project-stub(template engine) it would look like this:

If you add modifier to block. Then compile(bemjson) to html.

{
    block : 'portfolio',
    mods : { theme : 'list' },
}

You will see this code

<div class="portfolio portfolio_theme_list">
</div>

You write elements correctly and understand that they need to be separated(without inheritence).

So now you need just define styles for your block with modifier(portfolio_theme_list).

You have 2 options:

1) If you have 2 different blocks - you need separate common and unique styles. Unique styles place in styles with modified blocks.

2) If you have only 1 different block & you already have styles on this blocks. Then you can override and don't separate common styles(but it can cause pain if you add another modifier/instance)

Zentro
  • 73
  • 1
  • 7