BEM CSS 和状态

BEM CSS and states

一直在尝试学习 BEM,虽然我知道 BEM 不仅仅是 CSS,但它似乎是一个最好的起点。

所以我制作了一些基本的预加载器 css: https://jsfiddle.net/ygz931s7/

并修改它以适应 BEM 符号: https://jsfiddle.net/af36921w/

有问题的部分是 loaded class,它从 js 方面简化了一些东西,我不知道该怎么做 'BEM'-wise。

我的尝试结果如下: https://jsfiddle.net/rd40ve3m/

我的问题是:

有没有更好的方法来做到这一点。在最后一个示例中,我需要修改几个元素并知道要使用的特定 classes,而在原始示例中我只需要添加一个 class.

那么有更好的 "BEM"- 方法吗?

这是最后一个例子中提到的代码:

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);

解决方案:

BEM 方法允许嵌套选择器(https://en.bem.info/methodology/css/#nested-selectors)因此只需使用 loder--loaded 修饰符就可以了(tnx to @tadatuta)。所以生成的代码将是:

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);

只需切换 loader 修饰符就足够了。在这种情况下,元素的样式可以使用嵌套。有关详细信息,请参阅 https://en.bem.info/methodology/css/#nested-selectors

为 BEM 命名空间 类 是对它们进行分类的好主意。将这些前缀用于不同类型的 类 :

c- => 对于独立的 组件.

l- => 定位 c- 组件并构造应用程序的 布局 .

h- => 附加一个单一函数到组件。

is- / has- => 将 状态 附加到组件。

js- => 将 JavaScript 行为 附加到组件。

更多信息:Battling BEM CSS: 10 Common Problems And How To Avoid Them

我还在代码中添加了命名空间:jsfiddle