5

Been trying to learn BEM and while I know that BEM is not just CSS it seems like a best place to start.

So I made some basic preloader css: https://jsfiddle.net/ygz931s7/

And modified it to fit BEM notation: https://jsfiddle.net/af36921w/

The problematic part was the loaded class which simplified stuff from the js side, that I didn't know how to do 'BEM'-wise.

My attempt resulted in this: https://jsfiddle.net/rd40ve3m/

My question is:

It there a better way to do this. In the final example I need to modify several elements and know specific classes to use, where in the original example I need but to add one class.

So is there a better "BEM"- way of doing this?

Here is to code noted in the last example:

HTML:

<div class="container">
    <div class="loader">
        <div class="loader__element loader__element--left"></div>
        <div class="loader__element loader__element--right"></div>
    </div>
</div>

CSS:

.loader {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1000;
}

.loader__element {
  position: fixed;
  top: 0;
  width: 51%;
  height: 100%;
  background: black;
  z-index: 1000;
  transform: translateX(0);
}

.loader__element--left {
  left: 0;
}

.loader__element--right {
  right: 0;
}

/* loaded */

.loader--loaded {
  visibility: hidden;
  transform: translateY(-100%);
  transition: all 0.4s ease-out 0.8s;
}

.loader--loaded__element--left {
  transform: translateX(-100%);
  transition: all 0.4s ease-out 0.4s;
}

.loader--loaded__element--right {
  transform: translateX(100%);
  transition: all 0.4s ease-out 0.4s;
}

JS:

   setTimeout(function() {
    document.getElementsByClassName("loader")[0].classList.toggle('loader--loaded');
    document.getElementsByClassName("loader__element--left")[0].classList.toggle('loader--loaded__element--left');
    document.getElementsByClassName("loader__element--right")[0].classList.toggle('loader--loaded__element--right');


  }, 1000);

SOLUTION:

BEM metodology allows nested selectors (https://en.bem.info/methodology/css/#nested-selectors) therefore just using loder--loaded modifier whould be ok (tnx to @tadatuta). So the resulting code would be:

HTML:

<div class="container">
    <div class="loader">
        <div class="loader__element loader__element--left"></div>
        <div class="loader__element loader__element--right"></div>
    </div>
</div>

CSS:

.loader {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1000;
}

.loader__element {
  position: fixed;
  top: 0;
  width: 51%;
  height: 100%;
  background: black;
  z-index: 1000;
  transform: translateX(0);
}

.loader__element--left {
  left: 0;
}

.loader__element--right {
  right: 0;
}

/* loaded */

.loader--loaded {
  visibility: hidden;
  transform: translateY(-100%);
  transition: all 0.4s ease-out 0.8s;
}

.loader--loaded .loader__element--left {
  transform: translateX(-100%);
  transition: all 0.4s ease-out 0.4s;
}

.loader--loaded .loader__element--right {
  transform: translateX(100%);
  transition: all 0.4s ease-out 0.4s;
}

JS

   setTimeout(function() {
    document.getElementsByClassName("loader")[0].classList.toggle('loader--loaded');
  }, 1000);
12init
  • 127
  • 8

2 Answers2

1

It should be enough to just toggle loader modifier. Styles for elements may use nesting in this case. See https://en.bem.info/methodology/css/#nested-selectors for more info.

tadatuta
  • 2,007
  • 11
  • 12
  • Thank you for taking the time to reply. So something like this I guess? https://jsfiddle.net/rd40ve3m/12/ `.loader--loaded .loader__element--left` and then just use .loader--loaded – 12init Sep 25 '18 at 17:06
0

Namespacing your BEM classes is a good idea to classify them. Use these prefixes for different types of classes :

c- => for a standalone components.

l- => to position c- components and structure an application’s layout.

h- => attach a single function to components.

is- / has- => attach a state to components.

js- => attach JavaScript behavior to a component.

For more info : Battling BEM CSS: 10 Common Problems And How To Avoid Them

Also I added namespace to code : jsfiddle

Bahman Parsa Manesh
  • 2,314
  • 3
  • 16
  • 32
  • Thank you for taking the time to reply and provide an example. I am not really sure how much namespacing conflicts with BEM methodology. – 12init Sep 25 '18 at 17:10
  • Actually namespaces contradict main ideas of BEM: 1. to follow component approach through all the technologies (so JS behavior is just one of the block techs and you should use same names as for CSS implementation) 2. to use modifiers for state, not so additional classes with `js-` or `has` – tadatuta Sep 25 '18 at 21:12