БЭМ CSS и состояния

Я пытался изучить БЭМ, и хотя я знаю, что БЭМ — это не просто CSS, мне кажется, что это лучшее место для начала.

Поэтому я сделал базовый css для предварительного загрузчика: https://jsfiddle.net/ygz931s7/

И изменил его, чтобы он соответствовал нотации БЭМ: https://jsfiddle.net/af36921w/

Проблемной частью был класс loaded, который упрощал вещи со стороны js, и я не знал, как это сделать с точки зрения «БЭМ».

Моя попытка привела к следующему: https://jsfiddle.net/rd40ve3m/

Мой вопрос:

Это лучший способ сделать это. В последнем примере мне нужно изменить несколько элементов и знать, какие классы использовать, тогда как в исходном примере мне нужно было добавить только один класс.

Так есть ли лучший способ "БЭМ" сделать это?

Вот код, отмеченный в последнем примере:

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

РЕШЕНИЕ:

Методология БЭМ допускает вложенные селекторы (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);

person 12init    schedule 24.09.2018    source источник


Ответы (2)


Достаточно просто переключить модификатор loader. В этом случае стили для элементов могут использовать вложенность. См. https://en.bem.info/methodology/css/#nested-selectors для получения дополнительной информации.

person tadatuta    schedule 24.09.2018
comment
Спасибо, что нашли время ответить. Так что-то вроде этого, я думаю? jsfiddle.net/rd40ve3m/12 .loader--loaded .loader__element--left, а затем просто используйте .loader--loaded - person 12init; 25.09.2018

Пространство имен ваших классов БЭМ — хорошая идея для их классификации. Используйте эти префиксы для разных типов классов:

c- => для отдельных компонентов.

l- => для размещения c-компонентов и структурирования макета приложения.

h- => прикрепите к компонентам одну функцию.

is- / has- => прикрепите состояние к компонентам.

js- => прикрепите поведение JavaScript к компоненту.

Для получения дополнительной информации: Борьба с BEM CSS: 10 распространенных проблем и способы их избежать

Также я добавил пространство имен в код: jsfiddle

person bahman parsamanesh    schedule 24.09.2018
comment
Спасибо, что нашли время ответить и привести пример. Я не совсем уверен, насколько пространство имен противоречит методологии БЭМ. - person 12init; 25.09.2018
comment
На самом деле пространства имен противоречат основным идеям БЭМ: 1. следовать компонентному подходу во всех технологиях (поэтому поведение JS — это всего лишь одна из блочных технологий, и вы должны использовать те же имена, что и для реализации CSS) 2. использовать модификаторы для состояния, а не так дополнительные занятия с js- или has - person tadatuta; 26.09.2018