Pull to refresh

Comments 681

Подобные разгромные статьи, касающиеся любой методологии нужно начинать, не с
BEM'а не должно существовать
а с чего-то что-то типа:
Имея за плечами более чем двадцатилетний опыт разработки…
Не думаю, что тут особо важен опыт разработки. Ибо опыт опыту рознь. Да и 20 лет опыта разработки в вебе? Где же столько взять. Да и в добавок 20 лет, так или иначе будет некий фанатизм, обречённость, принятие, не будет рационального. А вот свежий взгляд тут и говорит о проблемах. После использования webpack + less|sass|stylus, на BEM смотреть вообще не могу.
UFO just landed and posted this here
Да, но как быть с этим?
<ul class="article-rewind article-rewind_type_static article-rewind_lang_ru">
    <li class="article-rewind__next">
        <div class="article-rewind__next-text">Читать далее</div>
        <a class="article-rewind__next-link" href="">Основные понятия</a>
   </li>
</ul>

Как то однажды я сделал так:
const _ = "app_tourney__popup__";
const w = _ + "w";
const l = _ + "l";
const r = _ + "r";
const b = _ + "b";
const c = _ + "c";
const bg = _ + "bg";

export default class TourneyPopupView extends React.Component {
    render() {
        const { position } = this.props;

        return (
            <span className={b} ref={e => (this.b = e)}>
                {this.props.children}
                <span className={c}>
                    <span className={(position == "right" ? r : l) + " " + w}>
                        <span className={position == "right" ? l : r}>
                            <span className={bg}>{this.props.title}</span>
                        </span>
                    </span>
                </span>
            </span>
        );
    }
}

а не проще ли использовать css-modules и делать просто импорты классов?
Ну вот не лежит у меня душа к css-modules. Что-то внутри меня прямо так и говорит: «Не используй css-modules!»
Вы наверно ещё и ESNext-ненавистник?

А почему? Как по мне — очень удобно. Ты создаешь компоненту, рядом кладешь CSS. И тебе не надо заморачиваться по поводу именования. Допустим есть компонента Article и Comment. И них есть автор. В двух CSS-ках компонент совершенно спокойно можно использовать класс .author не боясь, что что-то где-то пересечется

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

Ну в моей практике CSS modules просто превращает классы в уникальные хэши. При этом вид конечного класса можно настроить, чтобы красиво отображалось (имя файла добавить, изначальное имя класса и т.п.). И проблем при дебагинге нет

Может сейчас уже удобно, но когда пробовал очень неудобно было делать стилизацию компонентов низкого уровня зависящей от компонентов высокого. Типа цвет фона кнопки должен быть такой же как цвет бордера текущей панели.
UFO just landed and posted this here
Что-то Альфа-банк придумал дичь какую-то, как мне кажется. И зачем для реакта еще что-то придумывать, если есть Styled components, прекрасная либа.

Генерировать эти классы/атрибуты автоматом. Например, из такого шаблона:


<ul id="my-article-rewind" _type="static" _lang="ru">
    <li id="next">
        <div id="next-text">Читать далее</div>
        <a id="next-link" href="">Основные понятия</a>
   </li>
</ul>
Я тоже склоняюсь к такому решению.
Миксы — сомнительная практика. Я их не применяю.
UFO just landed and posted this here

Да нет, тут всё правильно. Название должно обладать семантической точностью. text — слишком общее, текстов может быть много разных в блоке. И если в next и prev должны быть разные стили текста, то и называться они должны соответственно next-text и prev-text. А вот если одинаковые, то уже и там и там должно быть item-text.

UFO just landed and posted this here

В article-rewind__next-text всё правильно написано. Это элемент next-text блока article-rewind.

UFO just landed and posted this here

Это что у вас за элементы элементов? По бэму не может быть такого. Стоит перечитать. И ещё используйте пакет classnames для конкатинации стилей.

БЭМ — не священное писание. Иногда требуется стилизовывать и элементы элементов.

Вы или не на тот коммент отвечаете или просто ёрничаете не найдя что ответить)

На реакте я запилил такое:
(показываю только использование, без реализации)


const { block, element } = bem('ArticleRewind');

function ArticleRewind (props) {
  return (
    <ul {...block({ [props.type]: true, [props.lang]: true )}>
      <li {...element('next')}>
        <div {...element('nextText')}></div>
        <div {...element('nextLink')}></div>
      </li>
    </ul>
  );
}

При вызове


<ArticleRewind type="static" lang="ru" />

На выходе будет:


  <ul class="ArticleRewind ArticleRewind_static ArticleRewind_ru">
      <li class="ArticleRewind__next">
        <div class="ArticleRewind__nextText"></div>
        <div class="ArticleRewind__nextLink"></div>
      </li>
    </ul>
Как-то много писанины. Лучше вынести всю её в HOC.

Как будет выглядеть, не опишите? Мне как-то не очень нравится идея с дополнительным HOC для каждого компонента.

Идея простая, ХОК получает VDOM дерево, пробегается по нему, находит id атрибуты и генерирует по ним россыпь классов.
HOC не может получить VDOM-дерева, как и любой другой компонент. Для модификации VDOM нужно не HOC делать, а декоратор который в готовом классе методы заменяет.
ХОК и есть такой декоратор.
С чего бы? Отрендерили вложенный компонент, обработали полученный от него вдом.
Как получить вдом от вложенного компонента? Притвориться реактом и вызвать у него метод render напрямую?
Ваш любимый JSX как думаете что возвращает?
Повторяю вопрос: как вы собрались добираться до jsx, который инкапсулирован в методе render вложенного компонента?
А давайте вы выключите дурачка. Оборачиваете функцию/класс компонента и именно его VDOM процессите. Лезть глубже совершенно ни к чему, там свои хоки отработают.
А давайте вы перестанете нести тарабарщину и приведете хотя бы примерный код?
Мне оно зачем? Я не пользуюсь Реактом и вам не рекомендую.
UFO just landed and posted this here

Формально у вас вроде БЭМ, но по существу издевательство. Я бы предложил:


<ul class="article__rewind rewind rewind_static rewind_lang_ru">
    <li class="rewind__next">
        <div class="rewind__text">Читать далее</div>
        <a class="rewind__link" href="">Основные понятия</a>
   </li>
</ul>

Теги вложены на много уровней, а элементы блока идут "в один уровень". Это фишка БЭМа, которая все упрощает. В то же время блок является элементом другого блока за счет применения нескольких классов (миксования).

Ну а что тут не так? Вы же не одним пальцем набираете. Все же, больше времени уходит не на напечатывание имен классов, а на продумывание стилей.
Препроцессор можно заставить генерировать код по БЭМ, но ради какой практической выгоды?
UFO just landed and posted this here
Ссылочку на реальный бенчмарк, где в условиях чистого эксперимента сравнивается пресловутая «нагрузка» при использовании каскадных и не-каскадных селекторов вы представить можете?
UFO just landed and posted this here
Это называется premature optimization
Этого никому не может быть достаточно для обоснованного вывода, потому что влияющих факторов — множество. Нет практического сравнения двух изолированных случаев — нет факта, есть одни домыслы.
UFO just landed and posted this here
Естественно, я сам не проверял, как и вы.
Но вот какая штука — browser-ы писались и пишутся исходя из каскадности стилей. Потому реальных оснований считать, что селекторы с километровыми именами без каскадности работают лучше — нет. А в пользу вашего утверждения даже косвенных аргументов нет.
Каскад действительно работает медленнее классов без вложенности, яндексоиды публиковали тесты.
Но реально заметную на глаз разницу это давало только на очень больших страницах — десятки тысяч узлов. В реальной жизни такие почти не встречаются.
Но некоторая разница всё-таки есть, это факт.
UFO just landed and posted this here
Это очень абстрактное утверждение. В зависимости от условий узкие места могут меняться. В принципе я согласен, что на практике CSS не является узким местом почти никогда. Но потенциально может им быть.

Там смысл был в том, что каскады влияли на скорость reflow.
И если вдруг ваше веб-приложение так устроено, что reflow случается часто (а способов его вызвать довольно много) — это могло вылиться в ощутимые подлагивания.
UFO just landed and posted this here
Какой конкретно браузер какой конкретной версии? Или все браузеры с 90-х годов парсят идентично?
А теперь условный сайт на БЭМ'е попадает в руки к новому разработчику. Сайт большой, десятки css и html файлов и т.д. И встает перед ним задача — поменять background у элемента. Открывает он сайт, копирует класс нужного элемента, ctrl+shift+f '.header__title' (только в реальности это будет article__heading_level_1_active). А нет такого. В лучшем случае помогут map'ы, но с ними тоже проблем хватает.
Зачем копировать? Он видит имя блока «header», идет и открывает файл _header.scss в котором достаточно быстро находит искомый селектор.
идет и открывает файл _header.scss в котором достаточно быстро находит искомый селектор

Если это сферический проект в вакууме, то да, все так и будет. Реальность же несколько отличается — проект растет и меняется, разработчики сменяют друг друга, а их уровень может быть самым разным.

JFYI класс article__heading_level_1_active не по БЭМ.

Виталий, а почему? Это же вроде так:

article - блок
heading - элемент
level_1_active - модификатор


Или потому, что смешаны модификаторы level_1 и active?
гененрировать класс с помощью препроцессора не плохая ли практика?
UFO just landed and posted this here
еще для автоматизации рутины придумали компьютер
UFO just landed and posted this here
Только в читабельности и поиске.
Хотя я не совсем понимаю, какие вообще есть преимущества такого исользования.
Преимуществ несколько, но все их собирательно можно обозначить как «общие множители полезно выносить за скобку»
Есть проблема, если я хочу найти место, где класс был определен, то с таким подходом нельзя просто искать по имени класса. Например я хочу найти scss, где определен .header__title, искать его по "__title", а потом потом по ".header" или наоборот.
UFO just landed and posted this here
Препроцессоры наоборот помогают использовать БЭМ. Можно же писать примерно так:

Вопрос в том — зачем?

На тупой вопрос тупой ответ: это удобно.

Так наоборот же — очень неудобно.
Вот и вопрос — ради чего жертвовать удобством?

Почти так же удобно как простым каскадом, но получаете плюсы БЭМ.
Почти так же удобно как простым каскадом, но получаете плюсы БЭМ.

Так мы как раз и начали с того, чтобы выяснить плюсы. То есть минусы очевидны — лишняя писанина, что делает использование БЭМа неудобным.
А что их плюсов? Вроде как снимается проблема изоляции стилей, но если использовать современные фреймворки/shadow dom, которые эту изоляцию в адекватном виде предоставляют, то это становится ненужным, разве не так?

но если использовать современные фреймворки/shadow do

И городить костыли и велосипеды для того, чтобы это работало одинаково везде. Уж проще принять соглашения по именованию классов)

И БЭМ, и современные фреймворки/shadow dom можно считать в этом контексте решением одной родовой проблемы CSS. Можно сказать и «если используем БЭМ, то возможности изоляции стилей современных фреймворков/shadow dom становятся ненужными». Это, например, расширяет список рассматриваемых фреймворков. Ну и об адекватности представления у разных людей разные мнения. Некоторыми например считают абсолютно неадекватным подход CSS-in-JS.

Плюсы от бема описаны на bem.info и это не про изоляцию стилей. Это и упрощение поддержки/рефакторинга и правила позиционирования, и правило применения одинаковых свойств большому количеству элементов. Просто откройте и почитайте bem.info про цсс, там не много

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

Это все про обычный цсс, а не про бэм. Зачем нцжен цсс понятно, мы же тут конкретно бэм обсуждаем, какие задачи бэм решает.

Нет, это как раз про бэм. Вы не разобрались просто.


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


БЭМ это про самодокументируемость, поддерживаемость, внешнюю геометрию и позиционирование, про стилизацию групп блоков, упрощение рефакторинга кода, и другое.


С бемом все разработчики кодят как один при этом не превращая проект в хрупкий кусок говна, взрывающийся от любого прикосновения. При этом на новой работе не придётся привыкать к неким новым правилам кодирования цсса


Без бем все разроботчики договариваются о своём неком стиле кодирования, при этом на каждой новой работе_без_бэма правила разные — это удлинняет процесс адаптации новых сотрудников.

Нет, это как раз про бэм.

Погодите, еще раз. В цсс все это есть, что к этому добавляет бэм, если оно уже есть, без бэма?

что именно есть в цсс?
В цсс все это есть

А можете привести конкретный пример того, как описанное выше в комментарии достигается с помощью «обычного» CSS, без всякого БЭМа и т.д. Сейчас складывается впечатление, что вы потралливаете. Причём второй комментарий подряд)

А можете привести конкретный пример того

Ну давайте тогда с конкретным примером, по поводу чего надо привести пример, чтобы не было ненастоящих ирландцев ;)


Типа: "вот так оно в БЭМ: ..., это решает задачу Х за счет Y, как в данном случае решить Х без БЭМа?".

Типа: "вот так оно в БЭМ: ..., это решает задачу Х за счет Y, как в данном случае решить Х без БЭМа?".

Тут в комментариях много кто уже об этом написал, зачем повторяться?)

Если бы кто-то в комментах написал — вы могли бы привести ссылку на коммент. Но не привели. Потому что никто не написал :?)

БЭМ не добавляет ничего к CSS, БЭМ наоборот накладывает запрет на использование всех возможностей CSS, в этом его суть.
Блин. Цсс это технология или язык если угодно, бэм — методология наподобии архитектурного паттерна. Какие задачи решают паттерны?

Задачи унификации и коммуникации. Как в этих задачах помогает БЭМ?

Собственно унифицирует подход к написанию CSS и упрощает коммуникации путем введения терминов, а так же правил именования.

Ну вот беру я условный ангуляр, там есть те же по смыслу термины, при этом их семантика еще и форсируется на уровне самого фреймворка (например, изоляция стилей гарантирует, что внутри "блока" можно управлять только стилями "элементов" и внутренними стилями самого блока, без плясок с именованием и самоограничений).
Зачем БЭМ? Он в данном случае будем выступать как ненужная дублирующая концепция, разве нет?

БЭМ прежде всего для «голой» вёрстки, без ангуляров и реактов. Хотя может применяться и с ними, если игнорировать возможности фреймворков по стилизации, полностью или частично. С таким же успехом можно спросить зачем в ангуляре сделали изоляцию стилей, если уже есть БЭМ? Грубо, это конкурирующие подходы к стилизации, со своими плюсами и минусами, и надо смотреть по конкретным проблемам и задачам. Вводить ангуляр только для изоляции стилей без использования остальных его возможностей — явно не самое удачное решение будет (если вообще єто будет возможно, если он не вынудит нас использовать и другие его фичи типа биндингов и директив), если проблема у нас только со стилями.
С таким же успехом можно спросить зачем в ангуляре сделали изоляцию стилей, если уже есть БЭМ?

Потому что в ангуляре изоляция работает на уровне фреймворка без дополнительный усилий со стороны программиста. Просто работает.


БЭМ прежде всего для «голой» вёрстки, без ангуляров и реактов.

Ну то есть при использовании полноценных фреймворков БЭМ не нужен. Это просто костыль. Так?

Нет, она требует дополнительных усилий. При обычной организации стилей изоляции нет (если не использовать БЭМ :) и ко). ФРеймворк требует прилагать особые усилия, чтобы была изоляция.

Не путайте «не нужен» и «появляется альтернатива». Грубо, без ангуляра у вас две альтернативы: спаггети и БЭМ, а с ангуляром три: спагетти, БЭМ и средства ангуляра.
Нет, она требует дополнительных усилий.

Эм, нет. Фреймворк все делает сам.


спаггети и БЭМ, а с ангуляром три: спагетти, БЭМ и средства ангуляра.

Но зачем использовать БЭМ, если есть некостыльные методы, которые делают то же самое, но лучше и без дополнительных телодвижений?

Сам он не делает, нужно соблюдать правила фреймворка чтобы изолировать стили. Например подключать их в JS-коде компонента а не обычным тегом link. Или вообще писать их нестандартным способом, какой-нибудь CSS-in-JS со своей спецификой типа обязательных кавычек вокруг имён CSS-свойств со знаком -.

Изоляция стилей во фреймворках — тоже костыль для обхода недостатков CSS, просто другой подход к проблеме изоляции стилей.
Сам он не делает, нужно соблюдать правила фреймворка чтобы изолировать стили.

Но это не требует каких-то дополнительных усилий, вот в чем суть. Использование БЭМ — требует.

Чтобы соблюдать какие-то правила написания CSS кроме стандартных всегда нужно прилагать дополнительные усилия. А прилагать их для соблюдения правил БЭМ или фреймворка — вопрос выбора. Например, выбирать между усилиями по написанию длинных имён классов или по экранированию имён свойств и сеелеторов, да настройке окружения для этого.
Чтобы соблюдать какие-то правила написания CSS кроме стандартных всегда нужно прилагать дополнительные усилия. А прилагать их для соблюдения правил БЭМ или фреймворка — вопрос выбора.

Конечно нет, ведь есть еще вопрос количества усилий. В случае фреймворка — они практически нулевые, примерно на том уровне, когда их и вовсе нет. В случае БЭМ — они выше на порядок.


С-но, ведь тот же ангуляр при изоляции стилей, по сути, делает ровно то же самое, что в делается в БЭМе, только автоматически. В БЭМе это надо делать руками.

Он не делает этого автоматически, чтобы он сделал нужно как-то указывать какой компонент с каким CSS файлом связан. Ну никак иначе фреймворк не догадается какой файл стилей с каким компонентом связан. Это я исхожу из предположения, что в ангуляр таки можно как-то вообще связать CSS файл и компоненты, а то может быть что новый язык стилей нужно будет учить
Ну никак иначе фреймворк не догадается какой файл стилей с каким компонентом связан.

Зависит от архитектуры. В MAM архитектуре, сборщик вполне понимает, что эта группа файлов относится к одному модулю. Другое дело, что проблема конфликтов имён куда лучше решается семантическими неймспейсами, чем изоляцией.

Он не просто так понимает, а вы ему указываете, что эта группа файлов относится к одному модулю, помещая их в одну директорию.
Он не делает этого автоматически, чтобы он сделал нужно как-то указывать какой компонент с каким CSS файлом связан.

Естественно, мысли фреймворк не читает. Вы говорите, ему, какие стили как изолированы, и он автоматически обеспечивает эту изоляцию. Именно про автоматическое обеспечение изоляции речь и идет. В случае БЭМ вы это делаете руками.

В случае БЭМ — они выше на порядок.

Если фреймворк по настоящему умеет в БЭМ, то наоборот ниже на порядок, так как не надо прокидывать классы — они генерятся автоматически исходя из дерева компонент и их семантики. При этом не усложняя кастомизацию и понимание отрендеренного дома, в отличие от различных форм изоляции.

Если фреймворк по настоящему умеет в БЭМ, то наоборот ниже на порядок

Ну, с-но, как тот же ангуляр, там ведь изоляция де-факто по БЭМу и работает. Вот, с-но, и вопрос — зачем руками делать параллельный БЭМ, если фреймворк делает тот же БЭМ под капотом автоматически. Ненужно, выходит.

Ангуляр не делает БЭМ, он делает изоляцию. А потом программист с этой изоляцией героически борется. Ненужно, выходит.
Ангуляр не делает БЭМ, он делает изоляцию.

Семантически, он делает ровно то же самое, что и бэм.


А потом программист с этой изоляцией героически борется.

Зачем?

Семантически, он делает ровно то же самое, что и бэм.

БЭМ даёт каждой сущности уникальное имя, по которому понятно что она из себя представляет и кому принадлежит.


Изоляция позволяет разным сущностям давать одинаковые имена, если они объявляются в разных местах, а потом без конца путаться между этими именами.


Где вы тут увидели "ровно то же самое"? Особенно семантически.


Зачем?

Кастомизация компонента под контекст использования, например.

БЭМ даёт каждой сущности уникальное имя, по которому понятно что она из себя представляет и кому принадлежит.

И изоляция так же реализована.


Где вы тут увидели "ровно то же самое"? Особенно семантически.

Ну как где? И там и там добавляются "лишние" селекторы для возможности различить конкретное место применения стилей.


Кастомизация компонента под контекст использования

Эту возможность должен предоставлять сам компонент.

И изоляция так же реализована.

Ага, только эти нагенеренные имена понятны исключительно машине, но не человеку. И дают контекст лишь первого уровня. Примеры разных уровней на человеческом языке / в машиночитаемом бэм-виде (pin — сторонняя библиотека, ya_mail — конечное приложение) / "изолированном" виде :


  1. Кнопка / pin_button / wsri_button
  2. Кнопка очистки инпута / pin_input_clear / wqrl_clear
  3. Кнопка очистки поискового поля / pin_search_clear / wqrl_clear где-то внутри wprl_search
  4. Кнопка очистки поиска по списку пользователей / ya_mail_users_filter_clear / wqrl_clear где-то внутри wprl_search где-то внутри vprl_users
  5. Кнопка очистки поиска по списку пользователей в выпадающем меню выбора адресата / ya_mail_recepient_popup_filter_clear / wqrl_clear где-то внутри wprl_search где-то внутри vprl_users где-то внутри vqri_recepient

Эту возможность должен предоставлять сам компонент.

А программист должен писать без багов, а компьютеры не должны ломаться, а мир должен быть без войн. Выпьем же за идеальные сферические компоненты в вакууме, предоставляющие богатые возможности по любой кастомизации и поддержка которых не требует команды из 10 человек на постоянной основе.

Ага, только эти нагенеренные имена понятны исключительно машине, но не человеку.

А зачем их человеку понимать? В том-то и дело, что при наличии изоляции вам вообще не нужно смотреть на эти имена. Они не несут никакой информации, которую вы могли бы использовать. И не важно, нагенерены они рандомно или не рандомно.
Именно в этом смысл изоляции.
Было бы удобно, чтобы инспектор вообще их не выводил, и в этом плане как раз нагенеренные имена удобнее, т.к. сразу понятно что их надо игнорировать и они никакой информации не несут и ни на что не влияют. С другой стороны, если вы видите какое-то осознанное именование — в этом уже нельзя быть уверенным, что усложняет разбор стилей. То есть с рандомными идентификаторами стили смотреть проще.

Чтобы понимать что где откуда зачем и почему в незнакомом вам приложении. Вы предпочитаете не замечать проблему — ваше право.
Чтобы понимать что где откуда зачем и почему в незнакомом вам приложении.

Именно так, даже в незнакомом. Изоляция гарантирует что у вас сразу есть вся необходимая информация для понимания. Вам не надо чего-то искать, разбирать имя класса и т.п. вещи.



Какой компонент править, чтобы добавить стили в h1 а для каунетра уровнем выше?
Сколько вы потратили времени на выяснение?
Как думаете, как это время зависит от размера и сложности приложения (константно/логарифмически/линейно/экспоненциально)?

Какой компонент править, чтобы добавить стили в h1 а для каунетра уровнем выше?

Не совсем понял вопрос, стили можно добавить большим количеством способов, мы вароде говорили о том, чтобы определить каким именно добавлен, но для этого надо видеть селектор, очевидно. Дефолтно, если надо стиль для h1 — это элемент внутри counter, если для counter — это либо my-appz, если селектор на ngcontent, либо :host в самом counter, если селектор на nghost.


Сколько вы потратили времени на выяснение?

Секунд 5.


