7

I'm looking at slowly refactoring a pretty big project that is built on Angular / Bootstrap that has just over 16,000 lines of CSS. Yay!

I've been looking more and more into BEM and believe it would be a good way to go for this. There is also a strong possibility that we will be moving to React, which I don't know much about yet, but it seems to me the modularity of both React and BEM would mesh nicely.

For now, I'm looking purely at the CSS, and wondering how I can combine BEM's methodology with the layout and presentational classes we use from Bootstrap (e.g. .container, .row, .col-m-12, etc.).

I'm aware of the practice of using @extend or @include to add the styles of these layout classes to blocks or modules, but I personally don't think it's a good one. This practice makes it impossible to tell what is happening by looking at the html alone and makes it very difficult to maintain/debug/refactor.

Is there anything wrong with simply doing something like the following?

<div class="nav container">
   <div class="row">
      <div class="nav__item col-sm-2">…</div>
      <div class="nav__item col-sm-2">…</div>
      <div class="nav__item col-sm-2">…</div>
      <div class="nav__item col-sm-2">…</div>
      <div class="nav__item col-sm-2 col-sm-offset-2">…</div>
   </div>
</div>
bernk
  • 1,155
  • 2
  • 12
  • 22

4 Answers4

5

I'm aware of the practice of using @extend or @include to add the styles of these layout classes to blocks or modules, but I personally don't think it's a good one. This practice makes it impossible to tell what is happening by looking at the html alone and makes it very difficult to maintain/debug/refactor.

You're right.

You could consider to use an alternative syntax for BEM in order to prevent naming conflicts:

Paleo
  • 21,831
  • 4
  • 65
  • 76
1

There's nothing wrong with the scheme you suggested. Keep going with it.

tadatuta
  • 2,007
  • 11
  • 12
0

I would put the nav__item after col-sm-2 as I would want the BEM to override the nav_item in most cases. col-sm-2 would be the base class and nav_item would add to it or amend it.

  • 3
    You might be surprised to learn that the order of classes in the class attribute of an element has absolutely no bearing on anything. It's their order in the source that matters. So if you have an element with `class='red blue'` you might logically assume that blue will override red, but if in the source red is defined after blue, it will override blue! – bernk Jan 17 '20 at 18:40
  • Well I didn't know that, thank you for clarifying it. I suppose the order is down to what works for you and as I tend to load bootstrap first before main if I write them in that order it helps to remind me what is over writing what, in my head anyway. – Stephen Brown Jan 19 '20 at 10:29
0

I was also thinking about this topic (mixing BEM and bootstrap) and I have used a similar approach like your code in past projects. So generelly, yes, your code is working. You are mixing 2 approaches (component-based/BEM and utility classes). BEM in its "strict philosophy" would not allow utility classes. But mostly, in a more straightforward approach, it ends up by mixing BEM (for your own components) and utility classes (provided by the framework). What I would recommend is using a prefix for your own components/blocks (so ".myproject-nav" instead of ".nav") to avoid naming conflicts of bootstrap and your own components.

Volker
  • 9
  • 1