Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BEM CSS and states

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);
like image 516
12init Avatar asked Nov 08 '22 01:11

12init


1 Answers

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.

like image 60
tadatuta Avatar answered Nov 11 '22 18:11

tadatuta