Как думаете, как это время зависит от размера и сложности приложения (константно/логарифмически/линейно/экспоненциально)?

Практически — константа, т.к. от сложности и размера приложения тут мало что вообще зависит, зависит от определенных особенной структуры дома. С-но, вы вполне намеренно вместо типичного кейза сделали более сложный. По сути, сложнее чем в вашем примере, ситуации быть не может (теоретически — можно построить, конечно, но в реальности очень сомнительно, что такой код будет встречаться чаще, чем на уровне стат. погрешности), т.к. counter прокидывается через 2 проекции.

Ну вот если вы попробуете написать переиспользуемый код, то куча проекций у вас будут идти вперемешку и владелец элемента будет находиться где-то вверху по дому, и его придётся выискивать глазами по чудесным именам атрибутов. И если ангуляр достаточно дубовый, в нём переиспользуемые компоненты наворотить сложно, то в реакте подобная динамика очень даже распространена.


Мне же будет достаточно пройтись по атрибутам самого элемента и всё.


Ну вот если вы попробуете написать переиспользуемый код, то куча проекций у вас будут идти вперемешку

Нет, не будет, я же стараюсь писать хороший код. Но даже если будет:


и его придётся выискивать глазами по чудесным именам атрибутов

ctrl+f в инспекторе и поиск первого вхождения атрибута.


Мне же будет достаточно пройтись по атрибутам самого элемента и всё.

Согласен, это формально удобнее (хотя практически на производительность не повлияет никак). Только какое отношение это имеет к цсс? Смысл-то один — фреймворк и там и там позволяет за время порядка секунд найти принадлежность элемента и исключить (при наличии изоляции) любые проблемы с поиском стилей.

UFO just landed and posted this here
UFO just landed and posted this here
Обратная сторона такого подхода в том, что может появиться 100500 стилевых файлов разных компонентов с одинаковыми классами .foo, .bar, .baz, различающимися только хешем.

Ну так и ладно, чем это может помешать? Я же эти стили все равно не увижу.


а на этапе разгребания этого bloatware.

На каком таком этапе? Вы же работаете с исходниками, а сгенеренных стилей не видите.

UFO just landed and posted this here
А если нужно пофиксить какой-нибудь стиль? Открываем инспектор, а там .foo--q1w2, .foo--a3s4, .foo--z5x6. Дальше приходится искать конкретный стиль методом тыка.

Не понял. Если вы смотрите в исходники — там нет никаких .foo--q1w2, .foo--a3s4, .foo--z5x6, если вы открыли инспектор — то нужный стиль уже перед вами, ничего искать не надо.

UFO just landed and posted this here
UFO just landed and posted this here
Я думаю, это сработает с чем угодно при условии наличия корректных sourcemap

Ну вы же всегда знаете, где она, т.к. видите нужный элемент.

UFO just landed and posted this here
Название класса на нём неоднозначное.

А зачем вам название класса? Просто игнорируйте это название. При изоляции любой стиль применяется к одному единственному компоненту, то есть к тому, который вы сейчас смотрите в инспекторе. Стили других компонентов к нему применяться не могут. Это и есть смысл изоляции — ситуация, при которой есть какие-то неоднозначности с тем, как и к чему применяется стиль, становится в принципе невозможной. То есть если у вас есть button_3232 и button_5454, то не может быть элемента на котором будет сразу оба этих стиля и не может быть двух разных компонентов, в каждом из которых применяется один и тот же стиль.
Вы всегда сразу знаете что, как и куда — даже не глядя на селекторы стиля.
Здесь, видимо, проблема в ментальной модели — вы пытаетесь анализировать получившийся css как обычный css, что неверно. изоляция дает гарантии, при учете которых анализ существенно упрощается.

UFO just landed and posted this here
Получается, единственный выход — правильно настраивать source maps

Зачем? Еще раз — вы сразу знаете, к чему относится стиль, т.к. он не может относиться к чему либо кроме как к компоненту, который вы выбрали.
Вам не нужны ни сорус мапы, ни названия, ни какая-либо еще фигня.


нужно детектировать, в каком компоненте это произошло?

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

UFO just landed and posted this here
Нет. В проекте может быть много похожих компонентов

Ну как нет? Вы знаете место в котором верстка поехала, т.к. вы его по факту видите. Ну, страницу открыли и видите, что на ней что-то не так. С-но, нужный вам компонент — это тот, что отображает данное место. Он вам сходу известен.


Часть из них может разделять одни и те же стили, часть нет.

Изолированные стили не разделяются в принципе, так что не может. Иначе они не изолированные. В этом-то и суть. Если у вас стиль button_3434 то он используется только в одном единственном компоненте, при этом никаких других button_n в этом компоненте быть не может.
Как я и сказал, у вас неверная модель, вы смотрите на получившийся цсс как на обычный цсс. А он не обычный, он обладает некоторыми дополнительными свойствами.

UFO just landed and posted this here
В некоторых реализациях можно разделять, например, в CSS Modules. При этом они остаются изолированными на уровне стилевого модуля, т.е. css-файла.

А это ничего не меняет. Вы знаете, для какого компонента стиль, и далее вы из этого компонента однозначно попадаете в соответствующий css-модуль. Наоборот, тут даже плюс — т.к. вы легко можете посмотреть, какие компоненты еще используют этот модуль и, с-но, где что может (или не может) сломаться, если вы данный стиль поменяете.


В результате у нас могут возникнуть button_3434, button_4343, button_3443, button_4334.

Ну и пусть возникают.


Искать же, какую именно тут использовали кнопку, — то ещё удовольствие.

В каком смысле, что искать? Вы же видите эту кнопку перед собой. Вот у вас кнопка, стиль которой надо оправить, жмакнули по ней и в инспекторе увидели, что это button_foo. Надо поправить стиль соседней кнопки — жмакнули по ней, и увидели, что это button_bar. Что вы ищете вообще? Опишите как-то flow работы для конкретного кейза, где у вас проблемы. Потому что я даже теоретически не могу представить, на каком этапе они могут возникнуть. Что вы конкретно делаете, что у вас возникает неопределенность, где какой стиль?

> Вы знаете место в котором верстка поехала, т.к. вы его по факту видите. Ну, страницу открыли и видите, что на ней что-то не так. С-но, нужный вам компонент — это тот, что отображает данное место. Он вам сходу известен.

Не факт. Какой-то div без классов и айдишника не несёт информации какому компоненту он принадлежит. Но вот назначили баг что кнопка какая-то полезла в проекте который только что команда приняла от заказчика, потому что старую команду он разогнал из-за того что документацию не писали :)
Не факт. Какой-то div без классов и айдишника не несёт информации какому компоненту он принадлежит.

А почему у вас div без класса и идшника вместо тега с именем компонента?

Потому что инспектор ничего не знает про реакты и ангуляры.
Потому что инспектор ничего не знает про реакты и ангуляры.

Он то конечно не знает, но это уже проблема вашего фреймворка в том, что он хост-элементы затер. К цсс и изоляции это отношения уже не имеет.

Имеет. Если фреймворк теряет имеющуюся в коде семантику для изоляции, то эта изоляция не бесплатна для DX
Имеет.

Каким образом-то? Еще раз — это проблема того, как фреймворк хост-элементы генерит. При чем тут цсс?

причём тут генерит? я на корневой элемент компонента класс повесил, а он превратился во что-то непонятное

Класс ни во что непонятное не превращается, он каким был, таким и остается, его не трогает никто.

UFO just landed and posted this here
А зачем мне айдишник на каждом элементе?

Ну вот чтобы вы знали, чей это элемент — за тем и нужен. То, что какие-то фреймворки "без этого справляются" — уже проблема данных фреймворков, и эта проблема ортогональна обсуждаемой.

У вас все компоненты состоят ровно из одного элемента? Ну-ну.
У вас все компоненты состоят ровно из одного элемента?

Конечно же, нет. Но любой элемент принадлежит ровно одному единственному компоненту, в котором находится. Так что если вы видите конкретный элемент, то вы точно знаете, какому компоненту он принадлежит.

UFO just landed and posted this here
Почему вы решили, что я это знаю?

Его название написано. Если читать умеете — то знаете, верно?


Притом, как я уже сказал, похожих.

Да не важно, похожих или нет, имя компонента перед вами, конец истории.

UFO just landed and posted this here

Ну вон выше vintage скриншот кинул, wrappez, my-appz, counter — имена компонетов. В типичном случае вам надо просто по вложенности компонентов пройти вверх до первого "кастомного" компонента (что обычно эквивалентно "посмотреть на несколько строк вверх"), он и будет тот, что нужен. В более сложном (с проекциями) надо пройти выше, до компонента с номером меньшим, чем в ng-content элемента.

А я бы назвал костылем приписывание километрового хэша к имени класса или атрибуту, которым фреймворки и реализуют изоляцию. Костыль работает, но это костыль.
Да и 20 лет опыта разработки в вебе? Где же столько взять.

А что, в 1998 году интернета не было?

В 1998 году не было WebGL, HTML5, CSS3 и прочих. Ну и подход к формированию страниц тоже другой был.
В 1998 году не было WebGL, HTML5, CSS3 и прочих.

Зато украшать сайты с помощью &ltmarquee&gt было не западло. А сейчас никакого удовольствия от дизайна :(
Верстайте письма для email рассылок! Это же прямо как окунуться лет на 20 назад. Табличная верстка, нарезка картинок, указание всех стилей в каждом теге, и вечная оптимизация под разные клиенты… Вот это я понимаю — романтика!
А еще фреймы, куда же без них!
И ничуть не хуже совремЁнного дивнючество работало — на тогдашнем железе и диалапах… )))

Можно подумать, это мешало получать опыт разработки.

Подход был уже тогда — HTML так-то изначально подразумевает разметку смысла, а не внешнего вида (google://семантическая вёрстка). Другой вопрос, что надёжнее было сверстать на таблицах.

И что, что не было? А web был. Html был, js был и css был.
UFO just landed and posted this here
HTML5, CSS3 и сейчас нет.
Воспринимается как фильм ужасов, когда у тебя для 90% аудитории код доставляется в стандарте ES2017 (ES8).
Кто из браузеров реализовал ES5 полностью хотя бы в последних версиях? Кажется даже бабель не может c ES5 до конца разрулиться.
Интереса ради, что не реализовано в хроме или ff, например?
Оптимизация хвостовой рекурсии.
Сорри, да, попутал.
UFO just landed and posted this here
Я не про то, что важен опыт в 20 лет, а про то, что автору необходимо обозначить свой бэкграунд.
… выход книги «Сто авторов против Эйнштейна». Под этим названием были собраны мнения ста ученых, которые опровергали и ругали и теории, и самого Эйнштейна. Говорят, что когда он узнал об этой книге, он спросил: «Почему сто? Если бы я ошибался, хватило бы и одного»
«А я книжку прочла!»?
Я же не запрещаю автору что-то критиковать, а просто обозначить на основании какого опыта он это делает. И не для того чтобы топать ногами и негодовать «молодо-зелено», а чтобы адекватно интерпретировать поданный материал. И еще раз — это относится только к критике технологий, методологий, языков и пр.
UFO just landed and posted this here
В рамках данной статьи, приведенные «конкретные аргументы против» рассматриваются только в контексте создания кода с нуля. Остается непонятным, как предложения из статьи повлияют на процесс модификации проекта под изменяющиеся требования, на удобство реюза блоков из старого проекта в новом, на время, требуемое одному разработчику на поддержку кода, написанного другим разработчиком. Именно в этом контексте хотелось бы узнать, какой у автора бэкграунд, чтобы хотя бы косвенно оценить, с какими проблемами он уже мог сталкиваться в процессе разработки, а с какими скорее всего еще не сталкивался.

А вы верите авторам статей только на основании бекграунда (i.e. авторитет) или всё-таки на основании доказательств в самой статье?

А вот свежий взгляд тут и говорит о проблемах

«свежий взгляд» в вебе это на самом деле новая инкарнация «фатального недостатка» — проблемы одной технологии лечатся созданием новой, со своими проблемами.

Да, 20 лет в вебе. Такое бывает. Как и обречённость: «Щас школьники сайты клепают. Что я до сих пор в веб-разработке делаю?»

Собственно когда они их не клепали? )
Я в 98 году клепал, у меня midi музыка была на страницы была и фреймы (не iframe`ы) :)

Препроцессоры, цссмодули наоборот поощрают бем. Ведь бэм включает в себя правила касающиеся вёрстки, а не только правила именования. Например взять хотя-бы правило по которому блоки не должны влиять на своё позиционирование — это очень многого стоит, и помогает избежать хаоса в крупных проектах через годик.
Или например модификаторы — это тоже лютый мастхев, и позволяет производить избавление от говнокода.


Когда верстаешь один то конечно ты можешь это делать как хочешь, а когда вас 10 разработчиков и ты там главный то тебе нужно чтобы каждый разработчик верстал правильно и не допускал говнокода. Правила бэма позволяют это сделать.
Бэм это когда 9 женщин за 1 месяц раждают здорового

Да и 20 лет опыта разработки в вебе? Где же столько взять

Об том, что можно быть фрилансером, я узнал от одного веб-мастера.

Где-то в конце 20-го века он уже вовсю работал из России на иностранных заказчиков.
Делал им сайты.
Не поможет. Даже, имея 20-ти летний опыт разработки… Если этот опыт основывался на шаблонах, придуманных кем то не очень вменяемым — то все 20 лет псу под хвост.
Есть спецификация, есть описание обработки кода в барузерах — всё, этих текстов должно быть достаточно.

Автор статьи правильно негодует по поводу БЭМ-а, этот маразм вообще не должен был появиться, но сам даже близко не подошел к использованию спецификации «как надо».
В первом же примере, он для наглядонсти, сокращает код:
<ul class="article-rewind type-static lang-ru">
    <li class="next">
        <div class="text">Читать далее</div>
        <a class="link" href="">Основные понятия</a>
   </li>
</ul>


Но, что ему мешает сделать так: (ведь перед ul уже есть какой то старший тег, допустим div id=«i_1_», этот ul не в воздухе первым на странице повис)

<ul>
    <li>
        <div>Читать далее</div>
        <a href="">Основные понятия</a>
   </li>
</ul>
/*в css */
#i_1_ ul {}
#i_1_ ul>li {}
#i_1_ ul>li>div {}
#i_1_ ul>li>a {}
/*при необходимости*/ 
#i_1_ ul>li:nth-child(n) {}
#i_1_ ul>li:nth-child(n):first-line {}


Зачем тащить в html код кучу бесполезного, нагружающего парсер самого браузера (и особенно парсеры ПС) бредотекста с классами, лишними тегами и прочей чепухой?

Повторюсь — есть спецификация, она работает, зачем выдумывать какие то НАД-спецификации и кучу мусорного текста. Если кто-то будет спорить, что классы нужны для наглядности кода в больших проектах — то, как раз, автор тут вам всё и показал, что, наоборот, куча бредотекста не добавляет читабельности коду, а лишь ухудшает её.

Есть несколько вопросов:
Над какими проектами с каким количеством людей вы работали?
Использовался ли в этих проектах предложенный вами подход(#i1 ul>li>div {}) ?
Встретились ли вам какие-нибудь минусы ?

Частично согласен с вашими словами. Иногда сам тип вложенного тега говорит за себя и к нему можно не приписывать class/id. Наверное наиболее частый тег без класса у меня это img. Оно и понятно :)
Но большая вложенность из безымянных тегов тоже не очень удобна. В этом случае удобнее присвоить класс нужным тегам и обратиться к ним напрямую.

Это порядка не добавляет в проекте

UFO just landed and posted this here
Парсер не нагружает, парсер работает один раз и все подобные вещи индексирует. А вот увлекательные сайдэффекты связанные с неожиданным весом селекторов, жесткой привязкой порядка вложения тегов друг в друга и невалидной версткой (в li нельзя блочные элементы) — наличествуют.
По вашему выходит лучше жестко завязаться на структуру html в css через такие специфичные селекторы и потом при каком либо изменении верстки править все сразу.
В моей практике верстка диктуется стилями. Так что пока стили менять не понадобилось — структура html не изменится.

И обосновывается это просто. Что серверу, что клиентскому фреймворку одинаково просто сформировать html любой структуры. А вот дизайн не на любую структуру «налезает» одинаково хорошо. Поэтому всем проще структуру html подогнать под запросы css.

Мне кажется наоборот все. Создаем разметку и потом лепим ней стили. При добавлении элемента разметки выстраиваем стили по новой(обновляем). Разве не так?

Ну, у нас стили писал отдельный человек, верстальщик-дизайнер, который делал статическую страницу. А потом эти стили использовались разработчиками, наполнявшими эти страницы динамическим контентом и поведением. И тут с версткой было все просто — правильная верстка это та которая не ломает стили.

И с языком аналогично


<html lang="ru">
...
<ul>
БЭМ ничуть не противоречит спецификации, не нарушает правил, не вводит новый синтаксис, не требует изменений в движках браузеров. Только то использует, что браузеры обеспечивают из коробки.
Слушайте, но на развернутое утверждение в статье нельзя просто взять и ответить «нет, не нарушает», без всяких аргументов. Это ж бесполезно. Одобрят только те, кто с вами изначально согласен.
Попробовали бы разработчики использовать то, что браузеры не поддерживают, конечно. Но собственно спецификация html задает тегам семантику. h1 — это тег заголовка. Бэмчики кладут на спецификацию и создают свой значит класс «desktop-header__title», для них он имеет значение, а сам тег html (h1) -нет. Не удивительно, что зачастую везде используется только div. Даже функционал ссылок симулируется с помощью div и javascript, ну что это такое? Работает? Работать может и не такое, но вы не видите здесь нарушения спецификации? И как же это не называть новым синтаксисом? Не оценивать с позиции читабельности со старым синтаксисом? До требования изменений в движках браузеров докатиться — эт надо очень сильно упороться, но наделать бэм тож надо умудриться.
Но собственно спецификация html задает тегам семантику. h1 — это тег заголовка. Бэмчики кладут на спецификацию и создают свой значит класс «desktop-header__title», для них он имеет значение, а сам тег html (h1) -нет.
Семантика и стилизация это почти ортогональные вещи.
Даже функционал ссылок симулируется с помощью div и javascript, ну что это такое?
Тут вообще ловкая подмена понятий. Эмуляция ссылок через div+js — это одна из самых плохих практик, она всячески порицается, и к БЭМ-у имеет отношение… правильно, никакое.
А заворачивать дивы в ссылки — хорошая практика? К сожалению, эмуляция ссылок через js там, где это вообще непонятно зачем имеет отношение к Яндексу, Вадим Макеев их на этом ловил, причем несколько раз. Это во-первых. Тот же Макеев ругал Яндекс за увлечение дивами и игнорирование многообразия тегов. Я вот перед тем, как предыдущий пост писать, сам сбегал на Яндекс Дзен. Элементов не много, но тега h1 нет в помине. Вы скажете, это не имеет отношение к БЭМу и тому, что они ориентируются практически только на классы, по минимуму используя правила типа ul>li? Теоретически, оно может и ортогонально, но вот на практике видите как выходит. Семантика летит на три буквы.
UFO just landed and posted this here
В любом случаи, seo это другая тема.
Оно никак не влияет на обсуждаемые вопросы
БЭМ ничуть не противоречит спецификации, не нарушает правил, не вводит новый синтаксис

Я выше писал, что противоречит, нарушает, вводит.
И уж тем более необходимость считаться с seo никак не влияет на мое предложение аргументировать свои мысли, а не бросаться безапелляционными утверждениями. А то сами с собой поговорили, сами с собой согласились, поцокали над другими неумными, у них там каша в голове.
С утверждением что css и html в принципе разные формы я согласен конечно. Ну, вот я когда-то юзал всякие fieldset, legend, label, чтобы мои формы были семантичными и чтоб в них не было противных дивов. Уверен, БЭМщик этим заниматься не будет. Вы скажете, ну, БЭМ не запрещает, он вообще параллельно. Хорошо. Предложите свою объяснение, почему люди, использующие БЭМ переходят на сплошные дивы, только не игнорируйте общую практику. Она ж это самое, критерий истины. Я например в бэмовской верстке такое очень часто замечал. Методология БЭМа имхо к тому подталкивает. Не согласны — предложите другое объяснение моему наблюдению. Что, сам Яндекс плохой пример? Так они же эту методологию и разрабатывают. Где-то есть флагман, в котором все по-другому?
Яндекс плохой пример как раз. Подавляющее большинство требований «семантичная вёрстка» встреченных мною в реальной жизни исходили от сеошников. Ещё немного от необходимости поддержки скринридеров и подобных кейсов.

В целом же, уверен, что поддержка или неподдержка html семантики мало зависит от используемой методологии, это вопрос личного выбора разработчика/архитектора. А если даже корреляция сильная наблюдается между отказом от семантичности и использованием БЭМа, то скорее у них просто общая причина, а не причинно-следственная связь «раз используем БЭМ значит отказываемся от семантики». Ну, например, и БЭМ, и верстка только дивами/спанами делают более простым и предсказуемым в разработке и(или) поддержке код веб-приложений. В частности на дивы и спаны навешиваются минимальные (и одинаковые в разных браузерах) браузерные стили касательно шрифтов, границ, отступов и т. п., с которыми не нужно бороться в своих.
UFO just landed and posted this here
У вас жуткая каша в голове.

Если что-то делает Яндекс, это не означает, что так же делают все, кто использует БЭМ. А по поводу заворачивания ссылок в div. В HTML5 согласно спецификации стало возможным помещать в ссылки блочные элементы. В предыдущей версии действительно с точки зрения спецификации это было недопустимо. Однако согласитесь, что иногда удобнее поместить весь большой блок в одну ссылку, нежели делать внутри блока несколько разных ссылок, которые ведут на одну страницу. Удобнее хотя бы потому, что область клика многократно расширяется: куда не ткни, не ошибёшься.

Та переопределите ссылку и спаны в ней на блок через css и сохраняйте html валидным, а оформление — по макету. Делов-то. По-моему, это первое, что приходит в голову.
Я ссылаюсь на Яндекс, потому что ссылаться на своих знакомых — бэмщиков нет смысла, они кроме меня никому не знакомы. Но все описанные мной тенденции и у них на месте. И пример с бла-бла-title, вместо h1 не выдуман и показателен. Люди мыслят иначе, чем тегами + правилами css с дополнением классами. Мыслят одними классами + стилизация ss без c. Это уже совсем другое качество синтаксиса.
Я выше писал про то, что я использовал по максимуму теги форм т.к. это позволяло с одной стороны, поддержать код семантичным, с др. обернуть все в блоки и сделать по макету. Я использовал микроразметку например в адресах т.к. это опять же позволяло прицепиться ко многим элементам, не внося лишних элементов в html. Я использовал blockquote для цитат т.к. там не просто кавычки, а цитаты, их оформление может отличаться от просто текста с кавычками. И чем более семантичный код я получу, тем больше власти для стилизации css буду иметь, сохраняя код чистым от лишней инфы в классах. Связь прямая. Сохраняется ли она с использованием БЭМ? Когда в классах больше инфы, чем в самих тегах? Ну, нифига не сохраняется. Можно продолжать верстать семантично? Можно, но зачем? Кому оно надо? Сеошники конечно могут потребовать, но что-то я не наблюдаю такой тенденции.

Стили на тегах использовать не очень хорошая идея. Вы завязываете стили на структуру страницы. И если что-то где-то поменяется (даже небольшие изменения в структуре), стили придется переписывать. Естественно, что сброс браузерных стилей придется делать на тегах, иначе-то и не выйдет.


Когда в классах больше инфы, чем в самих тегах?

Когда классы имеют осмысленные названия. Теги обычно мало о чем говорят о том, что за блок перед нами, кроме пространного "список", "блок текста", "навигация" и т.д.

Вы считаете, что CSS БЭМ не пройдёт валидацию по спецификации? И не забывайте, что CSS-классы ортогональны HTML-семантике. Эта семантика про разметку текста, CSS — про (визуальное) представление. Для СSS не существует HTML-семантики, теги для CSS лишь абстрактные идентификаторы тегов. h1 или div в HTML для CSS не имеет значения вообще (считаем что браузерные стили сбрасываются для всего), а имена CSS-классов никакого значения для HTML не имеют.

То, что какие-то верстальщики не соблюдают семантики HTML, когда работают по БЭМ, не проблема и не вина БЭМ. Она ничего подобного не требует и не рекомендует. Ну то есть вообще не связано это, кроме каких-то паразитных ассоциация в мозгах некоторых верстальщиков типа «теги в селекторах не используются — всё заменяем на div». Я не понимаю как к этому можно прийти, хотя сам в своё время практиковал чисто «дивную» вёрстку, без всякого, заметьте БЭМ, которой тогда даже в зачатке не было, если верить официальной истории.
Я понимаю, что css и html — разные инструменты. Но вот когда коллега доказывает мне приемущества БЭМа на примере
<div class="бла-бла-бла-родословная-title">Я заголовок</div>


и говорит, что мол, смотри, я могу с помощью вот это длинной штуки с title на конце отловить все заголовки, у меня появляется вопрос, а почему бы не сделать h1, h2 и ловить все заголовки по данному тегу в css? Почему нужно забыть про первое слово в Cascading Style Sheets? И вы сколько угодно можете доказывать мне, что БЭМ не заставляет писать так, но вот посмотрю на верстку яндекса, на верстку использующих БЭМ знакомых — вижу, что как не бэмовец, так обязательно divиантное поведение замечаю. Есть у меня версии почему так происходит? Есть, озвучил выше. Я не заставляю вас с собой обязательно соглашаться, но мне кажется, меня легко понять, если не упрямиться.
UFO just landed and posted this here
Мило, когда вы выдвигаете аргумент и сами же его опровергаете. Так что, все зло от SEO и это именно они делают БЭМ целесообразным?
Я так и знал.

Если серьезно, мне никто, никогда не говорил «мы делаем это из-за сеошников» т.е. пример конечно логичный, но насколько он реалистичный?
UFO just landed and posted this here

Я вам дополнительно говорю что никто не заставляет вас использовать в разметке только дивы. Но если используете h1 то у него должен быть class с чётким именем. Если в цссе будете навешивать стили на имена тегов то это увеличит вес селектора и в будущем может привести к проблемам. Как правило никто не любит проблемы, нолюбит поддерживаемость. Делайте как рекомендуется в бэм, и получите то любите

Как-то на хабре комменты расскиданы по веткам странно. Вроде отвечал в рамках одной беседы, а выходит много веток комментариев. Может с этим связана некоторая неразбериха. Я отвечал на коммент о том, как бэм влияет на синтаксис. В контексте этого вопроса, я написал, что БЭМ таки влияет на синтаксис и провоцирует использование div.
Но я при этом согласен с тем, что БЭМ задает четкие указания на именование классов, стандартизирует процесс верстки и делает его более поддерживаемым для больших команд. Это другой вопрос.
UFO just landed and posted this here
Версии это «Не удивительно, что зачастую везде используется только div.»? Вот для меня удивительно. Не, я могу предположить причины, но к БЭМ они отношения не имеют, например, пресловутое «придёт SEOшник или спец по адаптации у ограниченным возможностям и скажет поменять теги». Если такая мысль появилась, то БЭМ или нет на проекте — глубоко по барабану по моей выборке. По вашей версии БЭМ чем-то провоцирует такие мысли? Как по мне то только частично и вывод у меня противоположный вашему: поскольку по БЭМ мы не привязываемся к тегам, то ничто нам не мешает менять div на более подходящие по семантике или другим факторам типа посикового ранжирования, доступности и т. п. элементы. В «теговой» вёрстке предложение «а давайте сменим div на h1 в таких-то случаях» очень легко может вызвать отторжение у разработчиков как только они представят сколько селекторов надо будет переписывать, причём внимательно следя за тем какие надо переписать, а какие нет.
Вопрос в том, что без БЭМа теги влияют на код больше, чем с ним.
Отвечал выше
habr.com/post/422537/#comment_19088331
Но я ж не только теоретизирую, я делюсь практическим наблюдением. Бэмщики злоупотребляют div-ами. Можете не соглашаться или предложить свою версию, почему. Для меня ответ на кончиках пальцев. Семантика сместилась на классы.
Простая версия: между БЭМ и отсутствием семантичных тегов нет причинно-следственной связи, есть корреляция из-за общих причин. Люди решают какую-то проблему в верстке в целом, и на уровне CSS решают её БЭМом, а на уровне html отказом от семантичных тегов.
, а имена CSS-классов никакого значения для HTML не имеют.

Имена классов, вообще говоря, и для css никакого значения не имеют. По крайней мере не большее значение, чем имена тегов.

Подобное требование — типичный пример аргумента "сначала добейся". Когда автор представляет всю логику, лежащую в основе выводов, в дебатах, основанных на логике, принято строить контр-аргументы к аргументам автора, а не к его личности или заслугам, к которым относится мифический опыт.
И тем не менее возможно стоит согласиться с тем что использование BEM ухудшает читаемость кода. Столь длинные и сложно структурированные названия классов читаются как каша и требуют дополнительного времени на осмысление. Это так-же повышает вероятность опечаток и ошибок. Ну и усложняется повторное использование элементов.
А вот радикальные заявления в стиле «Технология\методология\соглашение X это плохо\не должно существовать\ненужна.» на хабре встречают, в первую очередь, скептические оценки. Часто заслужено.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Имея за плечами примерно 15-летний опыт фронтэнд-разработки, я согласен с автором статьи, BEM'а не должно существовать
бэм, это просто, быстро, понятно. Реальных альтернатив нет. Если кто-то в голове держит несколько технологий, то представьте статью, которая подобно этой будет перечислять не только минусы, но и реализацию. Мне кажется, что жести будет куда больше. Остается ждать поддержки shadowdom.
Реальная альтернатива — styled components (для React) и однофайловые компоненты со scoped-стилями (для Vue), пока shadow dom не принял такое распространение. В случае таких компонентов, ты придумыввешь стили в рамках компонента, и потому по сему, отсутствует ограничение глобального пространства имён.

Возможно, я не прав, но на мой пре-джуновский взгляд, так кажется
UFO just landed and posted this here
Можно собрать фронт, потом натянуть на бекенд.
Есть еще вот такая штука
У scoped стилей есть огромный недостаток — нельзя стилизовать через родителей. В бэме можно спокойно написать, что block2 с модификатором mod, лежащий внутри block1, будет иметь такие-то стили. В scoped стилях мне для этого пришлось фигачить внутри компонента data-атрибут, который добавлялся в определённые моменты. Это очевидный костыль и вообще неправильное использование.

А вообще scoped-стили имеют все недостатки БЭМа из статьи, только умноженные на 10.
Глобальные стили не переиспользуешь, только если в случае БЭМа всё-таки как-то можно ухитриться, то тут вообще никак.
Не нравится html-ка такого вида?
<div className="block block1_mod1 block1__element_mod1 block1__element_mod2">

Так получи же такую:
<div className="block_abcdefghijklmop123456 block_qwertyuiop98765 block_asdfghjkl6574849 block_bvncmzasnsk463901289">
И так далее.

Понятия не имею, зачем избавляться от БЭМа в пользу scoped styles.
Последний пример не понял. По количеству классов очень напоминает BEM…
Вы пишете такой вот css:
.button {}
.active {}
.size_big {}

Затем пишете такой вот jsx:
import cl from './styles.css';
...
return <button className={[cl.button, cl.active, cl.size_big].join(' ')}></button>

Итоговая ваша вёрстка выглядит примерно так:
<button class="button__button_214914283c7dd64040bec5c61d9fe59b button_active_6792e285b0931148ef0f16d0b444c2bc button_size_big_a9f74cda406500c9b9c3e0125b242b0f"></button>

Сравним читаемость с БЭМ?
<button class="button button_active button_size_big"></button>
Извиняйте, но я так не пишу )
А как вы пишете?
Кажется, что это вполне типичный компонент с типично используемым scoped styles.

Что мешает настроить цссмодули чтоб не было хешей?

Без хэшей вы в итоге получите БЭМ в том или ином виде.
У меня в коде, у фб в коде, да и у всех кто порылся в настройках, хеши составляют 4-5 знаков. Просто потому, что поняли как оно работает.

Ну и ещё у меня в коде сразу херится изначальные названия классов, но это уже спицифика (конечный код в проде никто не читает).
<button className={[cl.button, cl.active, cl.size_big].join(' ')}></button>

У меня это выглядит так
<button className={cn(cl.button, cl.active, cl.size_big)}></button>

Где cn — это classnames.
И ваше сравнение не совсем корректное, речь об исходном коде и удобстве его написания, так что нужно сравнивать это:
<button className={cn(cl.button, cl.active, cl.size_big)}></button>

с этим
<button class="button button_active button_size_big"></button>

учитывая, что классы по бэму могут вырастать до неприлично больших размеров, чего нет в css modules.

Ну и автодополнение прекрасно работает с css modules
classnames сделал пример короче на 5 символов. Я тоже его юзаю, но в данном случае не добавил, т.к. зачем привносить новые сущности туда, где они принципиально ничего не меняют.

Эм, нет. Моё сравнение абсолютно корректно. Я сравнил код, который получается на выходе. Потому что в самой статье, как я понимаю, также речь идёт об итоговом коде (который вполне себе появляется в веб-инспекторе, и его надо отлаживать). И тут button_size_big_a9f74cda406500c9b9c3e0125b242b0f никогда не будет читаемее, чем button_size_big.

Ладно, давайте тогда сравним исходный код. Если у вас классы в БЭМ разрастаются до нечитабельности, то вы что-то делаете не так. Это сродни тому, что использовать React без JSX и жаловаться, что код слишком большой и нечитабельный получается.
Потому что либо вы используете i-bem, и у вас примерно такой код:
{
  block: 'button',
  mods: {
    active: true,
    size: 'big'
  }
}

Либо же вы пишете например в реакте, и вам стоит просто заюзать какую-нибудь функцию наподобие classnames, которая замечательно сделает всё то же самое с модификаторами:
<button className={bem({
  block: 'button',
  mods: {
    active: true,
    size: 'big'
  }
})}></button>

В bem-react могут быть какие-то такие штуки, я не выяснял.

В CSS всякие препроцессоры вроде stylus тоже замечательно всё упрощают:
.button {
  &_active {}
  &_size_big {}
}
У scoped стилей есть огромный недостаток — нельзя стилизовать через родителей.

Можно так


.parent-class :global(.child-class) { /* ... */ }
Так получи же такую:

Попробуйте для localIdentName в опциях css-loader использовать следующий шаблон для дев-режиме: `[name]-[local]-[hash:base64:5]`. Более того, вы можете как угодно настроить этот шаблон под себя, и тогда у вас не будет неожиданных неожиданностей и непонятных непоняток.

Про :global ниже уже написали, но вообще scoped стили для того и scoped, чтобы быть scoped, не? Хотите переиспользовать стили — для этого есть удобные инструменты: `@import`, `@include` и `@extend` в scss и `composes` в post-css.

Бэм не только про уникальность имён классов!
Главная его фишка это порядок в вашей вёрстке.
на large-scale проектах это оооочень хорошо чувствуется.


Не надо говорить что с приходом стулед

Упс недописал…
Не надо говорить что с приходом мтулед-Сомпонентов и цссмодулей бем становится не нужен.

UFO just landed and posted this here
UFO just landed and posted this here
Вроде как даже не просто можете, а под этот сценарий, компоновки блоков из блоков, он и заточен изначально.

Вы правильно говорите, но позволю вас дополнить:
Бэм не только про пространства имён.
Он ещё и про правила по уменьшению связанности кода, про формирования стилей отвечающих за внешнюю геометри блока, применение груповых стилей, и куча другого.


Цель всего этого увеличить поддерживаемость упростить переиспользование и рефакторинг.

Сегодня он у вас белый, а завтра дизайнеры решат сделать жёлтым. Более подходящие имена: -main, -primary, -payed.

С год назад пришёл к выводу, что даже "-main, -primary, -payed" не помогают.) Ибо через время, понятия что есть prymary, а что есть secondary — также достаточно сильно размываются. Поэтому начал все переменные обзывать просто $color_1, $color_2, $color_3 ..., $breakPoint_1, $breakPoint_2, $breakPoint_3… Как оказалось, в долгосрочной перспективе удобнее. При редизайнах не нужно думать, куда какой цвет прилепить, добавить новый или менять по всему проекту переменные.
PS ide и редакторы подсвечивают sass переменные соответствующим цветом — запоминать не нужно.
И как не используя браузер разобраться в вашей писанине?
UFO just landed and posted this here
Что будет когда корпорация сменит дизайн с желтокрасного на синезеленый? Переменные так и останутся желтыми?
UFO just landed and posted this here
Как правило, «желтый» — это несколько оттенков для фона, текста и рамок. Выполнить полную замену по папке src с $text-red -> $text-blue не очень сложно. Я сам, конечно, полностью поддерживаю наименование переменных исходя из контекста и семантики, а не значения, а то так недолго докатиться до
for (var zero = 0; zero < n; ++zero)
не проще ли работать со стилями? Мне кажется, многие забывают или не знают про root.

:root {
  --primary-color: #f4d249 // корпоративный желтый
}

li {
  background: var(--primary-color); /* хоть для фона */
  border: 1rem solid var(--primary-color) /* даже сюда */
}
li a {
  color: var(--primary-color) /* хоть для текста */
}

тыкаем во все необходимые блоки — меняем 1 раз. Нужен зеленый? Меняйте и все само встало. Не нужно бегать по всем блокам и менять цвета
Изменить имя переменной.
Конечно так и будет, как вы написали. Но не надо делать так, как вы написали. Если у вас лендинг со сложной вёрсткой — не уходить от БЭМ. Если у вас приложение — используйте css-modules.
Можно точно указать на элемент, чтобы небыло конфликта. Типа того:
.article-rewind {
  & > .link {
    ...
  }
}
Ужасное решение, и БЭМ и css-modules и прочие вещи изобретали, чтобы не надо было писать такие больные селекторы.
Пробовал так делать. Поддерживать это невозможно.
Мои примеры кода лишь показывают, насколько всё могло быть красивее, семантика сохранена разработчиков Yandex'a. Возможно, я бы сверстал совершенно по-другому. Статьёй хотел показать на живом примере, что есть способы намного читабельнее и логичнее, чем использовать BEM.

Просто любым инструментом нужно уметь правильно пользоваться.


Похвалите BEM в статье, которую напишите вы, возможно, я передумаю, если хорошо опишите и докажете.
И да, много пишут: критикуешь — предлагай. Хочу предложить архитектуру и идею Bootstrap'a, похвалить SMACSS и OOCSS, чем и займусь в слудеющих статьях.
UFO just landed and posted this here

Bootstrap тоже не идеален, когда дело касается переопределения стилей его компонентов. Там тоже полно привязок к тегам, тройной и более вложенности селекторов.

Парадокс в том, что читать верстку, написанную с соблюдением БЭМ несравнимо удобнее. Стоит только начать, вернуться назад желания уже не возникнет.
Вопрос применимости данной технологии. Как вы озвучили выше, методология используется крупными проектами и популярна в СНГ, любой инструмент в неумелых руках может привести к хардкоду и костылям, а в умелых — в мощный инструмент, позволяющий облегчить жизнь и упростить разработку.
Методология БЭМ не только в СНГ популярна. Например, MDL (а нынче MDC), который рекомендует Google для веб-разработки в стиле Material Design как раз использует БЭМ. Есть ещё куча примеров использования БЭМ'а на западе.
«Критикуешь-предлагай»
Хотелось бы тогда увидеть приведенные вами альтернативы БЭМ'у, хотя-бы с краткими объяснениями почему они лучше.
Автор же прозрачно намекает, что говнокод решает все проблемы
И судя по количеству плюсов к этому посту, автор такой не один
Отвечу за автора. Есть например RSCSS. Идея там та же — компоненты, элементы, варианты. Решает все эти проблемы с длинными именами классов, нечитаемым HTML; есть хелперы, которые можно применять куда угодно.

Из минусов — постоянно находятся люди в интернете, которые говорят, что если добавить обертку вокруг элемента, то все сломается (т.к. все строится на непосредственной вложенности). Но за последний год ни одного такого случая не припомню. Может сам дурак, а может и нет этой проблемы.
Очевидно, у вас очень слабая переиспользуемость кода. Попробуйте разбить ваши страницы на компоненты. Особенно на компоненты со слотами.
Так разбиение идет по компонентам, а не по элементам. Компоненты можно и по сетке расставить, и обернуть во что-то, если это нужно. Слоты сколько раз видел — всегда через них передавались компоненты целиком. Мне сложно придумать пример, в котором понадобилось бы оборачивать во что-то отдельный элемент внутри компонента.

Любой компонент — это одновременно:


  • бэм-блок
  • бэм-элемент владеющего им компонента (бэм-блока).

Так вот, как стилизовать бэм-элемент, если между ним и владельцем рендерится обёртка, добавляющая чёрт знает какие хтмл-элементы?


Ну, пример на Реакте:


<div class="app">
    <Panel header={ <div class="title"> }/>
</div>

Надо лишь передать нужный класс компоненту Panel — а тот пусть сам его применит к элементу верхнего уровня.


<div class="app">
    <Panel class="app_content" header={ <div class="title"> }/>
</div>

В любом случае, это общая проблема BEM и RSCSS.

Нету в БЭМ такой проблемы:


<div class="my-app">
    <Panel header={ <div class="my-app-title"> }/>
</div>

Речь сейчас не про стилизацию панели, если что. Стилизация панели — это уже проблема Реакта :-)

Есть. Стили предназначенные для my-app_title смешиваются со стилями предназначенными для какого-нибудь my-panel_header с образованием случайной смеси.

По БЭМ-у не смешиваются. Вот если в Panel наворотили каскада, то конечно.
Ответ прост — не мешать элементы и компоненты. Если компонент может иметь несколько разных вариантов самого себя — использовать варианты, а не пытаться достучаться к нему из другого компонента. Это даже не сколько про обертки, сколько про логику в коде.
Вы лучше код напишите, как вы стилизуете title.
UFO just landed and posted this here

А можно поинтересоваться, насколько большие вам доводилось делать? Какая была самая большая команда в которой приходилось работать?
Если проект небольшой и пишется в одно лицо, то можно много каскадных красивостей нагородить. При наличии даже двух разработчиков начнется ад.

Не очевидно. Всю общемировую инфраструктру тысяч jquery plugin'ов (чем не компоненты?) авторы поддерживают только при помощи здравого смысла и негласного соглашения с пользвателими уметь в F12.
Прочитав заголовок, я подумал, что внутри будет одно из двух. С вероятностью 95% это очередной горе-разоблачитель, который рассматривает БЭМ как набор чьих-то странных прихотей и совершенно не понимает, почему он устроен именно так и какие проблемы призван решать. Ну и с вероятностью 5% я узнаю какую-то новую, крутую, интересую идею. К сожалению, теорвер не подвел.

Многолетний опыт верстки мне говорит: БЭМ не идеален, но это лучшее из имеющегося. Никакая другая методология не выдерживает конкуренции с ним на практике. (Единственное исключение — css-in-js, но это игрок с несколько другого поля). Существенно лучше него может быть только радикальная переделка всего стандарта CSS, с блекджеком и неймспейсами.
Ценой некоторой многословности он решает огромную кучу проблем.
Каскад БЭМ не отрицает, а лишь призывает к ограниченному его применению. Изобретался каскад в древние времена, когда сайты были на порядок проще, а сейчас условия изменились — вылезли на поверхность побочные эффекты.
Препроцессоры он тоже не отрицает, а наоборот прекрасно с ними сотрудничает.
Остальное даже комментировать нечего.
Короче, учиться и ещё раз учиться.
А я, увидев это в самом топе хабра, прям сильно понадеялся найти более изящное решение ( Но автор даже не искал
Самое удивительное в этой статье — рейтинг. Я был уверен, что там будет минус много.
Это своего рода праздник непослушания. Толпы говнокодеров обрадовались, что они не одиноки в своем невежестве.
Ведь автор реально невежда, как и множество его предшественников.
На самом деле, я бы удовольствием отсыпал плюсов статье с серьезной критикой бэма и предложениями по его усовершенствованию/замене. Но таковых пока не видел.
Все виденные мною «разоблачители» — это люди, которые просто ни черта не поняли в теме. И на самом деле они критикуют не сам бэм, а свои очень кривые его трактовки.
БЭМ-подобные подходы стали вынужденной мерой на фоне отсутствия в CSS возможности управлять наследованием на тот момент. Хотя в большинстве случаев вполне можно прожить без БЭМ и сейчас, особенно тем, кто ценит чистоту HTML-кода.

Но теперь есть all и initial / unset, которые, вероятно, сильно уменьшат востребованность БЭМ даже в больших, непрерывно развивающихся проектах конвейерного типа. Остаётся «лишь» дождаться поддержки этих возможностей CSS в браузере Edge и уменьшения доли устаревших версий браузеров Microsoft до пренебрежимо малой. Значения initial и unset поддерживаются уже начиная с EdgeHTML 13 (2015), но без свойства all толку от них мало.
UFO just landed and posted this here
Нечитаемость кода… соминтельно, учитывая тот факт что сейчас почти все пользуются сборщиками и читать нужно исходник а не сгенеренный код. Давайте еще скажем что минифицированный js плохо читается.
На мой взгляд все проблемы описанные в статье — скорее преимущества методологии, а не недостатки.
И если строго следовать методологии — то как минимум БЭМ не позволяет говнокодить — а только дисциплинирует и закаляет.
А в исходниках те же длинные имена классов будут. Как не собирай, но сборщик их сам не пропишет. Тут какой-то транспилер специального БЭМ-языка(ов) в HTML И CSS может помочь по типу TypeScript и SCSS. Но ни к методолгии, ни к сборщикам это прямого отношения не имеет.
У реакта есть замечательная библиотека github.com/bem/bem-react-core. Там и сборщики и разработка компонентов в методологии БЭМ. Довольно удобная штука (со своими недостатками декларативности БЭМа, но это уже каждому своё).
Эта библиотека как раз и умеет прописывать всё. Писал аналог на vue, правда только для на простых случаях. Очень сильно сокращался код и всякие условия по генерации классов и т.п.
Там где есть Реакт БЭМ как у собаки пятое колесо.
Это если с CiJ, JSS, CSSModules и иже с ними, которые предоставляют свои костыли для решения проблема. А вот если в чистую делать, то нужно всё равно либо эти вещи применять, либо свои велосипеды придумывать.

И вообще не надо путать. Реакт — не для вёрстки придуман. А BEM для того, чтобы вёрстку не упростить, а зажать в рамки, чтобы своих велосипедов никто не придумывал.
Ну это что-то типа транспилера и есть похоже.
Проблема в том, что с этой самой версткой потом приходится иметь дело другим специалистам, которые зачастую работают именно с HTML-кодом.

Единственная проблема, которую решает БЭМ — это конфликт селекторов. Говнокодить он никак не запрещает.

Та вы просто не знаете что предлагает бэм, поэтому так пишете. А вы почитайте, и поймёте что цель бэма это уменьшение говнокода в том числе, а не просто длинные имена классов

БЭМ, конечно, спорная фигня, но циклы в стилях — это точно за гранью добра и зла.

UFO just landed and posted this here

Хуже БЭМа лучше нет

А чем вас, простите, циклы в стилях не устраивают? :)

Тем, что стили должны иметь декларативный характер. Еще не хватало дебажить стили =)

Т.е. миксины, шаблоны, функции и прочую "ересь" тоже стоит запретить? :) Тогда мы придём к чистому CSS что в целом и неплохо, но многие вещи придётся делать руками вместо того чтобы автоматизировать.

Строго говоря, цикл декларативности не мешает. Канонического определения, вроде нет, но при отсутствии изменяемого состояния не понятно что дебажить.

Где это может понадобиться? В голову лезет только или спрайты или, куда более заманчивее, подгрузка изображений через background-img так как в этом случае изображения лучше всего поддаются адаптивщине, чем через втег IMG.

Я в текущем проекте насчитал 15 @for и 17 @each не считая библиотечных функций с циклами.


Функционально — всё то же самое для чего используются циклы в обычных языках программирования: либо итерация по чему-либо (например конфигурации или списку элементов) либо генерация последовательности элементов с разными значениями. Элементарный пример с созданием стилей для заголовков разного уровня здесь где-то мельках в комментариях, практических вариантов применения сильно больше. Вот банальный пример, да простит меня заказчик :) Имена категорий поменяны, но в остальном реальный код


$categories: (
    one: #33d28b,
    two: #587fe1,
    three: #5ac8fa,
    four: #966ec8,
    five: #ff914b,
);

@each $category, $color in $categories {
    .category-#{$category} {
        @include content-category-color($color);
    }
}

Вообще работа с maps в scss без циклов выглядела бы довольно сомнительной во многих случаях.


Или вот другая практическая задача из текущего проекта: необходимо было сделать возможность задания произвольных layout'ов для расположения контентных элементов. Всё прекрасно и легко решалось бы через CSS grids если бы не наш "любимый" IE11 в котором, как известно, реализована старая спецификация CSS grids. В ней, помимо всего прочего напрочь отсутствуют gaps между ячейками. Таким образом отступы между элементами нормально было не сделать, шаблоны grid'а там тоже не поддерживаются, синтаксис отличается.


В итоге просто был сделан map с описанием структуры grid'а и в цикле по нему генерируется нормальный CSS grid, а затем (с пересчётом номеров ячеек т.к. отступы для IE11 сделаны через дополнительные ячейки) из него же генерится отдельный синтаксис для IE11. С учётом поддержки в этом пересчёте col/rowspan'ов и ряда дополнительных функций, с учётом того что структура сеток меняется для разного типа устройств — получилось около 250 строк scss кода и немного конфигурации, объём же создаваемого CSS явно больше, да и писать (а тем более поддерживать его) вручную я бы точно не взялся.

Давно хотел узнать, а почему в БЭМе так принципиально отказываются от самой главной сущности CSS — каскадирования?
Например, не рекомендуется использовать контекстные (вложенные) селекторы:
Методология БЭМ допускает использование вложенных селекторов, но рекомендует свести их применение к минимуму. Вложенные селекторы увеличивают связность кода и делают его повторное использование невозможным.

Какая мне нужда увеличивать объём кода и два раза прописывать стили для какого-то блока с модификатором и без. Когда я просто контекстным селектором могу поменять отдельные свойства.

Ещё поясните насчёт запрета использования идентификаторов — это только касательно CSS? Или getElementById() тоже нельзя использовать?
UFO just landed and posted this here
Каскады вида .block--modifier .block__element можно применять, только осторожно. Дело в том, что если у вас в элементе окажется такой же блок (например, вы делаете древовидный компонент), то модификатор родителя будет влиять на элемент дочернего блока.

Вот это вот вообще непонятно. Я-то прекрасно знаю все селекторы CSS. В случае чего, можно с помощью контекста повысить специфичность, поставить дочерний/соседний селектор. Что значит «только осторожно» — для кого эта методика? Для тех, кто не в состоянии посчитать сколько раз блок встречается в документе? Так давайте пойдём ещё дальше и максимально упростим задачу для таких людей — будем вешать уникальный идентификатор на каждую сущность DOM. А потом для каждого прописывать свои СSS-правила (можно даже группировать одинаковые по стилям блоки, хотя судя по объёму кода в БЭМ — это далеко не первостепенная задача).
UFO just landed and posted this here
Опять началась мантра про «большие проекты», «большие команды». Если большая команда давно работает вместе — там в любом случае будет какой-то стандарт кода, договоренности между собой и т.п. Вон, ниже человек отписался. Я тоже частенько с таким сталкивался. При разработке сложных по иерархии документов, вменяемая команда найдёт некий стандарт именования сущностей.
Если в большой команде появляется новый человек — ему первое время все равно придётся пользоваться веб-инспектором.
Понимаете, что лично у меня вызывает раздражение — это что «веб-евангелисты» Яндекс и Макеев (да и не только они — большинство фреймворков сейчас ориентированы на такой подход), пытаются представить вёрстку как сугубо механическую работу — наплоди тучу блоков, каждому присвой уникальный класс и автоматом пропиши для него правила. Да, скорее всего это работает быстрее. При этом вопросы чистоты кода и семантики идут просто лесом…
А мне вот как-то по старинке ближе, когда в начале подробно изучается проект, строится иерархия использования стилей, определяются глобальные классы, сразу продумывается «резерв» для медиа-запросов и т.д. Когда в итоге стилевой файл абсолютно читабелен и легко поддается изменениям, а HTML-структура выглядит понятно, семантично и легковесно. И потом не возникает никаких проблем (даже для новенького) — всунуть туда новый блок или изменить старый, потому что варианты развития проекта продумываются ещё на этапе построения абстрактной DOM-модели.
Ну и наконец, есть такой известный методологический принцип — «Не плодите сущности без нужды»(с) У. Оккам
UFO just landed and posted this here
БЭМ создавался не столько для улучшения по каким-то критериям вёрстки одного проекта, а для переиспользования готовых кусков в разных проектах и уменьшения порога входа в новый проект. В целевом сценарии БЭМ места для «в начале подробно изучается проект» или вообще нет, или оно есть только один раз на все десятки и сотни проектов. Уже второй проект должен использовать весь подходящий код из первого по умолчанию. И при этом не предусматривается единого жёсткого UI стайлгайда/брэндбука, в них только общие принципы максимум, а в конкретном проекте они адаптируются или даже явно нарушаются (по согласованной процедуре обычно), но при этом писать с нуля если есть что-то хоть немного похожее в соседнем проекте, не рекомендуется.
Каскады вида .block--modifier .block__element можно применять, только осторожно. Дело в том, что если у вас в элементе окажется такой же блок (например, вы делаете древовидный компонент), то модификатор родителя будет влиять на элемент дочернего блока.


Если верстальщик/девелопер интерфейса не может представить, или даже просто записать структуру своего интерфейса, который делает — то чего он делает вообще в этом бизнесе?
Каким нужно быть… чтобы нагородить вложенные блоки прототипов, влияющих друг на друга.

Тут еще выше люди отписывались про ад при работе в команде, если без БЭМ, это просто жесть. Если команда сама себе придумывает проблемы на ровном месте, не имея каких либо общих договоренностей об именованиях при разработке, то это не команда — это бесполезное сборище.

Я уже просто десятилетие, не побоюсь этого слова, во всех проектах, с разными командами использую простейшее правило именования — цифровые индексы с буквенными приставками для разных типов селекторов. И ни разу еще после оглашения этого правила, никто не смог запутаться в коде. Именуем все классы, идентификаторы, прочие необходимые селекторы в пределах одной логической единицы интерфейса, строго цифровыми индексами от 1 и далее (к выданным буквенным префиксам этого интерфейса). В начале самого кода, каждый разработчик, работающий с этим кодом, указывает последний используемый индекс в этом интерфейсе — всё! Что там еще городить? Какие циклы? Какие вложенные структуры и блоки? Любой разработчик, открывая файл проекта с кодом, видит номер последнего примененного имени, просто продолжает дальше имена со следующими цифрами.

Понадобилось вам после нескольких лет работы приложения/интерфейса внести изменения (дополнить ли, или изменить код и внешний вид), продолжаете вносить модифкаторы для нужных блоков именуя их дальше по порядку цифровыми индексами, это гарантия, что вы никогда не столкнетесь с конфликтом имен в кодах проекта.
Если же ваш проект-менеджер сделал так, что у вас один ленд, или страницу интерфейса верстает сразу несколько человек — гоните такого менеджера в шею, в любой момент времени, отдельную логическую единицу верстает всегда, ВСЕГДА! один девелопер. Да млина, это не войну и мир писать группой — это одна видимая страница интерфейса, как могут там оказаться 2 верстальщика? Какими нужно быть упоротыми, чтобы до такого додуматься?
Если верстальщик/девелопер интерфейса не может представить, или даже просто записать структуру своего интерфейса, который делает — то чего он делает вообще в этом бизнесе? Каким нужно быть… чтобы нагородить вложенные блоки прототипов, влияющих друг на друга.

Уровень разработчиков даже в пределах одной команды всегда разный. Можно использовать соглашения, но потом ты такой перескакиваешь на другой проект, а там… Либо другие соглашения, либо отдельные чуваки с собственным видением того, как правильно.


Я уже просто десятилетие, не побоюсь этого слова, во всех проектах, с разными командами использую простейшее правило именования — цифровые индексы с буквенными приставками для разных типов селекторов.

А можно живой пример?

Уровень разработчиков даже в пределах одной команды всегда разный. Можно использовать соглашения, но потом ты такой перескакиваешь на другой проект, а там… Либо другие соглашения, либо отдельные чуваки с собственным видением того, как правильно.

Так это и с БЭМом так же. В одной команде использую свою систему именования, а в другой иную. Кто может просто наприсваивать одинаковых классов разным блокам (потому что как раз система именования в БЭМ не продумана).
UFO just landed and posted this here

Ну а когда ваша "команда" вырастает до двух человек буквенно-цифровые индексы будкт постоянно незаметно приводить к незримым ошибкам на пуллреквестах.
Я не говорю уже про команду в 20 человек, в которой наверное нет иного способа работать, кроме как договариваться в общем чате о том кто какой индекс использует: "посоны, .header-xyz324 не берите, это мой"

Давно хотел узнать, а почему в БЭМе так принципиально отказываются от самой главной сущности CSS — каскадирования?

Потому что чем глубже зарыты стили, тем сложнее их поддерживать и модифицировать. Первый вариант:


.header {
    .title {
        a {
            span {}
        }
    }
}

Здесь несколько классов и стили на тегах, каждый из которых может использоваться в самых очевидных и не очевидных местах. На каждом из таких классов/тегов могут быть уже кем-то когда-то навешанные стили, которые вам придётся переопределять в любом подобном «нестандартном» блоке. И не дай бог вы поменяете глобальные стили .title или a, будете ли вы уверены, что где-нибудь что-нибудь не поломается?)


Если же перепишем стили выше на что-то подобное:


.global-header {
    &__title {}
    &__link {}
    &__link-text {}
}

То едва ли получим пересечение стилей. Даже визуально каскад сократился всего до одного уровня, а в скомпилированном CSS (в данном примере использован SCSS) каскада не будет вовсе. Полагаю, что и браузеру будет легче обрабатывать стили меньшей вложенности, нежели зарываться в пучину на каждый чих.


Ещё поясните насчёт запрета использования идентификаторов — это только касательно CSS?

Повесив однажды стиль на идентификатор, изменить его можно будет либо еще бóльшим уровнем вложенности селекторов, либо через !important. Ни то, ни другое не является таким уж отличным решением.

Дополню.
Идентификаторы не нужны потому что есть классы, которые умеют работать (почти) точно так же. А когда верстаешь на бэме, классы лучше идентификатора.


Блоками могут быть как какие-то общие переиспользуемые компоненты (.button, .input, .textarea...), так и единожды появляющиеся глобальные компоненты (.main-page, .sidebar, .open-file-popup...). Именно для вторых у автора вопроса очень естественное желание использовать идентификаторы, но на самом деле от их замены на классы станет только лучше.

Когда мы получили препроцессоры, все так радовались, говорили «ура, можно будет писать в сорок раз меньше кода». А потом все превратилось в
.something {
   .another {
      .and-another {
         a { color: red; }
      }
   }
}


И в этом less/sass/scss/stylus просто вся верстка всего сайта зашита. Сколько раз я приходил в проекты и выпиливал там все подобное к чертовой матери, потому что ну разумеется там любое изменение в дизайне проходило через стадию «это невозможно сделать в нашем подходе» к стадии "!important", «style=''''» и наконец «style=''!important''».
У вас ошибка в цепочке приоритетов — "!important" имеет приоритет над инлайновым стилем.
Ужасно рад такой ошибке, поскольку последний раз использовал нечто подобное лет двенадцать назад. Спасибо, что поправили.

Вы вроде даже приводите цитаты с bem.info, а там ведь по-русски всё написано. Но вы просто не читали. Там на все (да, вообще все) ваши претензии есть ответы.


Больше всего доставил запрет «всё блоками». Нет, правда, ржу. Вы не поняли, что блок — это не коробка, не кирпич, не что-то большое. Блок — это самостоятельная единица интерфейса. Есть блоки, у которых нел элементов и стилей 5 свойств. Это тоже блок.


Смешно, грустно, стыдно за вас. Что вот так вышли и показали себя миру, сказав гулопсть, поторопившись, не разобравшись.


Почитайте «Архитектуру CSS» Филипа Уолтона, вчитайтесь в bem.info, например в FAQ есть хорошие ответы. Ну и видео посмотрите, для вас же снимали:


Справедливости ради, стоит заметить, что БЭМ популярен не только на просторах СНГ, но и в Европе, и за океаном. Возможно, не настолько популярен, как у нас (у меня нет на руках статистики), однако статьи пишутся, видео снимаются :)

Мне кажется, вы не разобрались в БЭМ. Сама идея независимых блоков прекрасна и отлично работает в огромных проектах. Ваши идеи с переиспользованием селекторов лишь усложняют жизнь — если вы переиспользуете одно правило в нескольких блоках, то их нельзя редактировать по отдельности.

Позвольте еще покритиковать.

Во-первых, SCSS — гадость. То есть сам язык неплох, но используется в 99% случаев неправильно и получается плохой нечитаемый код. Ну например, люди начинают в SCSS копировать струтуру дерева DOM и городить невменяемые селекторы вроде

.class {
div {
a {
span {
.something {

}}}}}

Во-вторых, когда эти вложенные блоки огромные и становятся длиннее 1 экрана, то непонятно, внутри какого селекторы ты находишься.

Далее,

> Ниже предоставлен образец вёрстки без наследования в имени класса названия блока, модификаторы привязываются к главному классу через наследование в SCSS, а не текстовое название класса:

Ваш код хрупкий. Достаточно добавить один враппер вокруг .next и стили перестанут действовать:

> & > .next

Также, это правило

> .link {

Будет действовать на любые классы .link внутри блока. Если в ваш блок вложить другой блок, в котором тоже есть класс link, то правило подействует на него. BEM, в отличие от вашего подхода, позволяет произвольно вкладывать блоки без конфликтов стилей.

> По сути, в глобальных классах нет ничего плохого. Проблема в том, что в названии класса сохраняется имя блока или элемента и использовать его вне блока уже нельзя и глобальность становится бесполезной.

Это специально. Стили блока относятся только блоку и ни к чему больше.

Во-первых, SCSS — гадость

Пожалуй, нет
И всё же, да. Меня больше всего раздражает, когда нельзя скопировать из отладчика селектор и быстро найти файл и место в этом файле, где на этот селектор наложены стили.
Чаще приходится работать с блоком DOM, чем с каким-то отдельным селектором. Если дерево CSS схоже с деревом DOM для блока, то это позволяет быстро разобраться что и как сделано, а это ускоряет работу с CSS.

Вообще все доп инструменты призваны улучшить опыт разработки, а никак не наоборот. Плюс есть ещё субъективный момент в использовании.
Это проблема решается при помощи source-map, а вот осторожное использование & чем либо заменить сложно.

И как source-map поможет быстро начать редактировать? :-) с чистым CSS я просто копирую селектор, жму ctrl+shift+F в редакторе, вставляю и в один клик перехожу к редактированию нужных стилей.

Работая сейчас с Реактом могу предположить, что это проблема не css (он у вас один глобальный?) а модульности самой вёрстки. Когда я работаю с каким-то селектором, я работаю в первую очередь с компонентой, а в стилях для компоненты нет никаких сложностей найти нужный селектор в SCSS из сгенерированного CSS, потому что я изначально знаю где искать.

Замечательно. Теперь слетайте в отпуск на месяц куда-нибудь в тайгу без ноута, а по возвращении пофиксите срочную багу «тут у нас менюшка из бокового виджета налезла на кнопку оплаты».

Дак дело то не в этом. Есть компонента, есть css этой компоненты. Фиксите стиль компоненты — первым делом идёте в код и ищете саму компоненту (и её стили). По имени-иерархии-чему-угодно. А там уже находите нужный стиль. Или сразу ищете по ctrl+shift+f и отсеиваете (при совпадениях) заведомо ложные вхождения (из других компонент).

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

Крайне спорное утверждение.
Давайте гипотетически, один большой CSS по которому просто искать и куча SCSS исходников по компонентам.


Когда работа в процессе и мы работаем с одной-двумя компонентами удобнее (и быстрее конечно же) когда есть пара файлов с минимумом лишнего кода (стилей) по которым просто (и быстро, конечно же) ориентироваться.


Когда же вы возвращаетесь через полгода чтоб что-то подправить — согласен, быстрее добраться до места по глобальному поиску по точному совпадению строки.


Но давайте сравним, что же в итоге быстрее — десятки изменений в процессе работы, или пара изменений через полгода?


Мне кажется что именно через полгода можно потратить пару лишних минут, чем мучаться в процессе работы.


Но в общем, по большому счёту, модульно можно и с CSS работать, просто собирать в один файл, тут дело такое.

Поддерживаю.
Неоднократно получал на поддержку подобные проекты.
Причём найти код ещё мелочь, нужно потом этот код ещё изменить, а если оказывается, что нужно подправить не только css, а ещё и html (что-то добавить или переместить), то зачастую летит вся описанная в css каскадность. Особенно это «радует» когда проект с адаптивной вёрсткой и описание каскадности идёт вперемешку с медиазапросами, такие вещи зачастую проще с нуля переверстать, чем поправить.
Как итог, последние пару лет всё, что делаю с нуля, делаю с применением БЭМ. Поддерживать такой код потом в разы легче.
И как следствие: распутывать каскады и делать в них правки выходит настолько муторно, что каждое поколение разрабов идет по пути наименьшего сопротивления и лепит быстрые перекрывающие заплатки с еще более длинными каскадами и импортантами. Да и менеджмент подстегивает — надо поскорее. Со временем эти говнофиксы копятся и копятся, наслаиваются и наслаиваются… Я лично встречал каскады в 6-8 ступеней.
И в какой-то момент наступает понимание, что это необратимо — даже если я и хочу сделать всё правильно, я уже не могу. Там такие авгиевы конюшни, что разгрести его не представляется возможным, только сжечь. И даже самый добросовестный разработчик смиряется и просто плывёт по течению.
Хуже каскадов только каскады используемые глобально. Иногда так 1 строку поправишь, а на проекте в десятке мест потом самые непредсказуемые баги вылазят.
Теперь слетайте в отпуск на месяц куда-нибудь в тайгу без ноута, а по возвращении пофиксите срочную багу «тут у нас менюшка из бокового виджета налезла на кнопку оплаты».

Открываете css менюшки из бокового виджета и фиксите. Две секунды делов, в чем проблема-то?

Правильно настроенный source map показывает конкретный номер строки в конкретном файле.

Вам настолько лень переключиться между окнами? :)

Мне настолько лень накликивать нужный файл и искать в нём нужную позицию, если можно воспользоваться поиском и сразу перейти туда куда нужно.

Нагуглить не получается, но ЕМНИП среды от JB могут понимать урлы вида localhost:65532/go/foo.cpp/80 (от урл написал от балды)

Меня больше всего раздражает, когда нельзя скопировать из отладчика селектор и быстро найти файл и место в этом файле, где на этот селектор наложены стили.

Попробуйте использовать карты исходников. Даже копировать ничего не придётся. =)
image

Кстати, в Chrome (как минимум) есть возможность подключения файловой системы исходников, так что править стили можно прямо в отладчике. Так даже путь копипастить не надо.

Отладчик, конечно, умеет в SCSS.

Сам по себе, конечно, не умеет, но у вас же на эти файлы всё равно натравлен вотчер, который их компилирует при изменении. А изменять можно прямо в DevTools, потому что им без разницы какое расширение имеет ваш текстовый файл.
И правда, зачем мне подсветка синтаксиса, подсветка ошибок, автодополнение…
Комментарии странные. Помню, как Яндекс впервые писал про БЭМ, единственное для чего его создали, единственную обозначили ключевую проблему, которую он решает: СКОРОСТЬ рендеринга. Отсюда длинные уникальные независимые наименования классов. Остальное попутно. Жду комментариев к этому.
Скорее всего вы впервые узнали про БЭМ именно из статьи рассматривающей вопрос скорости. Но нет, основная причина появления БЭМ — возможность располагать блоки как угодно друг относительно друга так, чтобы стили не ломались.
Нет, скорость они называли как один из факторов, но не основной.
Найдите и посмотрите видео Харисова, он подробно рассказывал откуда, как и почему появился БЭМ.

Почему только СНГ? Новая библиотека от Гугла тоже использует БЭМ https://material.io/develop/web/


С БЭМом очень удобно добавлять свои стили. Четко ясно и понятно, где твои, а где библиотечные блоки.


Выше в комментариях упомянули что одно из преимуществ БЭМ это скорость рендеринга. Тут сложно сказать почему, но гугловая либа визуально быстрее materializecss. Но тут возможно из-за перехода от float на grid'ы

Статья вызывает только улыбку =)

Собственно всё сводится к тому, что у БЭМа «длинные» имена классов, и вам это не нравится. «Нечитабельный» — это не аргумент. Что для вас нечитабельно, для других может быть очень даже удобно.

<ul class="article-rewind
           article-rewind_type_static
           article-rewind_lang_ru">

Прекрасно!

Пример с фоном притянут за уши. Если класс ничего не делает, кроме изменения фона, никто не запрещает вам создать такой класс отдельно. Не вижу здесь ничего криминального.
<div class="promo-section background-white"></div>


Про семантику в заголовках. Вы предлагаете
h2.heading {font-size: 21px;}

Ок. Написали, всё прекрасно. Прибегает сеошник и кричит, что в этом месте нужно убрать теги h2 и заменить их на дивы. Ваши действия?

Хотите дропдаун не только в хэдере?

Тогда сделайте его блоком.
Есть простое правило, о котором многие новички не забывают или не понимают его сходу: стили блока описывают его внешний вид, но не позиционирование, стили элемента могут содержать правила позиционирования. Совмещаем это с идеей миксования и получаем:
<div class=header>
  <div class="header__dropdown dropdown"></div>
</div>
<div class=footer>
  <div class="footer__dropdown dropdown"></div>
</div>

B никаких проблем от того, где вы захотите расположить блок, в шапке, в подвале, или еще где-то.
Прекрасно!

Не, лучше так:


<div my-article-rewind my-article-rewind_type="static" my-article-rewind_lang="ru">

my — потому, что есть не только ваши компоненты, но и сторонние.
Атрибуты — потому, что с ними куда больше возможностей как в JS так и в CSS.

Ок. Написали, всё прекрасно. Прибегает сеошник и кричит, что в этом месте нужно убрать теги h2 и заменить их на дивы. Ваши действия?

Посылаю сеошника лесом :-)


С остальным согласен.

из вашего примера, я бы сократил еще background-white до bg-white и все было бы шоколадно.

Наконец-то кто-то это написал! Последние лет 5-10 программеры упорно тащат в мир дизайна кучу решений из своей практики, и решения эти для дизайнеров выглядят уродливо и неудобно.


Теперь уже простой сайт не сверстаешь без npm и прочих радостей командной строки, да и вообще вместо сайтов делают простоодностраничныеприложения (да, в одно слово)


Вот это вот всё БЭМгое — опять программеры натащили, и, конечно, будут защищать — см. комменты выше.


Только это все другая логика. Дизайнеры работают с визуальными подходом, и хотят видеть все текстовые вещи простыми и далекими от программирования. CSS задумывался просто и по-дизайнерски. Поэтому там нет наследования и так далее. Мы не пишем IScalableHeadingLevelInterface::_blockDivLayer, мы пишем div.h1… div.h5, и нам так удобнее. Нам не надо мейнтенить, рефакторить, супероптимизировать и асинхронно выполнять. Нам просто надо, чтобы flex уже везде заработал нормально...

<sarcasm_on>
Во-во! Понапридумывают своих pug, sass, less, bem, а другие страдают, учить приходится! <sarcasm_off>

Less отличная штука, только непонятно, почему для неё нужен отдельный компилятор, не встроенный во все среды разработки.


Да и вообще, почему нормальной среды визуальной разработки так и не появилось со времён DreamWeaver.

На вкус и цвет все фломастеры разные, я привык к pug и sass — компактны, функциональны и минималистичный код.
Less отличная штука, только непонятно, почему для неё нужен отдельный компилятор, не встроенный во все среды разработки.

Потому что это надстройка над CSS и смысла для неё пилить нативную поддержку браузерами нет. Сегодня есть LESS, SASS, Stylus. Завтра появится еще что-нибудь.

А дизайнеры хотят ли иметь право попросить передвинуть "вон ту штучку" "куда-нибудь туда"? Законное право для дизайнера.
А верстальщик хочет сделать это на раз, без лишних трудозатрат? Законное право и торжественная обязанность верстальщика.
А если внешний вид "вон той штучки" размазан по каскаду?
А если внешний вид "вон той штучки" завязан на конкретное местоположение?
Или пусть не дизайнер и верстальщик, а заказчик и фуллстек человек-оркестр, он же дизайнер, он же вёрстку творит.
Вы считаете уменьшение связности кода злом и ненужным усложнением? Возможно, Вы адепт одноразовой разработки: быстро сделал, отдал и забыл?
Программисты, конечно, себе на уме, но снижение связности кода (вёрстки а частности) удешевляет его изменения, в противовес микроменеджменту в отношении элементов вёрстки. Один раз научили элемент как-то выглядеть, а дальше он сам выглядит, как надо.

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


Если эта Штучка (такая, штучка!) выглядит в разных местах по-разному, то это две разные штучки. На уровне функциональности — пожалуйста, переиспользуйте. А то, что относится ко всему визуальному — не надо, правильно будет сделать заново.

> Если эта Штучка (такая, штучка!) выглядит в разных местах по-разному, то это две разные штучки.

А как это работает, если, скажем, при прокрутке первая штука морфится во вторую?
Вы это сейчас про дизайнеров в целом или только про верстальщиков-говнокодеров? Аргументы вида «нам не надо поддерживать» очень сильно попахивают вторым.

Вопрос в том, что значит — поддерживать.


Если сайт готов и в него надо встроить новую кнопку, баннер, поддержку эмодзи в именах пользователей — это все нормальную верстку сломать не должно.


Все проблемы, которые решает БЭМ — это если изначально сверстано так, что дунешь — разваливается.

Ох-хо-хо! А не могли бы вы тогда «поиграть со шрифтами» и сделать этот «жёлтый менее жёлтым»?
Дизайн — это инженерная профессия. И решения в нем должны быть с инжереным подходом.
И поверьте, никого не волнует как удобно вам, удобно должно быть людям, которые код поддерживают.
Поправка: промышленный дизайн, а не любой. Веб-дизайн обычно относится к промышленному.

Кто вам такое сказал? Дизайн — это профессия на стыке творчества (художники) и инженера (верстальщики). И перекос в любую сторону плох, а всё, о чем я писал — как раз перекос в сторону инженеров.

А в это время в другой вселенной дизайнеры САМИ программируют дизайн систему:


http://whitepaper.tools

Так и не понял, что это и с чем это едят. Кто-то что-то программирует… Демо есть?

Лениво разбирать всё, но вот первый же пример:
Чтобы разобраться, можно ли безболезненно изменить стили для класса .active, разработчику придется просмотреть всю структуру страницы или проекта. Любое изменение потребует значительных временных затрат только на поиск зависимых компонентов.

Зачем тут изобретать велосипед? Прописываем стили для .nav .item, а потом для .nav .item.active. Если вы так боитесь что до этого вам кто-то мог насовать в .active всяких !important (что само по себе уже странно, так-то вам и без того в код могут насовать чего угодно, например уже использовать тот же «nav» — тоже ведь получается надо просматривать всю структуру данных) — ну обзовите как «nav-active».
UFO just landed and posted this here
Без конкретных примеров мы окончательно запутаемся.
Если не будет каскада, то как вы собрались повышать приоритет правила? Расположением ниже по коду? Но это же вообще дичь!
А вообще разовью мысль.
Имеем, например такой HTML:
<ul class="nav">
 <li class="item active">
  <ul class="subnav">
   <li class="item active"></li>
   <li class="item"></li>
  </ul>
 </li>
 <li class="item"></li>
</ul>


Ну и набор правил:
.nav .item{...}
.nav .item.active{...}
.nav .subnav .item{...}
.nav .subnav .item.active{...}
.nav .item.active .subnav .item.active{...}

Этими правилами покрываются все возможные варианты оформления. Более того, в CSS файле каскад селекторов даёт наглядную демонстрацию уровня иерархии. Если потом возникнет нужда изменить оформление пунктов меню — то просто переписываем свойства в ".nav .item" — заодно сразу подхватятся стили и для пунктов вложенного меню. И только если возникнет задача — изменить пункты верхнего меню, не трогая пункты подменю, то тогда можно просто навесить новый класс и дописать:
.nav .item.new-design{...}
.nav .item.new-design.active{...}

Но лично мне подобные задачи встречались крайне редко.
А если понадобится три уровня вложенности? .nav .subnav .subnav?
UFO just landed and posted this here
Не надо приводить в пример идиотскую вёрстку. Дурак и в БЭМ такого нагородит (причём с гораздо бОльшей вероятностью).

Это не «идиотская вёрстка», а реальный пример с продакшна. И такое, поверьте, встречается гораздо чаще, нежели какой-нибудь подход поадекватнее. Это похоже на страсть к сокращению названий переменных в коде или колонок в таблицах БД. Когда ты такой смотришь на это и только «просканировав» большую простыню кода понимаешь, а что тут, собственно, имелось-то в виду под этими названиями.


Так и здесь. .button — что за .button? .panel — что за .panel? .item — что за .item? Список можно продолжать… Добавьте сюда еще стили на тегах, понатыканный везде > и не дай боже стили на идентификаторах) Туши свет, бросай гранату называется.

UFO just landed and posted this here

Значит, стили изначально неправильно переиспользовались или недостаточно гибко писались.

Ну так БЭМ, он для гибкости и создавался же) Он не про замену заголовков на div, как тут некоторые пишут. Он про минимальное пересечение стилей между различными компонентами, а также про композицию этих компонентов друг с дружкой.

Стоит отметить, что с БЭМ селекторы будут выглядеть гораздо лучше, и появится возможность создать любую вложенность.

.nav__item{...}
.nav__item--active {...}
.subnav__item {...}
.subnav__item--active {...}


Но это, конечно, только если вы знаете, что БЭМ — это не только про нейминг классов, но еще и про определенные принципы написания стилей вообще.

А потом вы напишете стиль для .nav.active img, а потом вложите в .nav.active блок .dropdown-menu, который тоже может быть .active, и внутри которого тоже может быть img (и какие-то стили для .dropdown-menu.active img), и у вас внезапно стили от .nav.active img окажутся также стилями для .nav.active .dropdown-menu img.

Простите, почему у меня вдруг «внезапно стили… окажутся»? Я как бы не вслепую верстаю. На img всегда можно навесить свой класс. Более того, наследование CSS-свойств определяется ещё на этапе присвоения классов.
Я точно так же, как и БЭМ, могу спокойно обвешать классами каждую сущность. Только вот в отличие от БЭМ, я могу очень гибко пользоваться наследованием стилевых свойств. Определив классы для какой-то вышестоящей по иерархии сущности, я сразу их определяю для целого ряда вложенных сущностей, чтобы избавляет меня от нужды по несколько раз копипастить участки кода.
UFO just landed and posted this here
А БЭМ разве не добавляет класс? Как он производит модификацию блока?
В то время я (не ограниченный жёсткими рамками БЭМ) могу как навесить доп.класс этому блоку, так и просто поставить цепочку контекстных селекторов (ведь у этого блока наверняка есть родитель с классом) — тут всё зависит от конкретного проекта. Есть гибкость. Я внизу статьи добавил комментарий о том, как инкапсуляция блоков сильно мешает поддерживать проект.

Не надо использовать "внезапные переиспользуемые компоненты". Они так же поломают БЭМ, при желании.

UFO just landed and posted this here
это у вас было — "… и не предполагаете, что на ней могут внезапно появиться переиспользуемые компоненты"

где гарантия, что эти компоненты не сломают BEM, если уж они ломают обычный грамотный CSS?
UFO just landed and posted this here
Я могу… я могу… Да можете, ради бога. Вот вам кейс: сверстать менюшку, которую можно гарантированно безболезненно копипастить в абсолютно любой проект. Чтобы вы не выдумывали, оговорим сразу — каждый сайт который поломает ваш код, вы переверстываете по БЭМу и бесплатно.

И когда окажется что ваш nav .item наследуется в коде другого чудного разраба, а какой-нибудь jquery плагин от пятого рукожопа вообще превращает его в карусель, вы, матерясь и проклиная всё на свете придете к БЭМу. Думаете те кто его юзают любят и поэтому защищают? Вы ошибаетесь. Я его ненавижу. Все хотят чистый и красивый html, но в реале у нас БЭМ + schema.org + a11y аттрибуты. Так и живем.
«Только ситхи всё возводят в абсолют.» — Оби-Ван Кеноби

Используя БЭМ совместно с глобальными классами для цвета, фона, границ и прочего (определяемыми активной темой) можно вполне себе неплохо жить — будет меньше разных классов с одинаковым содержимым.
Следовать БЭМ буква-в-букву никто же не заставляет. Авторы методологии, конечно утверждают обратное. Но ведь мы же все со своими головами, правда?
Практически все комментарии отрицательно отнеслись к статье, но её рейтинг почти 60) Хм..)

Это нормально. Комментарии без критики просто не нужны — вместо них можно просто поставить плюс.

А я давно предлагал давать одно из двух: или комментарий, или оценку. И не надо будет лепить эти дисклеймеры «минус не мой».
Комментарий — это «ты не прав, вот почему». Минус — это что-то среднее между «ты не прав» и «я не хочу это видеть на хабре», причём судя по интерфейсу хабра (приглушать заминусованные) скорее второе.
UFO just landed and posted this here
Подозреваю что те кто плюсуют не особенно в теме фронтенда, и сказать им нечего, но в общем поддерживают поверхностные выводы автора.
Допустим, есть у нас большой проект нарисованный на БэМе, в проекте на одной из страниц есть блок «Клиенты» с классом .clients, приходит новый сотрудник и ему ставят задачу сверстать новый макет, в котором есть блок «Клиенты» но внешне он совершенно другой. Он создает свой класс .clients и пишет свои стили, в результате чего верстка начинает ехать. Как Бем решает эту проблему?
Я в своих проектах стили каждого блока храню в отдельном файле, с названием файла равным названию блока. Это удобно, особенно если проект большой и имеет много блоков.
А смысл, если ровно тоже самое лежит в css и можно поиском найти этот класс?
Или я тебя не правильно понял :)
Удобство. Я сразу вижу список всех блоков в дереве ресурсов IDE, а так же точно знаю, что никакие другие стили, кроме стилей в данном файле не влияют на этот блок (особенно актуально при адаптивной вёрстке).
+ удобно потом переиспользовать стили в других проектах.

Во первых есть модификаторы. Во вторых есть возможность сделать диугой блок с нуля. Выбирайте то что прощще.

Хабр отнёс мой коммент к вам. Это конечно же не к вам а к человеку в цепочке

UFO just landed and posted this here
Да как ни организуй, все равно, 500 компонентов помнить не будешь.
CSS Modules к бему не относится, вопрос чисто про бем был.
Помещение их в один каталог убирает необходимость помнить малой (тхнически) кровью, ОС не даст создать каталог с тем же именем. Можно и какие-то верификаторы/лиентеры прикрутить, если каталог с 500 подкаталогами напрягает.
Эта проблема ортогональна БЭМ-у, она возникает (и довольно легко решается) при любой методологии.
Решение: запрещено использовать имена блоков, состоящие из одного слова, потому что однословные имена всегда слишком общие и расплывчатые.

Ну назову я список .products (товары) и что? У меня товары есть в каталоге, в корзине, в вишлисте, в инвойсе, в истории заказов…
Другой пример: блок .header — сразу признак малоопытного верстальщика. Хедер может быть у страницы, у статьи, у сайдбара, у модалки, у чего угодно. Это камешек в огород тех чудаков, которые думают, что семантические тэги header или nav решат все их проблемы.

Помимо принадлежности к странице, еще нужно различать группы товаров и собственно товары.

Поэтому в 99% случаев имя блока состоит из 2-3 слов. 4 слова и более уже многовато и используется только изредка.

.catalog-products-list — список товаров в каталоге
.catalog-products-list__item — элемент списка, отвечающий за позиционирование вложенного блока
.catalog-products-item — отдельный товар (каждый блок знает только собственное устройство, но ничего не знает о своем позиционировании)
.catalog-products-item__title — заголовок товара и так далее

Предвижу возражения.

1. Это же так длинно и нечитабельно!
Да, длинновато. Нет, вполне читабельно. К длине классов быстро привыкаешь и вскоре именно они становятся очень удобны и информативны. Прочитал и сразу все понятно. А не ползанаешь по дев-тулс в попытках понять, из какого каскада класс .list подхватил это свойство…

2. Почему не использовать модификаторы?
Типа вместо .catalog-products-list не написать .products-list--catalog.
Иногда можно. Но вообще модификаторы предназначены для смены декора, а семантически и по конструкции блок должен быть один и тот же. В нашем примере список товаров в каталоге и корзине существенно отличаются по всем показателям.
Ну вот есть у меня блок .catalog-products-list еще в одном месте, и это логичное имя для этого блока, сколько слов бы ты не использовал, пересечение все равно очень сильно вероятно.
У вас несколько разных и при этом равноправных каталогов? Допустим.
Но тогда вы их как-то различаете? Условно говоря, один будет primary-catalog, другой secondary-catalog. Соответственно получаем .primary-catalog-products-list.
Или может один будет promo-catalog или ещё как-то. Ноги обычно растут из бизнес-логики, никакие имена классов не выковыриваются из носа.
да несколько разных и равноправных. Если над проектом работает один разработчик, он скорее всего так и сделает, но если в проект пришел еще один разработчик, который не в курсе что где-то там есть еще один такой блок с таким же именем. Он не выковыривая из носа, следуя бизнес логике называет этот блок точно так же. И получаем проблему.
Вероятность такой проблемы есть всегда.
Но если она случается, при использовании БЭМ-а она сравнительно легко решается, потому что блоки независимы — где-то что-то переименовали, и оно дальше работает. Просто небольшой рефакторинг, нормальный рабочий процесс.
А вот если там было месиво из многоступенчатых каскадов, да размазанных по разным файлам… Удачи в отладке :)
в проект пришел еще один разработчик, который не в курсе что где-то там есть еще один такой блок с таким же именем.

Очень просто: храните стили блоков в отдельных файлах. Имя файла == селектору блока. А дальше файловая система вам просто не позволит создать два файла с одинаковым именем.
Сейчас вам расскажут, что новый человек не знаком с файловой структурой проекта, поэтому он сделает файл-дубликат в отдельной папке.
Любую систему можно сломать при должном уровне криворучия.
Ну а я отвечу, что даже если стили проекта разбиты по смысловым подпапкам, то нужно быть полным идиотом, чтобы создать дубликат файла _catalog-products-list.scss не в условной папке catalog (shop/products/etc), а в какой-нибудь personal. =)
Уволить того, кто добавил новый класс не посмотрев, есть ли такой класс уже в проекте. Не шучу. Это уровень даже не джуниора.
Как только ты начинаешь делать большие сложные штуки на вебе — всякие Яндекс-почты, Google Docs, админки CMS, и прочее такое — на красоту семантику CSS и HTML становится вообще совсем по барабану.

Семантика в таких аппах строится на уровне компонент, а CSS/HTML — остается низкоуровневым таким ассемблером, где важно все ровно поставить, важно чтобы оно с другими компонентами не пересекалось, а какие там хаки и как это все в исходниках выглядит — вообще всё равно.

Часто не BEM, а вообще CSS-in-JS инлайнами, или CSS Modules, где классы вообще до «f2ds3» сжимаются.

Так что странно смотреть на BEM с позиции «CSS писать и смотреть не удобно». В проектах где BEM — этот весь лишний код генерируется, и всем пофиг как оно выглядит.

Руками по BEM писать на чистом CSS и HTML небольшой сайтик, или даже селекторы типа «hero-button__caption» — это бред, конечно, не надо так делать.
а потом открываешь какую-нибудь Яндекс-почту или Google Docs, и браузер начинает скрипеть и корежится, с таким подходом (см CSS-in-JS инлайны и иже). И не приведи робот, если ты еще разработчик и тебе этот чужой код еще когда-нибудь нужно будет модифицировать.

Keep it simplе and stupid clear, мой дорогой друг. И вещи, которые ты делаешь, будут служить годами и радовать людей своей простотой и изяществом.
HTML и CSS выглядит как красивая семантичная история, только для людей, которые про это читали в книжках, и ничего сложного на нем не делали. Для тех кто пилит интерфейсы, CSS, HTML и JS — выглядит как блевотно задизайненное, и хреново работающее говнище, на котором ценой невероятных усилий и хаков, можно делать что-то на уровне интерфейсов из Windows 95.

Ты, дорогой друг, перед тем как давать ценные мудрые советы, сначала убедись что они не приводят к нищете и депрессии. Например, отыщи хоть один коммерчески успешный и семантично сверстанный сайт, с чем-то посложнее тупо статического контента.
Вы сейчас своим пассажем про " читали в книжках" на весьма зыбкую почву ступаете :)

Я не знаю, что в вашем представлении «коммерчески успешный». Но любой опытный разработчик вам скажет, что есть порог абстракции, после которого выгоды оптимизации процесса методом модульного абстрагирования, например, начинают проигрывать на фоне чрезмерной усложненности системы. Особенно если контуры будущего наращивания системы не очевидны. Не говоря уже о тенденции таскать из проекта в проект одни и те же убогие паттерны. И хорошо, если разработчик понимает, Что он таскает. Так зачастую же нет! Он просто увидел где-то и рад так же «запилить», просто потому что об этом уже написали в блоге другие такие же горе-разработчики, а так же из неофитского страха «отстать от тренда».

То, что нынче сайтов перегруженных модными девелоперскими свистелками, пруд пруди — не повод для того, чтобы делать так же.

Вообще, я вижу две основные причины тому:
а) мода на псевдоноваторские подходы (когда юный падаван не в состоянии отличить «те же яйца вид сбоку» от реально хороших идей, покуда его уровень понимания работы системы ограничивается уровнем отображения его верстки в браузере)
б) когда дедлайны и некомпетентность менеджмента диктуют рамки, в которых разработчики вынуждены находить быстрые но неэффективные решения, как в плане архитектуры самого проекта, так и бизнес-процесса в целом.

Применительно к нашей теме: ирония в том, что желание заглянуть в код возникает не тогда, когда ты не замечаешь frontend, а когда frontend по ощущениям настолько убого сделан, что невозможно устоять от искушения заглянуть «под капот». Но на вскидку…

Вот например сайт www.gov.uk
UK government services and information. Загляните в код, обратите внимание как все там аккуратно сделано. Так вот, это интерфейс автоматизированной системы полностью обслуживающей граждан Соединенного Королевства. Система налоговых отчетов, разного рода лицензирования, ИНН, выплаты на здравоохранение, все, что вам надо от гос сервиса. Там столько классно придуманных и просто сделанных нюансов внутри, что можно целый день рассказывать.

PS ну и за лексиконом я бы вам тоже посоветовал следить. А то, знаете ли, неприятно.
Простите, что вмешиваюсь в вашу дискуссию, но я так и не понял, кто из вас против БЭМ, а кто за.

Заглянул в код gov.uk, впечатления соответствуют названию:


  1. Дикий каскад в селекторах (#footer .footer-categories .footer-explore h2,#footer .footer-categories .footer-inside-government h2).
  2. Стили навешанные на теги и идентификаторы.
  3. Однако часть стилей сделана по БЭМ.
  4. Не собранные в бандлы стрипты и стили.
Для тех кто пилит интерфейсы, CSS, HTML и JS — выглядит как блевотно задизайненное, и хреново работающее говнище.

C 2009 (если считать с даты начала официальной работы, а не школьного баловства) пилю-попиливаю сайты разной сложности и могу сказать, что люблю и уважаю и HTML, и CSS, и JavaScript. Конечно, сейчас я в основном пользуюсь SASS вместо чистого CSS и препроцессором для JavaScript. Однако я не совсем понимаю таких комментариев, как ваш, а также разговоры о том, что, де, "верстка и фронтенд — говно, бекенд — зашибись". Причем на чем бы этот бекед ни писался.

Мой поинт не «верстка и фронтенд — говно, бекенд — зашибись». Я фуллстек, но больше люблю фронт — там сложнее и интереснее, и тоже уже 10 лет этим занимаюсь.

Мой поинт в том, что не надо воспринимать CSS/JS как божью росу, и заводить разговоры типа «вы дураки со своими реактами и тайпскриптами, всё можно сделать в 10кб на прекрасном, мудром, семантичном JS/CSS». Flexbox не смог — ок, JS-ом div-ы подвигаем. Не выходит сделать плавную анимацию CSS — берем canvas и рисуем сами на нём. Не получается нормально сделать работу команды с одним CSS-файликом — берем пре-процессор и лепим всякие сложные миксины, и пофиг что там в результате в самом CSS получится.

Только так сложные приложения и делаются. А на божественно-семантичном, чистом как слеза CSS, можно разве что какой-нибудь простой статический сайт сделать. Банальный DatePicker — уже треш, угар, и хаки.
Простите, а что такого сложного в Яндекс.Почте _с точки зрения дизайна_?
UFO just landed and posted this here
Поддерживаю вас в том, что ни автор статьи ни те кто плюсуют не знают БЭМ и скорее всего далеки от фронтенда.
Но ваш пример плохой, поскольку сильно затрудняет поиск класса по проекту. Это из личного опыта. Просто подумайте как вы будете искать класс .article-rewind__text в исходном коде?
Современные IDE прекрасно умеют находить нужные селекторы в исходных less/sass/postcss файлах.

Если подобный подход используется повсеместно и я об этом знаю — я найди блок .article-rewind, а потом внутри него найду блок &__text. Если я не знаю что такой подход используется повсеместно — я попробую найти .article-rewind__text, не найду, начну смотреть файл с начала и увижу в чем дело.


А вот если такой подход используется ровно для одного стиля — да, это может стать проблемой...

В проекте в котором я участвовал, было примерно так:
.article-rewind {
  ... 500 строк
  &__text {
    ... 100 строк
    &--red {}
    ... 100 строк
  }
  ... 500 строк
}
Это уже отдельная проблема. Ну не должно быть стилей по 500 строк…
Так из-за вот этих &__element и получается столько строк!
Без них это были бы отдельные стили. Вот что я имел в виду:
.article-rewind {
 ... 500 строк
 &__menu {
   ... 100 строк
 }
 &__link {
   ... 100 строк
 }
 &__text {
   ... 100 строк
   &--red {}
   ... 100 строк
 }
 &__etc {
   ... 100 строк
 }
}
Какой-то God Block получается. Все у него есть: и меню, и ссылка, и текст — и все элементы одного блока, и все это застилизовано вусмерть…
Если там несколько раз по 500 строк, блоку совершенно точно требуется декомпозиция.
Я бы начал задумываться о декомпозиции уже после ~100-150 строк суммарно на весь блок, включая все элементы и модификаторы.
Дополнил пример:
.article-rewind {
 &__menu {
   ... 100 строк
 }
 &__link {
   ... 100 строк
 }
 &__text {
   ... 100 строк
   &--red {}
   ... 100 строк
 }
 &__etc {
   ... 100 строк
 }
}

Какой тут способ декомпозиции кроме как не использовать &__element?
Элемент на 100 строк тоже требует декомпозиции. Скорее всего, он вполне потянет на отдельный блок. У меня стили для одного элемента обычно не превышают 20-30 строк.
&__menu {
... 20 строк
@media-for-tablet{
...20 строк
}
@media-for-desktop{
...20 строк
}
@media-for-UHD-desktop{
...20 строк
}
@media-for-print{
...20 строк
}
@media-for-tv{
...20 строк
}
}


Итого 132 строки
То есть каждый из медиазапросов переопределяет все-все-все стили? Кажется, с таким подходом вам будет намного проще делать 6 отдельных сайтов :-)
смысл же не конкретно в 20 строчках, а в том, что в файле может быть очень много строк, даже если это всего лишь элемент
UFO just landed and posted this here
Нет, медиа именно так и нужно писать, а за отдельные файлы бить по рукам.
Кого беспокоят лишние байты — есть специальные плагины для сборщиков, которые вытянут и скомпонуют.
UFO just landed and posted this here
Никаких проблем. Компоновать стили надо по смыслу, а не по технологиям.
Если у меня есть блок, то я хочу видеть его поведение сразу и полностью, а не ползать по нескольким файлам, сравнивая их построчно.
По факту при таком различии стилей — у вас действительно много разных сайтов, а не один адаптивный. Возможно, проще и разный HTML при этом отдавать?
UFO just landed and posted this here

Поделитесь css-кой? Я не могу себе представить, что там менять на 100 срок при

UFO just landed and posted this here

Есть плагин для gulp — group media query's.

UFO just landed and posted this here
Никогда у меня такого не было. Обычно у элемента для каждого медиа-запроса переопределяется пара-тройка свойств, а то и вообще ноль. Элемент это ведь маленькая простая сущность, чему там меняться? Ну размер или отступ какой-то.
Повторюсь: если там реально приходится писать 132 строки, нужна декомпозиция.
Нельзя просто так взять и применить в проекте файловую стукруту удобную для верстальщика.

Пример который я привел, был взят из проекта на AngularJS. Там была своя файловая структура, базирующаяся на компонентах AngularJS.

sourcemap. Сборщики умеют, браузеры (во всяком случае Хром точно) поддерживают. Видно и имя исходного файла, и номер строки.

Понапроходят курсов, считают что всё знают, а опыта нет. Не понимают зачем и почему именно так придумана технология. А потом мы видим такие статьи
БЭМ — это прекрасно. Поддерживать код с БЭМом в миллион раз проще, чем с лютыми каскадами селекторов по тегам.
Я могу сделать ctrl+клик по «ужасному, длинному» классу и моментально оказаться в определении селектора. Куда я попаду если сделаю такой клик по тегу или какому-нибудь классу ".active"? Правильно, в список из 146 различных файлов, где такое определние встречается.
Или нужно мне добавить враппер вокруг элемента, так я беру и добавляю его и ничего не ломается.

Маленький лайфхак в именовании классов, который мне нравится куда больше оригинала:
.Block-Name__element--mod

Именование может быть любым, главное, чтобы можно было программно определить где блок, где элемент, а где их модификаторы/значения:


https://ru.bem.info/methodology/naming-convention/

По приведенной вами же ссылке написано нечто противоположное вашим словам. А именно, там есть параграф «Правила формирования имен», который устанавливает эти самые правила формирования имен.
Долистайте до конца что-ли:
ru.bem.info/methodology/naming-convention/#%D0%92%D0%B0%D1%88%D0%B0-%D1%81%D1%85%D0%B5%D0%BC%D0%B0-%D0%B8%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F

Верхние правила — это классика. Есть ещё западное именование через "--", есть реактовское через CamelCase. Но самый последний пункт — «Ваша схема именования»
BEM это изоляция. Слышите? ИЗОЛЯЦИЯ. Когда у вас к сайту подключается сторонний скрипт галереи или прочего «коня в вакууме» ВЕМ не даст порушить всё и вся. Если вдруг пересекутся названия блоков то поедет именно этот блок, а не вся верстка. Если завтра левому человеку надо будет в определённом блоке сделать отступ у определённого элемента он не напартачит футер только потому что он просто после редактирования ё класса не увидел больше никаких изменений на странице.
Вообще ничего не понял! Если БЭМ нужен только для изоляции, то к чему тогда вообще городить велосипед? С задачей изоляции как раз справляются уникальные именования классов (что БЭМ как раз никак не решает).
Ну и поехавший блок как раз может разворотить всю вёрстку. И искать причину (какой нибудь font-size:0;) вы можете очень долго.

P.S. Почему-то у сторонников БЭМ всегда есть аргумент — «поналепят каскады тэгов, а потом удивляются почему вёрстка поехала». При этом почему БЭМ противопоставляется исключительно каскадам тэгов — не очень понятно…
Это было объяснено несчетное количество раз, но многие почему-то не понимают. Или не хотят понимать, что вероятнее. Очень кратко в стопиццотый раз. Пример утрированный, чтоб на пальцах.

Есть страница, у неё есть шапка и подвал. Есть модальное окно, у него тоже есть шапка и подвал. Если написать так
body header { ... }
.modal header { ... }

то стили глобального хедера применятся не только где надо, но и к хедеру модалки тоже. Ну потому модалка очевидно входит тоже входит в body.

Но погодите! — скажет любой неофит, окончивший курс «Верстка за 24 часа» — ведь можно написать вот так:
body > header { ... }
.modal > header { ... }

Можно, но только в идеальном мире, где html-структура делается один раз и навсегда. А в мире реальном она в ходе жизни проекта меняется много раз — доработки дизайна, функционала, багофиксы… Хотелки заказчика, дизайнера, сеошника… И частенько бывает нужно вставить промежуточную обертку. Или переподчинить узел другому родителю. Или сменить тэг. Или перенести что-то в другое место страницы.

Каскад нужно во-первых переписывать, а во-вторых молиться, чтобы эти изменения не поломали что-то в совершенно другом месте. Поэтому часто никто этим не заморачивается, а просто херачит рядом перекрывающий более специфичный селектор. Очень скоро всё это дело выходит из-под контроля.
При БЭМ-е доработки тоже понадобятся, но точечные.

Не понимать побочных эффектов каскада может только либо полный новичок, либо верстальщик, всегда работавший по принципу «сверстал, отдал, забыл» — потому что для него страница статична, он никогда не видел что с ней происходит потом.
В стопитцотый раз:
body header
body .modal-header

Почему противников тотального использования БЭМа принято считать полными идиотами? И всё у них разваливается постоянно, и классы они одни и те же используют, и каскады из тэгов строят… Если очевидно что стили затронут другой элемент DOM не имеющий каких-то наследственных признаков с родительским (сознательно не употребляю «блок»), то зачем к нему обращаться через подобный каскад? Причём тут вообще БЭМ? Дурак и на БЭМе напишет .header_wrap для обоих блоков.
Ага, уже проклюнулись первые зачатки бэма — modal блок, header элемент.
Какими символами они при этом разделены, совершенно неважно, это вопрос договоренностей и вкуса. Вы на правильном пути. Осталось понять, а зачем во втором случае привязываться к body?
Вообще незачем. Просто по аналогии с вашим верхним постом. Это даже вредно — без нужды повышает приоритет правил.
Ну так а при чём тут БЭМ? Это же всё довольно очевидные вещи. При этом БЭМ задаёт довольно жёсткие рамки, а я призываю к гибкости, а не копипастному следованию «философии БЭМ». Ладно, это всё бессмысленные споры и им уже не один год. Кто привык сидеть на БЭМ — будет защищать эту технологию и наоборот.
Потом вы решите что а чего это вдруг мне не переиспользовать блоки. Потом вот в этом блочке мне бы заголовок чуть больше и вуаля вы переизобрели блоки, элементы и модификаторы.

Я сам был не сторонником BEM'а думая что это уже излишества. Но чем сложнее становятся проекты и чем дольше ты работаешь непрерывно в «сфере» ты потихоньку изобретаешь велосипеды и потом сам видишь что твои мысли неутомимо сами собой стремятся к BEM'у.
Нет. Для меня особое удовольствие доставляет мозговой штурм при проектировании каркаса лэйаута и корректном определении глобальных стилей — задача довольно опасная (и не необходимая). Но при это «читаемость кода» значительно возрастает.
В реальной жизни лейаут не константа, он постоянно меняется — это аксиома. И любая сильно связанная система быстро вступит в противоречие сама с собой.
Так я про то же речь и веду! Его надо продумывать. Просто сверстать по макету вообще не проблема. Но приходится учитывать например, что переход на мобильную версию осуществлялся только стилями на той же структуре HTML (а не display:block/display:none). Тот же flex — довольно гибкая штука (пардон за тавтологию) — главное изначально всё правильно поставить.
Хотелось бы с вами насчёт этого поговорит через годик. Если конечно вы всё это время проведёте в сфере верстки.

BEM сверх читаем. Бэкендщики просто слюной изливаются видя верстку согласно BEM'а ибо знают, что здесь нет костылей, подводных камней и прочего. Бери и внедряй.
Некропостинг помог увидеть комментарий. У меня в этом году юбилей — 10 лет версткой занимаюсь. За последнее время отношение к БЭМ стало из умеренно-негативного — резко-негативным. Сейчас он расползся так, что увидев именование классов по БЭМ — скорее всего тебя ждут большие проблемы. Внутри будет полная каша. Никаким переиспользованием, изоляцией и т.п. там и пахнуть не будет. Будут только классы с двойным подчёркиванием.
Я даже не переиспользование кода в разных проектах. А в рамках одного и того же проекта.
Та же кнопка. Это блок с различными модификаторами и отсутствием или присутствием тех или иных элементов внутри.
Блин это уже 3 сообщение подряд уж простите.
По поводу читаемости и понимания BEM.

Вот есть у нас кнопка (пишу чисто классы и поясняю)

.button.button_large

Я сразу понимаю что у нас есть кнопки .button и они где-то используются, а это частный случай и к ней применён модификатор. Согласно BEM модификатор отвечает за то КАК меняется блок и элемент.
Идём дальше. Внутри я вижу типа такого

.button__icon.icon
.button__text

Я понимаю что у нас внутри есть иконка и она выделена в отдельный блок .icon и это неспроста. Значит этот блок используется на странице ещё где-то и так просто его редактировать не стоит ибо повлияет глобально.

Это элементарный пример увидя который, просто как бы открыв код HTML наугад, я получил просто море информации. И вы хотите сказать что это понижает читабельность?
Меня бэкэндщики тоже любят — я частенько сам внедряю. А ещё приятнее внедрять бэкэнд, когда классы нормально читабельны, а возникновение костылей и подводных камней — это уже не проблема бэкэнда, над этим должен думать фронтэнд. Так что сомнительный довод.

А давайте я вам теперь своё видение расскажу. Вот открываю я БЭМный код и вижу ".button.button_large". И мне это вообще ничего не говорит! Есть ещё блоки с таки классом и или нет. Мне это говорит только о том что человеек делавший вёрстку использовал синтаксис БЭМ. Всё! Мне все равно придётся открывать браузер и веб-инспектор, проверять, прокликивать и т.д. Или что, по-вашему БЭМный синтаксис сразу даёт какую-то гарантию?
Тут… Эта… Мои полномочия всё…
«Вот открываю я email с ТЗ и вижу набор кириллических символов и это мне вообще ни о чём не говорит! Мне это говорит лишь о том что мне придётся запускать скайп и обговаривать с заказчиком ВСЁ! Неужто умение читать даёт какое либо преимущество?»
Вы совершенно не понимаете BEM вот о чём это говорит. И спор в виду этого факта становится бесполезным.
Ну да, математика высших сфер. Куда уж нам…
И все же есть ситуации, когда структура не может быть произвольной.

table (> tbody) > tr > td
select > option
Тег tbody может быть, а может не быть. Или вместо него может быть thead/tfoot. Вместо тэга td может быть th.
И? И что из этого следует? BEM разве про произвольную структуру, вроде как наоборот. Элемент не отделим от блока.
Человек взял и все плюсы BEM, буквально перенес в минусы.
Мне кажется (я не работал с CSS/HTML в большой команде), что БЭМ — это про упрощение разработки для людей.

Каскадные стили и наследование — это очень круто, когда один человек может охватить всю совокупность стилей на проекте сразу и целиком — и в состоянии построить карту зависимостей, карту наследований стилей от стилей.

Если этой возможности нет — приходится:

А) тратить каждый раз время верстальщика на изучение «А от чего там у нас наследуется div и откуда у него взялся background-color: red (и это не гарантия того, что новый верстальщик охватит весь проект целиком и поймет, что вон там в одном месте »сделали вот так, потому что в другом месте эдак, а комментарий писать было лень, ибо лапки, да и так все очевидно".

Б) использовать подход с суффиксами, переопределяющими поведение: `-active`, `-passive`, `-foobar` etc.
Этот подход ущербен, как мне кажется, тем, что опирается на умолчания, заданные где-то, что возвращает нас к проблеме «запомни-ка иерархию стилей, бро».

Б) индивидуализировать стили — как в БЭМ или в «обычном говнокодном» CSS.

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

Как-то так.

Отмечу, еще раз, что я не верстальщик с 20-и летним стажем (хотя таки да, с HTML познакомился аж в 1997 году) и не работал в крупных командах. И не использую БЭМ (хотя надо бы, наверное, но у меня лапки).
БЭМ — это про упрощение разработки для людей

Да, всё верно. Про процесс разработки с БЭМ я рассказывал тут:
https://events.yandex.ru/lib/talks/686/

Так глобально наверно не нужно, но могу сказать что 99% где заказчики требуют бэм он там не нужен.

Пример хорошей верстки без БЭМ это Bootstrap.


<button type="button" class="btn btn-primary">Primary</button>

<div class="card">
  <div class="card-body">
    This is some text within a card body.
  </div>
</div>

В данном стиле верстки есть много схожего с БЭМ, но при этом нет такой каши в именах классов. Это золотая середина, а БЭМ это крайность. Любая крайность — зло.

Bootstrap — это библиотека, весьма статичная. В реальном проекте, который постоянно меняется, причем часто кардинально, не получится сделать так красиво.

БЭМ хоть и смотрится неуклюже, со временем не превращается в говнокод.
В реальном проекте...

В реальном проекте, если вы выбираете БЭМ, то у вас тоже будут проблемы, но они будут в других местах. Верстальщик по БЭМу верит (сходство с религией), что если бы он верстал без БЭМа, то проблем было бы больше.
Вот вам пример бреда, который рождает БЭМ:
toster.ru/q/425766
Можно возразить, что всегда есть плохие верстальщики, которые всё делают неправильно. Но тогда получается, что БЭМ этим плохим верстальщикам никак не помогает, а даже наоборот.
UFO just landed and posted this here
То что по ссылке правда на БЭМ не похоже:
custom__button — custom — это блок? Или mob-full__width — width — это элемент?
Похоже даже сам Яндекс не знает что такое БЭМ.
Картинки



Каково вам было бы во всём этом разбираться? Куча блоков с двойными и тройными именами, куча модификаторов, блоки, которые одновременно являются элементами других блоков… Это так БЭМ решает проблемы? А по-моему он решает одни проблемы и создает другие. В документации всё более-менее красиво, а на практике…
Да, вы правы:) vithar что вы на это скажите?))
Великолепный пример, спасибо ))

Что именно вам не понятно в этих стилях?
Тут применён адский микс при котором одна хтмл-нода это одновременно 5 бем-элементов.
Под капотом всё собирается декларативным шаблонизатором и в этом месте нет никаких проблем — вы просто не трогаете вёрстку руками, а пишите всё отдельно, и вам не нужно разбираться сразу во всём.


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

Из этого всего можно сделать вывод, что БЭМ для тех кому пофигу что получается на выходе, быстро слепил, миксанул и готово. А то, что нет семантики, браузер многократно переопределяет стили — это мелочи. Херак-херак и в продакшен, как говорится. Самое удивительное, что это технология от поисковика, для которого семантика должна быть на первом месте.

Никто не заставляет вас делать несемантично. Это вообще не про бэм, а скорее про целесообразность.


Не готов выступать адвокатом яндекса, поэтому всё что написано ниже лишь догадки.
Подозреваю что в данном случае дополнительная семантика не так важна, если я правильно понимаю о семантике с вашей точки зрения.
Я в коде яндекса встречал элементы элементов, чего не должно быть вообще то. Возможно также здесь ничто иное как человеческий фактор

Обоснуйте обратное :)
Вот здесь объяснено почему элементы-элементов плохо.

Там, очевидно, непонимание что такое элементы элементов. Элементы элементов появляются, когда у нас есть вложенный блок в качестве элемента, и у того блока есть свои элементы, которые надо стилизовать в контексте нашего блока.
Но ведь эта ссылка на официальный FAQ по бэму

А вы инженер или прихожанин? :-)


Разделение на блоки и элементы — не более чем костыль к CSS, позволяющий реализовать каскад на уровне компонент, а не хтмл-элементов. В правильном CSS у нас были бы селекторы вида:


.button >>> .icon
.button >>> .text
.panel >>> .close >>> .icon

И никакой БЭМ даже бы не появился. Веб компоненты должны были позволить такие штуки, но их погубили фанатики-изоляционисты.

Разделение на блоки и элементы — не более чем костыль к CSS, позволяющий реализовать каскад на уровне компонент, а не хтмл-элементов.

Селектор дочернего элемента это у вас каскад ?


В правильном CSS у нас были бы селекторы вида:
И никакой БЭМ даже бы не появился

яхз при чём тут изоляция. бэм не только про изоляцию.

Не придирайтесь к словам. Наложение дополнительных стилей на дочерние блоки.

И читайте внимательнее. Изоляция в веб компонентах как раз таки мешает выкинуть бэм.
UFO just landed and posted this here

Что для вас семантика? Под семантикой часто понимается не только корректное использование конкретных тегов, но и осмысленное наименование классов. Например, чем не семантичное название класса .product-list__product?

блоки, которые одновременно являются элементами других блоков

Это вполне допустимая ситуация. Как вы иначе будете делать композицию блоков?

Бутстрап это пример очень таксебешного кода.
Не потому, что его пишут глупые люди, а потому что он:
а) ориентирован на нишу верстального фаст-фуда (я не хочу думать, я хочу фигачить тэги);
б) тянет на себе легаси-концепции из прошлого десятилетия.
UFO just landed and posted this here
Можете привести пример такого кода?
Я могу. Класс .nav очень жестко завязан и в разметке, и в стилях, и в javascript. Если вам нужны навигация, табы, несколько разных видов, то упорешься все это стилизовать. И другой класс повесить нельзя, потому что js отваливается. Так что ставить в пример bs3 — так себе идея.
UFO just landed and posted this here
Первый пример спорный, т.к., думаю, навбар разработчики не пытались сделать универсальным, это и не нужно, потому что на практике главное меню может иметь столько вариаций, что универсальную верстку сделать невозможно.
Со вторым примером я согласен, но в четвертой версии вроде такого нет.
Это слишком сложно для аудитории бутстрапа, несколько другой уровень мышления.

Самый простой способ перекрасить Бутстрап — это затянуть к себе его исходники и переопределить несколько переменных. А вот через CSS что-то переопределять — и правда сложно.

Именно. Файл theme который как бэ предназначается для стилизации темы на моей практике оказался каким то ущербным на столько, что только полные исходники дают желаемый результат

Статья неверстальщика о методогии, которую он не понял.
Верстка в принципе отстой, а с бем она отстойна в цвет яндекса.
Любые попытки стандартизировать то, что не должно быт стандартизировано по своей природе, будет вызывать вечный диссонанс, пишите, творите так как вам удобно, не оглядывайтесь ни на кого, тем более не становитесь заложником корпорократии.
Удобно то, к чему привыкаешь.
css очень сложно поддерживаемый язык. и его стандартизация немного улучшает ситуацию.
CSS это самое простое что может быть. Я не могу к сожалению исправить свой коммент выше, правильно написать «Любые попытки стандартизировать то, что не может быть стандартизировано по своей природе, будет вызывать вечный диссонанс, пишите, творите так как вам удобно, не оглядывайтесь ни на кого, тем более не становитесь заложником корпорократии.»
Хорошо, раз уж вопрос встал про поддерживаемость. Куча откликов что, дескать, в крупных проектах по другому нельзя. В крупных проектах и без того имеются свои правила написание кода, договоренности по именованию сущностей и т.п.
Первая проблема БЭМ — он по факту абсолютно не поддерживаем. Представьте, вам дают совершенно незнакомый проект на БЭМ и… скажем, говорят «у нас на сайте используется фирменный градиент с анимацией, надо бы поменять в нём цвета и сделать его двойным». Вы открываете стилевой файл и… что делать? Открывать веб-инспектор и вручную прокликивать каждый блок, потому что:
Не имеет смысла объединять разные по типу блоки, только потому что у них, например, одинаковый цвет или размер.

В любом вменяемом css-файле, где-нибудь ближе к началу наверняка будет определение а-ля ".blue-gradient".
Из этого вытекает вторая проблема БЭМ — он абослютно не гибок. Проекты бывают разные. Где-то надо нагородить несколько сотен блоков, а где-то хватит и пары (а всё остальное графика), а где-то вообще не используются блоки. И подходить ко всей этой кухне с такой категоричностью «не использует», «не должны», «не может», «не рекомендуется». То, что Яндекс вполне успешно пропагандирует внутри своей компании эту философию, вовсе не означает что её надо бегом возводить в разряд спецификаций. В разработке важен гибкий подход и выбор подходящего инструментария для каждой конкретной задачи, а вовсе не «только БЭМ, остальное говнокод».
UFO just landed and posted this here
Т.е. мне ещё надо разбираться с конкретным препроцессором, вычленять оттуда нужные стилевые свойства и т.п. К тому же у механика работы препроцессоров идёт в разрез с философией БЭМ. А что, градиент (стилевое свойство отдельного блока) в БЭМ уже вдруг является отдельной сущностью? А псевдо-элементы в БЭМ тоже отдельными блоками реализуются?
Понимаете, вы смотрите на это со своей кухни — когда работаете в одной команде над одними и теми же проектами несколько лет — конечно, вам нет особой нужды смотреть на подобные вещи более абстрактно. Ну так вот пусть и яндекс проповедует это как собственную внутреннюю кухню, а не как «стандарт для веба».
UFO just landed and posted this here
Разве Яндекс говорил, что БЭМ следует всегда использовать всем? Вот автор данной статьи категорично заявляет, что никто никогда не должен им пользоваться.

Да, но занимается довольно активной рекламой. Так что мне неоднократно приходилось слышать требования к вёрстке одностраничного хомяка «БЭМ, SASS, Bootstrap»…
Это просто прекрасная страница! )))

Здесь у нас Параграф стиля Параграф. Ой, нет, он же в Статье. Значит, стиль будет Параграф-в-Статье. А у Списка — Список-в-Статье!

Тут впору изобретать NCSS — Non-Cascading Style Sheets!
<div class="article">
<h1 class="article__heading article__heading_level_1" ...>
<a class="article__heading-anchor" href="....>
<p class="article__paragraph">
<a class="article__link">
<ul class="article__list">
<li class="article__list-item">
Non-Cascading StyleSheet

А при чём здесь каскад?
Каскадирование — это не просто вложение селекторов (.parent .child {}). Это комплекс правил, определяющих применение стиля к элементу, и специфичность (на которую влияет вложенность) далеко не единственный фактор. Не хочется повторяться, подробное погружение можно начать отсюда developer.mozilla.org/ru/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance
В любом вменяемом css-файле, где-нибудь ближе к началу наверняка будет определение а-ля ".blue-gradient".

Кроме градиентов там еще могут быть тени, заливки, оформление текста и много чего еще. Найти в такой куче нужный градиент будет уже не так легко.


А еще дизайн проекта может меняться. Легко можно докатиться до такой конструкции:


.blue-bakground {
   background-color: green;
}

Staticlab правильно говорит. Переиспользуемые значения выносятся в миксины и константы. Причем в любом проекте, неважно, БЭМ там или нет.

Три сотри каментов и никто не отважился написать, что BEM по сути подход-костыль, задача которого убрать синяки и грабли от использования голого и безыдейного css. Сейчас таких костылей в индустрии несколько, что говорит о наличии проблемы, можно сказать даже боли.

Фактически сейчас css, как и html, превратился в эдакий машинный язык, который люди уже не читают и на котором не пишут. Мы давно уже используем другие языки, результатом работы которых является css или html, а с голым css или html сейчас уже почти никто не работает.

Думаю, что через несколько десятков лет решение найдется. Какой-то подход зарекомендует себя лучше других и войдет в стандарт css.

А пока как-нибудь так, как-нибудь так.
UFO just landed and posted this here
БЭМ не костыль

Такой подход к оформлению хорош для оформления статей и книг, но плохо подходит для оформления веб-приложений.
Я воспринимаю это так: БЭМ решает проблему, которая возникает из-за того, что css плохо подходит, т.к. на сегодняшний день устарел.

Т.е. сегодня css используется именно для современных веб-приложений, но плохо для этого подходит. Значит правильным решением будет изменить css, а не придумывать способ обойти проблему.

А так как БЭМ является способом обойти проблему css, не меняя css и не устраняя эту проблему, то именно поэтому я считаю, что БЭМ — костыль.
БЭМ по медицинским анлогиям скорее не костыль, а смирительная рубашка фиксирующая повязка, «гипс» ограничивающий свободу, которую даёт CSS, более узкими рамками, чтобы самому себе не навредить.
UFO just landed and posted this here
в современных фреймворках он уже и не нужен

У вас есть сторонний компонент "button" в стороннем компоненте "calendar" в стороннем компоненте "datepicker". Вы пишете компонент "daterangepicker" и вам надо по особому стилизовать ту самую кнопку "selected_date" в календаре. Причём по разному в обоих пикерах. Как "современные фреймворки" решают эту проблему?

UFO just landed and posted this here
Вы пишете компонент "daterangepicker" и вам надо по особому стилизовать ту самую кнопку "selected_date" в календаре. Причём по разному в обоих пикерах. Как "современные фреймворки" решают эту проблему?

Если вам хочется стилизовать сторонний компонент — используйте публичное апи этого компонента. А за попытки править стили компонентов внешним цссом следует руки отрывать.

То есть, если дизайнер хочет градиентик на какой-то конкретной кнопочке, то нужно либо оторвать ему руки, либо форкать и патчить все три сторонних компонента, либо велосипедить свой датепикер с нуля? Но ни в коем случае не писать что-то типа:


[my_daterange_from_calendar_selected] { /* градиентик один */ }
[my_daterange_to_calendar_selected] { /* градиентик другой */ }

Я правильно вас понял?

Я правильно вас понял?

Правильно. Ведь в следующем апдейте ваш [my_daterange_from_calendar_selected] может совершенно незаметно для вас сменить название без нарушения обратной совместимости, и ваша верстка превратится в тыкву.


Естественно, на практике, когда ну совсем надо, использование недокументированного поведения, почерпнутого из потрохов используемой библиотеки, может быть допустимо, но это именно крайняя мера, требующая отдельного обсуждения и согласования с явным обоснованием допустимости в конкретном случае, с четким пониманием того, что вы закладываете бомбу замедленного действия.
Но нормой или чем-то к ней близким это быть не может.

UFO just landed and posted this here
Апдейты ставят когда старая версия неправильно работает или с чем-то новым несовместима.

Вы уж определитесь, либо без нарушения совместимости, либо тыква. Но знаете, после мажорного апдейта проверить зависимый компонент и поправить классы, если вдруг, — несоизмеримо проще, чем поддерживать 3 форка и уж тем более собственную реализацию.

Вы уж определитесь, либо без нарушения совместимости, либо тыква.

Нарушение обратной совместимости — это изменение публичного апи. Изменение деталей реализации (к каковым относятся верстка и стили) публичное апи не меняет, по-этому эти детали могут меняться как угодно в любом минорном апдейте. И вы сами себе злобный буратина что раскопали потроха реализации и теперь на них завязались, в результате чего у вас тыква.


Но знаете, после мажорного апдейта проверить зависимый компонент и поправить классы, если вдруг, — несоизмеримо проще, чем поддерживать 3 форка и уж тем более собственную реализацию.

Ну вы не забывайте, что это все еще надо обсудить, согласовать…
А можно просто сделать форк (одну кнопку нажать) и оформить возможности кастомизации требуемых компонент по-человечески, вместо того, чтобы лепить говнокод.

Изменение деталей реализации (к каковым относятся верстка и стили) публичное апи не меняет, по-этому эти детали могут меняться как угодно в любом минорном апдейте.

Всё, что видит пользователь — публично по определению. Вы можете сколько угодно фантазировать про инкапсуляцию, но если кнопка стала в 2 раза больше или из квадратной стала круглой без изменения JS API — дизайн будет сломан.


Ну вы не забывайте, что это все еще надо обсудить, согласовать…

Тут нечего обсуждать и согласовывать. Есть типичная задача — есть типичное решение. А вот разработку велосипеда надо и обсуждать и согласовывать. Также как и поддержку форков.


А можно просто сделать форк (одну кнопку нажать) и оформить возможности кастомизации требуемых компонент по-человечески, вместо того, чтобы лепить говнокод.

В первом форке переключить зависимость на второй форк. Во втором на третий. Потом надо в первом форке изменить апи, добавив прокидывание дополнительного параметра во второй. Во втором — в третий. В третьем реализовать добавление его в нужное место. И повторить эти действия для каждого элемента, который захочет кастомизировать дизайнер. Примечательно, что имена параметров вскоре выродятся в тот же "путь до нужной кишки" вида "from_calendar_selected". Потом вам нужно следить за апдейтами в апстриме, периодически накатывать их в каждый форк, каждый раз разрешая одни и те же конфликты и переключая каждый форк на новые версии зависимостей. Если вы ещё и решите использовать не git submodules, а локальный npm-repo, то к этому добавится ещё и обновление версий, изменение имён зависимостей и публикация всех этих зависимостей в npm-repo.

Всё, что видит пользователь — публично по определению.

Так пользователь не видит CSS, он видит результат его работы. В компоненте поменяли название стиля, компонента как выглядела так и выглядит, она не изменилась. Сломался ваш кастомный css, делая который вы использовали приватные детали реализации.


Тут нечего обсуждать и согласовывать. Есть типичная задача — есть типичное решение.

Так использование костылей, которые закладывают бомбу под ваш проект — это как раз нетипичное решение. Естественно, его требуется обсудить и согласовать.


А вот разработку велосипеда надо и обсуждать и согласовывать. Также как и поддержку форков.

А вот форк — решение как раз типичное, у такого решения нет никаких проблем.


Потом вам нужно следить за апдейтами в апстриме, периодически накатывать их в каждый форк, каждый раз разрешая одни и те же конфликты и переключая каждый форк на новые версии зависимостей.

Вы же апдейты ставить не собираетесь? А если собираетесь — все то же самое вам придется делать и в случае предлагаемых вами костылей, только сильно сложнее.


Вы сейчас топите за нарушение инкапсуляции, это просто не имеет смысла. Общая практика длиной в десятки лет показывает, что бесконтрольное нарушение инкапсуляции в итоге приводит к значительно большим проблемам, чем адекватные решения.

вы использовали приватные детали реализации

Это точка расширения, а не приватные детали. И просто так точки расширения не переименовываются.


Так использование костылей, которые закладывают бомбу под ваш проект — это как раз нетипичное решение.

Думаю автору фреймворка виднее что в нём является типичным решением, а что — нет. А не человеку, который не потрудился разобраться в предлагаемом подходе. Уже третий год я разрабатываю компоненты $mol, и веду разработки на их основе, где применены те же идеи. За это время подход показал себя более чем положительно и никаких "бомб" обнаружено не было. Потрудитесь, пожалуйста, разобраться или не делайте громких заявлений о том, что не пробовали.


А вот форк — решение как раз типичное, у такого решения нет никаких проблем.

На поддержку форков для каждого проекта вы потратите в 10 раз больше времени, чем на поддержку одного селектора, даже если тот будет ломаться при каждом обновлении (что далеко не так). Если для вас это не проблема, то на этом нашу дискуссию можно закрывать. Запилите 10 проектов, для каждого из них по 10 форков сторонних компонент. А когда устанете от этой православной рутины — буду ждать вашего возвращения и описания впечатлений.


А если собираетесь — все то же самое вам придется делать и в случае предлагаемых вами костылей, только сильно сложнее.

Что именно "всё то же самое"? Ничего из перечисленного делать не придётся.


Вы сейчас топите за нарушение инкапсуляции

За отсутствие сокрытия. Сокрытие капитально снижает гибкость. Горячо любимые вами форки — это ведь тоже ни что иное как "открытие" стороннего кода. Тот же пресловутый "паблик морозов", но на уровне репозиториев, а не классов. Благами инкапсуляции можно пользоваться и не закрывая компоненты от расширения — тогда не надо будет их мучительно открывать с форками, обсужениями и прочими замедлителями разработки.

На поддержку форков для каждого проекта вы потратите в 10 раз больше времени

Создаем пулл-реквест, ждем пока его вмержат. Если не хотят мержить, используем своё. Замержили и зарелизили? Используем дальше)


Запилите 10 проектов, для каждого из них по 10 форков сторонних компонент.

Именно поэтому вы запилили $mol и активно его везде форсите?

Кастомизацию, сделанную под один конкретный проект не вмёржат никогда. А даже если вы сделаете действительно полезный многим PR, то вам придётся не одну неделю убеждать мейнтейнера, что он действительно полезный. Вы когда-нибудь пробовали продвинуть PR в сторонний проект?

$mol я запилил для быстрой и качественной разработки. Упоминаю я его как живой пример реализации тех идей, о которых вам говорю. Будете ли вы использовать $mol или нет — мне по барабану.
Это точка расширения, а не приватные детали. И просто так точки расширения не переименовываются.

Точкой расширения является то, что автор явно указал, как точку расширения.


Уже третий год я разрабатываю компоненты $mol, и веду разработки на их основе, где применены те же идеи.

И при чем тут ваш mol$ вообще, если о нем речи и не шло?


За отсутствие сокрытия.

То есть, за нарушение инкапсуляции.


Сокрытие капитально снижает гибкость.

Так если вы хотите предоставить клиенту возможность стилизации вашего компонента — то и дайте ему возможность прокинуть конфиг в нужное место через пропсы, вместо того, чтобы говнокодить.


Благами инкапсуляции можно пользоваться и не закрывая компоненты от расширения — тогда не надо будет их мучительно открывать с форками, обсужениями и прочими замедлителями разработки.

Естественно, если автор библиотеки позаботился о расширении — то никаких проблем и нет, чего тогда обсуждать?

Исчерпывающий конфиг будет сопоставим с css.

Вы сейчас находитесь в плену своих предубеждений. Попробуйте представить мир, где автору библиотеки, чтобы обеспечить расширяемость, не надо вываливать наружу конфиг из 100500 параметров, хитро влияющих друг на друга, и которые хоть и покрывают 80% кастомизаций, но которых не хватает для удовлетворения всех требований 80% приложений.
не надо вываливать наружу конфиг из 100500 параметров,

Зачем? Десяток параметров покроет чуть менее чем 100% кейзов.

Приведите же эти 10 параметров для, например, календарика.

несколько цветов темы, размеры, тип календарика, наличие тех или иных саб-контролов. с-но, для календарика даже десятка не набарется.

Что такое «тип»? Как добавить скругления кнопочкам? Как праздничные дни выделить пурпурным? Как выбор года переместить вниз? Как стрелки «вправо-влево» для месяца сделать «вверх-вниз»? Как привязать всплывающее окно к дням? Как изменить начало недели? Как убрать выходные дни? Как выделить диапазон дней? Как вывести текст между тулбаром и днями? Как изменить названия дней недели? И ещё 100500 этих «как». В результате получается монстр типа fullcalendar.io который имеет 100500 параметров конфига, весит как самолёт, тормозит, но 80% хотелок дизайнера обеспечить не в состоянии.
Что такое «тип»? Как добавить скругления кнопочкам? Как праздничные дни выделить пурпурным? Как выбор года переместить вниз? Как стрелки «вправо-влево» для месяца сделать «вверх-вниз»? Как привязать всплывающее окно к дням? Как изменить начало недели? Как убрать выходные дни? Как выделить диапазон дней? Как вывести текст между тулбаром и днями? Как изменить названия дней недели?

У вас половина вопросов к внешнему виду вообще никак не относятся и цссом не решаются.

1. Все относятся.
2. Кастомизация бывает не только стилевая.
> Всё, что видит пользователь — публично по определению.

Нет не всё. Вернее не всё из того, что видит пользователь входит в публичный контракт стороннего компонента. Банальный список поддерживаемых компонентом бразеров, который немного уже чем для вашего приложения, например вообще не включает IE. А вам последний IE нужен, и вы переопределили у себя один класс, который нашли в инспекторе и он так же выглядит и ведёт себя в последнем IE как и в поддерживаемых. Потом вышел патч апдейт у вас всё сломалось, потому что авторы в процессе фикса какого-то мелкого бага в поддерживаемых браузерах перенесли этот класс уровнем выше или ниже, на соседа или вообще убрали. И у вас всё сломалось даже в поддерживаемых — убираете свой класс — в поддерживаемых всё нормально, в IE сломано. И кто, по вашему, виноват, что у вас сломалось при патч-апдейте сначала везде, а потом только в IE?
Абсолютно всё, что видит пользователь является публичным контрактом. По определению. Вы не сможете ничего поменять в визуализации компонента так, чтобы визуализация приложения не изменилась.

Далее у вас идёт вымученный пример, основанный на том, что классы расставляются как попало, а потом на них через каскад навешиваются стили, что весьма хрупко. Однако присмотритесь к моим примерам. Там нет каскада. Там автоматически генерируемые на основе семантики элементов классы, расширяющие идею БЭМ. Эти классы не меняются при изменениях в вёрстке или стилях.
Я ничего не говорил про изменение визуализации. Вернее, в поддерживаемых браузерах визуализация и(или) поведение меняются, когда текущие признаны багом, не соответствуют документации.

И пример не вымученный, если в документации компонента вообще ничего не сказано про кастомизацию через определение стилей, то вы не должны рассчитывать, что она вообще будет работать после патч-апдейта, даже если вам это адалось до него.
Вот именно, что вы по привычке подразумеваете под публичным интерфейсом лишь JS API, на что я заметил, что публичный интерфейс визуального компонента — это далеко не только JS API. И любые изменения в стилях и вёрстке являются изменением публичного интерфейса. Иначе они были бы попросту бессмысленными.

Такие вещи говорятся в документации фреймворка — как кастомизировать компоненты на его основе. Если в вашем фреймворке не продуман этот вопрос — ну вот такой фреймворк вы выбрали, не рассчитанный на активное переиспользование кода от разных разработчиков.
Такие вещи говорятся в документации фреймворка — как кастомизировать компоненты на его основе.

Вот именно. И если в документации написана фига — значит, имена классов в публичный интерфейс не входят.

Разумеется. Давайте я вам напомню о чём наша дискуссия: https://habr.com/post/422537/#comment_19087403


Озвучена проблема. Современные фреймворки эту проблему не решают. БЭМ эту проблему решить может, если его интегрировать во фреймворк. Приведён пример фреймворка будущего — $mol, где с помощью БЭМ-а эта проблема решена. О чём тут можно спорить? Что попытка извне навеситься на scoped стили либо невозможна, либо порождает очень хрупкие селекторы — очевидно. Мой тезис в том, что развивать инструментарий надо в сторону неймспейсов и гибкости в решении задач, а не в сторону изоляции и костылей с кастомизацией. А кастомизация сторонних компонент — наитипичнейшая задача.

> Вот именно, что вы по привычке подразумеваете под публичным интерфейсом лишь JS API

Нет, не я, а вы упомянули про него в «из квадратной стала круглой без изменения JS API — дизайн будет сломан». Для меня контракт компонента более широкое понятие чем его JS API.

> И любые изменения в стилях и вёрстке являются изменением публичного интерфейса. Иначе они были бы попросту бессмысленными.

Нет. Если стили, разметка и вёрстка в целом не являются частью публичного контракта (читай — не документированы), то разработчики вправе их менять как деталь реализации в каждом патч-релизе. Ну это как приватные свойства и методы в ООП — от их, например, переименования ничего не должно ломаться.
От того, что публичный контракт не документирован, он не становится менее публичным и менее контрактом. Собственно сам вид компонента на демо-страничке или в виде скриншота уже является «документацией его визуализации».
Вид, да, в целом публичный контракт по умолчанию для визуальных компонентов. Используемые внутри стили, классы, разметка — нет. Это детали реализации, если авторы компонента явно не объявляют их как предназначенные для внешней кастомизации.
Если проверять «не сломалось» ли после апдейта, можно уходить из разработки.
И правда, зачем проверять. Если что пользователи обязательно напишут багрепорт.
Имелось ввиду что это поломки чекаются на этапе тестирования и не допускаются в продакшн.
Но написали вы там ровно противоположное.
UFO just landed and posted this here
А с какого перепугу дизайнер хочет градиентик на какой-то конкретной сторонней кнопочке?

Которая показывается в нашем приложении, вся визуализация которого находится в зоне ответственности дизайнера.


можно договорится обновить гайды, и изменения внесут в этот компонент

Расскажите ка Гуглу про ваши гайды. Поделитесь потом впечатлениями.

UFO just landed and posted this here
А если дизайнер не в курсе, что кнопочка сторонняя? Ну на предыдущей версии дизайна нарисовал кнопочку сам, разработчики увидели, что она 1-в-1 как в каком-то бустрапе по умолчанию или легко преврщается в неё штатной бустраповской кастомизацией. А потом дизайнер её немного изменил в новой версии дизайна, а бустрап почему-то нет. И вроде ещё можно кастомизировать, но уже не штатным способом. Вставили костыль. А потом бустрап обновился и уже тот нештатный способ не работает.
UFO just landed and posted this here
UFO just landed and posted this here
Дело не в проблемах коммуникации, просто сначала сторонний компонент стал «деталью реализации» о которой дизайнеру знать не нужно, а после небольшого изменения дизайна оказывается, что или костыль лепить нужно, или делать своё решение с нуля.
UFO just landed and posted this here
Что спрашивать? «Ты из бутстрапа скопипастил?» Ну сказал он «нет». Это что-то меняет?
UFO just landed and posted this here
А почему он не должен был его брать?

Не правильно. Хорошие компоненты должны уметь подмерживать стили пришедшие свыше. В БЭМ это называется миксом.
А если ваш сторонний компонент не умеет этого то штош… кроме хаков нет никакого способа кастомизировать.

CSS? Устарел?
Ок, критикуя — предлагай.

Предложите решение.
UFO just landed and posted this here

Каскад это когда стили написанные выше перетираются теми которые написанны ниже

Просмотрел комментарии, раз здесь столько специалистов по БЭМ — воспользуюсь случаем и задам вопрос :)


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


Собственно вопрос: как БЭМ, как методология относится к использованию всей этой мощи? Несколько моих попыток изучения БЭМ не дали однозначного ответа на этот вопрос, так что помощь более опытных специалистов была бы очень кстати, благо судя по комментариям — многие здесь неплохо разбираются в вопросе.

Вцелом ничего не мешает использованию так х штук как .you-class[attribute] + ~ > ::before ::after
В рамках своего блока вы можете делать всё что хотите, хоть атомик-цсс зашкваривайте на основе модификаторов. Важно не влиять на какие-то теги без классов или на не-свои блоки/элементы.
Главное — целесообразность всего этого)
Можете рассказать с какими особыми случаями вам приходилось сталкиваться?

Спасибо за комментарий. Примеров использования всяких сложных селекторов у меня на самом деле немало в разных проектах. Не факт, конечно, что все они функционально необходимы, но всякое бывает.


К примеру не раз сталкивался с задачей когда необходимо обеспечить отображение только полностью заполненных рядов элементов (галерея какая-нибудь, заказчик хочет чтобы было красиво). Разумеется с учётом responsive, когда количество элементов в строке может меняться — это решается скрытием части элементов. На CSS реализуется с использованием техники, описанной, например в этой статье, но в итоге там получаются селекторы вида (в SCSS) #{$selector}:first-child:nth-last-child(#{$in-html}) ~ #{$selector}:nth-last-child(#{$n}).


Ещё пример: в текущем проекте есть галерея у которой требуется различное поведение в зависимости от количества элементов в ней — где-то выводить thumbnails, где-то нет, что-то скрывать, да ещё и количество скрытых элементов показывать. Решается на чистом CSS, но в итоге там местами встречаются селекторы вида .gallery-image:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3)):not(:nth-child(4)). Конечно в SCSS всё это намного компактнее и выглядит существенно проще, но результирующий код именно такой.


Также, раз уж есть возможность, хотел бы задать ещё один интересующий меня вопрос относительно БЭМ: на практике очень часто встречаются ситуации когда внешний вид и поведение блоков зависит от некоторого внешнего состояния (обычно описываемого через дополнительные классы в body). Банальный пример — темы. Да, я знаю что предлагается использовать модификаторы вида --theme-name, но если тема меняется динамически — придётся прописывать этот модификатор всем элементам в DOM дереве и не факт что он везде нужен. Или я неправ? Другой пример навскидку приходящий в голову: открытие модального окна или меню когда необходимо "заморозить" body который явно не является блоком. Как БЭМ предлагает работать с этими ситуациями?

UFO just landed and posted this here
но если тема меняется динамически — придётся прописывать этот модификатор всем элементам в DOM дереве и не факт что он везде нужен

Не всем элементам, а только блокам у которых есть модификатор темы(то есть там где предусмотрена темизация).


На вашей странице есть блоки. Элемент <body> это обычный блок не отличающийся ничем от остальных. Я привык называть данный блок page
У этого блока могут быть элементы например: page__head или page__footer.


Чтобы применить тему к блоку page мы можем добавить к нему модификатор_темы page_theme.


На практике каждый отдельный блок должен уметь в свой отдельный модификатор темы, если это необходимо.
Например для стилизации блока header нужно добавить header_theme, для стилизации main -> main_theme и тд


В реальных проектах для унификации тем используются переменные препроцессоров, из которых каждый модификатор темы берёт себе значения.


Вот небольшой пример на скорую руку: http://jsbin.com/gowonob/edit?css,js,output (кликните там на кнопку)
Здесь я к блоку page добавляю модификатор page_theme и таким образом влияю на элементы этого блока

встречаются селекторы вида .gallery-image:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3)):not(:nth-child(4)). Конечно в SCSS всё это намного компактнее и выглядит существенно проще, но результирующий код именно такой.

в в бэм же не много правил )
Не вижу проблем в использовании :not(:nth-child(1)) и подобных штук. Главное чтобы они влияли на нужные вещи внутри этого блока.


Программирование это управление сложностью ) не проще ли эти задачи решать при помощи например js ?


Если у вас есть больше вопросов про бэм, то приходите в телеграм bem_ru. либо сюда css_ru

Не вижу проблем в использовании :not(:nth-child(1)) и подобных штук.

А я вижу. Прикручивание виртуального скролла ломает такие стили.

Использование БЭМ не противоречит применению каскада в каких-то конкретных местах. Он больше о том, что необходимо изолировать именно разные блоки друг от друга.

Я не знаю что такое БЭМ. Я нормальный?
Индустрия ходит кругами. Сначала придумывается конечный автомат, потом для него делается простенький язык, потом делается выразительный язык, потом в язык добавляются функции и модули, потом язык делается функциональным или объектно-ориентированым, потом на нем пишут конечный автомат, потом для этого автомата делается простенький язык, потом выразительный…

Индустрия ходит кругами. Сначала придумывают как передать бит информации, потом делают протокол для передачи потока битов, потом канал делают двунаправленым, потом на базе двунаправленного канала строят протокол который позволяет передать бит информации…

Индустрия ходит кругами. Сначала придумывают как отобразить информацию для пользователя. Создают библиотеки. Потом создают язык, с помощью которого можно декларативно описывать пользовательский интерфейс. Потом для этого языка придумывают библиотеки, для них придумывают свой язык.

Индустрия ходит кругами…

Первый, второй пункт про удлиннение имён классов
В третьем пункте автор не понял что такое семантическое наименование
В четвёртом пункте автор не наступал ещё на грабли перебивания специфичности.
В пятом пункте автор продолжает показывать своё невежество, и неумение в крупные поректы вертающиеся независимыми блоками.

Знал бы я, что за такие статьи сейчас раздают инвайты… Хотя мне бы было стыдно такое писать в качестве первой публикации. Получился субъективный взгляд разработчика который не разберается, зачем нужен БЭМ и как с ним работать правильно, что бы таких притензий не возникало.
можно еще было запостить статью на тему «что лучше ios или андроид?»
БЭМ сам по себе вряд ли «стоит инвайта».
BEM — это неплохая методология, но и у нее есть недостатки.

Самый основной из них — это длинные и плохо читаемые названия классов. Нет, если у разработчика все взаимодействие с кодом ограничивается только версткой, то у него все хорошо. Есть SCSS, есть Pug, которые скрывают это все безобразие.

Но как только речь заходит об интеграции верстки начинаются проблемы. Нет, я допускаю, что существуют индивидуумы, которые не видят ничего плохого в списке классов вроде: «link n-popular-recipes-list__item-link b-zone b-spy-events i-bem link_js_inited link_hovered_yes», но давайте будем честны: работать с этим неудобно.

Решение заключается в совмещении концепции независимых блоков с каскадной природой CSS. Для уменьшения конфликтов можно использовать суффиксы для классов блоков (.posts_box, .articles_box, например), а также следить за их вложенностью. Да, это более «хрупкий» подход, но зато с версткой потом кто-то сможет комфортно работать.
Можно классы в несколько строк указывать:

<button class="
	b-zone 
	b-spy-events 
	i-bem 
	link 
	link_js_inited 
	link_hovered_yes
	n-popular-recipes-list__item-link 
"></button
И теперь представьте, что таких тегов будет несколько десятков. А ведь помимо названий классов в коде шаблона может быть логика, могут быть скрипты.

В итоге код шаблона станет просто нечитабельным и неподдерживаемым.
Если из БЭМ использовать только классы, то да, они могут всё усложнить в некоторых случаях.
Но даже на jquery есть библиотека для работы с DOM в БЭМ-терминах — github.com/zenwalker/jquery-bem

Зашквар какой-то ))) вы простите но такой набор классов на одном элементе это скорее антипаттерн чем поддерживаемая вёрстка.

Подозреваю, что то что вы называете каскадом на самом деле называется дочерним селектором, и он не запрещается в бэм, но рекомендуется не злоупотреблять.


Не совсем понял что имеется в виду под решением проблемы). В бэм не так много проблем чтобы их нужно было

Подозреваю, что то, что вы называете «дочерним селектором», на самом деле называется «контекстным» или «вложенным селектором».
Ср.
.wrapper > .btn
.wrapper .btn
Если BEM настолько неудобен, то почему он популярен в СНГ? И какая по вашему мнению методология лучше BEM?
Потому что эту методологию активно продвигает Яндекс.

BEM удобен в больших командах, где есть несколько не очень опытных верстальщиков и требуется чтобы они могли хоть как-то вместе работать. Естественно, что вопрос насколько удобно с этой версткой работать в дальнейшем здесь не стоит.
где есть несколько не очень опытных верстальщиков

несколько опытных верстальщиков тоже в конечном счете выработают какую-то конвенцию именования. Иногда это может оказаться БЭМ.

Вы так говорите будто бы в бэм есть только нэйминг классов и никаких других проблем бэм не решает. И будто бы в этом есть какая-то проблема.

Для большинства людей (в том числе и автора этой статьи) БЭМ относится исключительно к именам классов.

Есть и другие трактовки, но мы же в контексте этой статьи говорим.

БЭМ помогает организовать процессы разработки.


Представьте что у вас 10 разработчиков, и крупный проект. Как объяснить им что хорошо, а что не очень. Что сделать чтобы проект не пришлось переписывать с нуля через год потому-что новые разработчики скрипят зубами и сроками при реализации фитч/исправлений, а старые разработчики давно уволились ?)

Это вы про другой БЭМ говорите (который про организацию проекта в целом, файловую структуру и т.д.) В нем действительно выстраивается структура проекта целиком (и JS, и CSS, и все остальное).

А статья исключительно про имена CSS-классов.

Да я уже понял, что у большинства тут подход "не читал но осуждаю" )

И всё же я сейчас не затрагиваю серверный бэм. Я говорю исключительно про методологию вёрстки

Грубо говоря БЭМ решение проблему текучки кадров.
Если в эту сторону копать, то не решение проблемы текучки кадров, а способ не делать из текучки кадров проблему :)
Да, такая формулировка точнее )
Все вышеперечисленные минусы я решаю миксованием двух подходов:
1) BEM
2) Atomic css или утилитарные глобальные классы

Если модификатор компонента соответствует какому-то обще/часто-используемому стилю / набору стилей — используем утилитарные классы (.color-primary, .bg-primary, etc..).
Если модификатор компонента описывает различную логику или логику которая распространяется на множество его потомков (полномасштабный компонент с дочерними элементами, например — темы для меню) — использую BEM. Модификаторы пишу через — (.c-nav--primary);

Bem решает проблему конфликта имён, если один из вложенных в Ваш компонент классов уже где-то задан глобально, каким-нибудь плагином, который придерживается другой технологии описания стилей. В вашем случае помимо обычных стилей Вам придётся писать стили обнуляющие стили вендора, что часто представляет из себя рутинную и непростую задачу. Ну и главное — вы не застрахованы от того, что подключив в дальнейшем в общий билд какой-нибудь плагин Вы не получите конфликты имён обще-распространённых классов.
В моих проектах я использую идею atomic.css или других (не знаю как они называются) — ставлю у компонента с логикой общей направленности префикс с-${componentName} (.c-btn, .c-header-section, .c-nav, .c-menu, ..etc)

Ещё, для того чтобы не создавать модификацию компонента который имеет иное поведение находясь в каком-нибудь блоке, я лишь в 50% случаях создаю модификацию самого компонента. Почему? стили компонента, которые переопределяют его поведение в блоке Х должны существовать ровно столько, пока существует блок Х. Удалили секцию, а стили внутри компонента относящиеся к модификации (по пространству имён) остались (подтирать не все любят, не все помнят). В 50% случаев я задаю стили компоненту от родителя, когда повторное использование данной модификации крайне сомнительно. Для страховки, если нужно изменить поведение компонента в определенной секции я создаю утилитарный класс у самой секции (.has-${componentName}), и в стилях пишу от этого класса по нисходящей. Теперь этот класс можно добавить всем секциям, в которых нужно иное поведение нашего компонента, без привязки к секции, и не задавая модификаций внутри самого компонента, привязываясь к контексту текущего проекта.
Как-то так.
Такой подход вообще дичь, простите:
1. БЭМ это про копипасту из проекта в проект.
2. Atomic это про утилитарность.

Одно второму противоречит. Чтобы переиспользовать ваш компонент мне нужно выковыривать из вашего css все классы. Например .flex-sb-top который флекс-контейнер, space-between и align-top.

То что вы используете очень удобно для single-dev проектов. Но с БЭМ Atomic дружит никак.
Насчёт single-dev проектов, это в точку!
Но.
Посмотрите на тот же bootstrap.
Никаким там бэмом и не пахнет, однако вложенные элементы часто носят в названии имя родительского блока, типа .form-control, .form-group и тд, только вот использовать их можно легко как утилиту с миксованием классов у родителя.
Что касается гибкости использования — тут сложно, согласен, вместо того чтобы гуглить по доке бутстрапа как у них там устроен тот или иной интерфейс конкретного компонента, проще ведь написать свой, но речь шла о миксовании подходов, которые нивелируют псевдо-минусы бема, описанные топикстартером. Я так работаю уже достаточно кол-во времени, и не вижу смысла нагружать себя теми проблемами, которые приносит с собою использование бэм для мега-проектов. Автор явно не из тех, который опробовал предложенный мною микс и остался при своём мнении. Насчёт копипаста из проекта в проект, возьмите тот же bootstrap — у него есть понятие «утилиты» — что мешает вам в рамках своей сборке запилить помимо компонентов ещё и утилиты которые будут выполнять узкий набор задач и решать типичные задачи у бэм компонентов? У меня например в проекте такими утилитами являются утилиты размера шрифтов, цветов фона и текста, отступов, дисплей-утилиты, и т.д. Это лишает меня потребности в создании абстрактного класса у которого единственная цель — задание цвета тексту или размера шрифта типовому заголовку.
А что касается переиспользования — никто Вам не запрещает написать мини-документацию к своей сборке с перечнем всех утилит, и расширять её из проект в проект.
UFO just landed and posted this here
Миксины требуют создание модификаторов, в которых они бы использовались. И так для каждого конкретного компонента. Это раздувает css.
Утилитарные классы же раздувают html, однако позволяют легко конструировать кастомные интерфейсы путём миксования классов, не только фронтовиком, но и бекендером.
Но тут, как говорится, на вкус и цвет. Всё зависит от проекта.
Когда, как я, верстаешь по большей части лендосы, от бэма никакого толку особо, отсилы 1-2 секции на ленде могут повторяться но иметь чуть другой вид.
А вот для single-dev разработки из проекта в проект, при учёте что в команде один и тот же дизайнер, который рисует интерфейсы из ранних наработок, добавляя им иные вариации — вот тут мой подход кажется аргументированным. А когда, иногда, дают верстать многостраничники с «похожими» компонентами, которых различают ну просто нереально кастомными отступами (как вариант), то не использовать утилитарные классы отступов и лепить для каждой вариации свой класс (причём ещё надо немало подумать, как же мы его назовём, привязывать ли название к контексту, без опасения что точно такие же отступы будут у секции с другим контекстом) — как минимум неразумно.
ИМХО.
UFO just landed and posted this here
Давай к конкретике?
У меня мультилендинг предположим.
В среднем у каждой второй секции отступы сверху и снизу по 70 пкс (60пкс на планшетах, 50 пкс на мобилках). У таких секций есть заголовок размер шрифта которого соответствует второго уровня заголовку (исходя из градаций разновидностей размеров в дизайне в целом) — 40пкс (32 пкс на планшетах, 25пкс на мобилках).

Ваши действия?
Опишите в рамках конкретной тестовой секции куда вы запихнёте отступы, куда запихнете размеры заголовка.
Затем отпишу я.
Пойдем дальше в нашем безумстве! Gulp плагин который в html берет все atomic классы элемента, группирует их css стили в один хэш-класс. В html соответственно заменяются тоже на хэш. Знай только классы в html пиши в одном порядке чтобы совпадало.
Но это ж убъёт утилитарность.

Вместо этого есть вот такое — acss.io/guides/atomizer.html
эта штука сканирует проект и генерирует цсс-файл только с используемыми классами
если мне нужно будет взять одну кнопочку из вашего проекта и перенести её к себе я должен буду взять 300кб вашего атомикцсс и файл со стилями кнопочки меньше 1кб?
Кнопка от атомарных классов никак не зависит. Атомарные классы для того и созданы чтобы не быть привязанным к контексту применения в отличии от модификаторов.
Кнопка это маленький компонент с достаточно объёмным размахов в кол-ве вариаций, поэтому у неё модификаторов может быть достаточно много.
Времени вы потратите на интеграцию моего компонента кнопки не более чем 5 минут, при этом это время вы потратите максимум на проверку наличия миксинов, которые присутствуют в хелперах кнопки, и которые отсутствуют в Вашей сборке.
И это я не считаю проблемой, потому что если уж так и считать, то использовать препроцессоры — беда!
В каждом большом темплейте есть мелкие элементы, как кнопки, дропдауны, тайтлы, субтайтлы, секции и т.д. Но в БЭМе у вас их нету, так как любой элемент без блока использовать тоже запрещено.

А где написано, что кнопка не может быть блоком?


<div class="button button--primary>
    <span class="button__text">Кнопка</span>
    <i class="button__icon"></i>
</div>

Тут я вижу обратное.


Можно создать любой блок, хочешь ссылку, пожалуйста:


.link {
    text-decoration: none;
}

.link--external {
    color: red;
}

Все есть в документации — https://ru.bem.info/methodology/key-concepts/#%D0%9C%D0%B8%D0%BA%D1%81


Не обязательно использовать длиннющие модификаторы для каждого отдельного блока, БЭМ же не запрещает это.


Когда нужно сделать инверсию у блока, почему-то многие создают дохера модификаторов для элементов блока, когда можно навесить один модификатор блоку. (из-за этого верстка в итоге становится нечитабельной, а потом все говорят, что БЭМ — говно)


Все в документации описано.

гхм… на всякий, нада сематики придерживаться. Т.е вместо span
Но это не отменяет того, что возникает путаница. Потому что нет чётких правил. А с миксами и того больше. Создатели БЭМа обещают, что будет удобно создавать повторно используемые компоненты, но на практике получается, что пока их очистишь от миксов голова начинает болеть.
UFO just landed and posted this here
В данном конкретном случае по логике «button» это элемент, но по БЭМу выходит, что блок.

А если вы, например, захотите создать класс ".text-danger" и использовать его везде, где нужен определенный цвет текста, то это будет не модификатор, как говорит нам логика, а блок или микс, потому что (цитата) «модификатор не может использоваться в отрыве от модифицируемого блока или элемента». Поправьте, если я не прав.
UFO just landed and posted this here
> Суть в том, что «глобальные» модификаторы, как text-danger, нарушают инкапсуляцию.

Это как посмотреть. Если рассматривать аналогию с ЯП, то класс ".text-danger" можно сравнить со статическим методом или константой. А когда мы пишем стиль для тега «button», это уже похоже на глобальную переменную. Странно когда в SASS может быть переменная "$text-error", а в CSS такого класса быть не может. Где логика?

UFO just landed and posted this here
В случае глобальных классов-модификаторов может получиться такая конструкция

В нормальной верстке такой конструкции получиться не может. Как я уже писал выше, из всего этого получается, что БЭМ это для тех кому пофигу что получается на выходе, главное чтобы быстро. Херак-херак и в продакшен.
В нормальной верстке такой конструкции получиться не может.

Приведите пример нормальной верстки, в которой такой конструкции не будет? А то тут все, кто против БЭМа, не могут привести адекватных контраргументов.

В данном примере я вижу только стили с каскадами, а для БЭМ не вижу. Поэтому ничего конкретного возразить не могу. Но согласен, что мой комментарий про «херак-херак» здесь не уместен. Невнимательно прочитал.
Смотрим примеры плохого CSS, которые приведены в документации БЭМа.
Картинка


Если честно, кто-то из верстальщиков стал бы в здравом уме писать такие стили? Зачем они впаривают такую дичь? Маркетинг.
UFO just landed and posted this here
Вот цитата с той странички:
Если понадобится добавить на страницу другой компонент, содержащий пункты, то стили для нового item повлияют на пункты из существующего навигационного меню. Или предположим, что в навигационном меню нужно изменить правила класса .active. По имени непонятно, какие компоненты его используют. Может оказаться, что на другой странице существует...

Автор взял самый плохой пример (хороший я приводил выше — Bootstrap). Что это как не манипуляция?
Автор взял самый плохой пример

Автор взял самый очевидный пример. Чтобы разница между «плохой» и «хорошей» вёрсткой была более очевидна.

Это тоже самое как, если бы я вам сказал, что вам нужен IPhone X, потому что он в 100 раз мощнее Nokia 3310. Не нужно сравнивать продукт с самыми передовыми, будем сравнивать с самыми плохими/устаревшими, чтобы разница была более очевидна.
сделай пуллреквест и исправь эту неточность авторов
Сегодня послушал ребят которые продвигают БЕМ, в какие красноречивые метафоры они оборачивают свои мысли, «ортодоксальный БЕМ», «Либеральные свойства», неприятное впечатление осталось у меня от них.
UFO just landed and posted this here
Частая проблема. Религия не так уж и плоха, если не слушать проповедников.
В каждом большом темплейте есть мелкие элементы, как кнопки, дропдауны, тайтлы, субтайтлы, секции и т.д. Но в БЭМе у вас их нету, так как любой элемент без блока использовать тоже запрещено.

Открою пару секретов:
1) Кнопки практически обязаны быть блоками;
2) То, что может использоваться повторно, надо делать блоком. БЭМ не обязывает все дропдауны делать элементами. Никто не говорит, что у вас не может быть базовых классов .title, .btn и т.д. Наоборот — они должны быть.
> Кнопки практически обязаны быть блоками

плавающие в тексте линки стилизованны под кнопки (обычно с глаголом внутри типа «Register») — стилизованные для поддержки метафоры «а тут вы перейдете из текста, на серьезную форму» — не могут быть блоками.
Да, но ссылки — немного другое, все же.
UFO just landed and posted this here
Хоспаде. Блок в смысле Бэм-блок, а не display: block
UFO just landed and posted this here
Для меня тогда расплывается смысл описания БЭМ-блока как «нечто что не занимается своим позиционированием». для флексов я понимаю что такая стратегия работает вместе с «привычным кодированием» HTML, но… display:inline-block — это тоже позиционирование — и выносить его куда из данного конкретного БЭМ-блока реализующего стилизованную ссылку я не готов. Впрочем это все схоластика. Все с БЭМом нормально, ненормально, что всерьез и долго спорят вокруг одного из возможных code of conduct. Ну как ненормально — наблюдаемое ненормально не более чем любая аллергия.
UFO just landed and posted this here
Исторически CSS смешивает в одном свойстве внутренний layout и внешний. Так что задавая себе layout элемент также задаёт своё позиционирование во внешнем. И «позиционируя» вложенный элемент нужно учитывать его внутренний «layout».
Вот вы такой написали статью, а сам Хабр написан по БЭМу.
Может напишете им пару слов в письме, а то вдруг они не в курсе? ))
Хабр авторитет в деле монеторизации контента, а в деле создания сайтов (и внесения изменений в них), извините, нет. По скорости с которой приходят анонсированные улучшения, а так же по решимости объявлять необязательными все запросы на улучшение UX — однозначно понятно — их процессы тяжелы и затратны.

Вы считаете что у хабра скорость выката фитч зависит от выбранной методологии вёрстки? )))

UFO just landed and posted this here
Нет, я сказал, что хотя ссылка на авторитет — правильный риторический прием — авторитет должен быть всеобщим. «девелоперы хабра» не в авторитете, и да — «из-за скорости выката фич» (спасибо предыдущему ответчику за емкое определение).
Автор, скажите пожалуйста. Если не бэм, ну и ладно.
Какой методологии вы придерживаетесь? или какую посоветуете и почему?
Есть SMACSS, например
Стили: общие, страниц, блоков, элементов и «атомарные» модификаторы к ним

По-сути БЭМ должен быть про переиспользование блоков, а не про превращение классов в id

Articles