Comments 681
BEM'а не должно существоватьа с чего-то что-то типа:
Имея за плечами более чем двадцатилетний опыт разработки…
<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. И тебе не надо заморачиваться по поводу именования. Допустим есть компонента Article
и Comment
. И них есть автор. В двух CSS-ках компонент совершенно спокойно можно использовать класс .author
не боясь, что что-то где-то пересечется
Генерировать эти классы/атрибуты автоматом. Например, из такого шаблона:
<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>
Да нет, тут всё правильно. Название должно обладать семантической точностью. text
— слишком общее, текстов может быть много разных в блоке. И если в next
и prev
должны быть разные стили текста, то и называться они должны соответственно next-text
и prev-text
. А вот если одинаковые, то уже и там и там должно быть item-text
.
В article-rewind__next-text
всё правильно написано. Это элемент next-text
блока article-rewind
.
Это что у вас за элементы элементов? По бэму не может быть такого. Стоит перечитать. И ещё используйте пакет 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 для каждого компонента.
Don’t Mutate the Original Component. Use Composition. — https://reactjs.org/docs/higher-order-components.html
Вот этому совету последовать не получится.
Формально у вас вроде БЭМ, но по существу издевательство. Я бы предложил:
<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>
Теги вложены на много уровней, а элементы блока идут "в один уровень". Это фишка БЭМа, которая все упрощает. В то же время блок является элементом другого блока за счет применения нескольких классов (миксования).
Но вот какая штука — browser-ы писались и пишутся исходя из каскадности стилей. Потому реальных оснований считать, что селекторы с километровыми именами без каскадности работают лучше — нет. А в пользу вашего утверждения даже косвенных аргументов нет.
Но реально заметную на глаз разницу это давало только на очень больших страницах — десятки тысяч узлов. В реальной жизни такие почти не встречаются.
Но некоторая разница всё-таки есть, это факт.
Там смысл был в том, что каскады влияли на скорость reflow.
И если вдруг ваше веб-приложение так устроено, что reflow случается часто (а способов его вызвать довольно много) — это могло вылиться в ощутимые подлагивания.
JFYI класс article__heading_level_1_active
не по БЭМ.
Препроцессоры наоборот помогают использовать БЭМ. Можно же писать примерно так:
Вопрос в том — зачем?
Так наоборот же — очень неудобно.
Вот и вопрос — ради чего жертвовать удобством?
Почти так же удобно как простым каскадом, но получаете плюсы БЭМ.
Так мы как раз и начали с того, чтобы выяснить плюсы. То есть минусы очевидны — лишняя писанина, что делает использование БЭМа неудобным.
А что их плюсов? Вроде как снимается проблема изоляции стилей, но если использовать современные фреймворки/shadow dom, которые эту изоляцию в адекватном виде предоставляют, то это становится ненужным, разве не так?
но если использовать современные фреймворки/shadow do
И городить костыли и велосипеды для того, чтобы это работало одинаково везде. Уж проще принять соглашения по именованию классов)
Плюсы от бема описаны на bem.info и это не про изоляцию стилей. Это и упрощение поддержки/рефакторинга и правила позиционирования, и правило применения одинаковых свойств большому количеству элементов. Просто откройте и почитайте bem.info про цсс, там не много
Это и упрощение поддержки/рефакторинга и правила позиционирования, и правило применения одинаковых свойств большому количеству элементов.
Это все про обычный цсс, а не про бэм. Зачем нцжен цсс понятно, мы же тут конкретно бэм обсуждаем, какие задачи бэм решает.
Нет, это как раз про бэм. Вы не разобрались просто.
В бэме не много правил но все они прлезны. И это не только про изоляцию стилей, поэтому я недоумеваю когда говорят что с приходом цсс-ин-жс или цсс-модулей, бем стал ненужен. Как раз наоборот он стал актуален как никогда, так как стало больше поводов наговнокодить в стилях.
БЭМ это про самодокументируемость, поддерживаемость, внешнюю геометрию и позиционирование, про стилизацию групп блоков, упрощение рефакторинга кода, и другое.
С бемом все разработчики кодят как один при этом не превращая проект в хрупкий кусок говна, взрывающийся от любого прикосновения. При этом на новой работе не придётся привыкать к неким новым правилам кодирования цсса
Без бем все разроботчики договариваются о своём неком стиле кодирования, при этом на каждой новой работе_без_бэма правила разные — это удлинняет процесс адаптации новых сотрудников.
Нет, это как раз про бэм.
Погодите, еще раз. В цсс все это есть, что к этому добавляет бэм, если оно уже есть, без бэма?
В цсс все это есть
А можете привести конкретный пример того, как описанное выше в комментарии достигается с помощью «обычного» CSS, без всякого БЭМа и т.д. Сейчас складывается впечатление, что вы потралливаете. Причём второй комментарий подряд)
А можете привести конкретный пример того
Ну давайте тогда с конкретным примером, по поводу чего надо привести пример, чтобы не было ненастоящих ирландцев ;)
Типа: "вот так оно в БЭМ: ..., это решает задачу Х за счет Y, как в данном случае решить Х без БЭМа?".
Задачи унификации и коммуникации. Как в этих задачах помогает БЭМ?
Ну вот беру я условный ангуляр, там есть те же по смыслу термины, при этом их семантика еще и форсируется на уровне самого фреймворка (например, изоляция стилей гарантирует, что внутри "блока" можно управлять только стилями "элементов" и внутренними стилями самого блока, без плясок с именованием и самоограничений).
Зачем БЭМ? Он в данном случае будем выступать как ненужная дублирующая концепция, разве нет?
С таким же успехом можно спросить зачем в ангуляре сделали изоляцию стилей, если уже есть БЭМ?
Потому что в ангуляре изоляция работает на уровне фреймворка без дополнительный усилий со стороны программиста. Просто работает.
БЭМ прежде всего для «голой» вёрстки, без ангуляров и реактов.
Ну то есть при использовании полноценных фреймворков БЭМ не нужен. Это просто костыль. Так?
Не путайте «не нужен» и «появляется альтернатива». Грубо, без ангуляра у вас две альтернативы: спаггети и БЭМ, а с ангуляром три: спагетти, БЭМ и средства ангуляра.
Нет, она требует дополнительных усилий.
Эм, нет. Фреймворк все делает сам.
спаггети и БЭМ, а с ангуляром три: спагетти, БЭМ и средства ангуляра.
Но зачем использовать БЭМ, если есть некостыльные методы, которые делают то же самое, но лучше и без дополнительных телодвижений?
Изоляция стилей во фреймворках — тоже костыль для обхода недостатков CSS, просто другой подход к проблеме изоляции стилей.
Сам он не делает, нужно соблюдать правила фреймворка чтобы изолировать стили.
Но это не требует каких-то дополнительных усилий, вот в чем суть. Использование БЭМ — требует.
Чтобы соблюдать какие-то правила написания CSS кроме стандартных всегда нужно прилагать дополнительные усилия. А прилагать их для соблюдения правил БЭМ или фреймворка — вопрос выбора.
Конечно нет, ведь есть еще вопрос количества усилий. В случае фреймворка — они практически нулевые, примерно на том уровне, когда их и вовсе нет. В случае БЭМ — они выше на порядок.
С-но, ведь тот же ангуляр при изоляции стилей, по сути, делает ровно то же самое, что в делается в БЭМе, только автоматически. В БЭМе это надо делать руками.
Ну никак иначе фреймворк не догадается какой файл стилей с каким компонентом связан.
Зависит от архитектуры. В MAM архитектуре, сборщик вполне понимает, что эта группа файлов относится к одному модулю. Другое дело, что проблема конфликтов имён куда лучше решается семантическими неймспейсами, чем изоляцией.
Он не делает этого автоматически, чтобы он сделал нужно как-то указывать какой компонент с каким CSS файлом связан.
Естественно, мысли фреймворк не читает. Вы говорите, ему, какие стили как изолированы, и он автоматически обеспечивает эту изоляцию. Именно про автоматическое обеспечение изоляции речь и идет. В случае БЭМ вы это делаете руками.
В случае БЭМ — они выше на порядок.
Если фреймворк по настоящему умеет в БЭМ, то наоборот ниже на порядок, так как не надо прокидывать классы — они генерятся автоматически исходя из дерева компонент и их семантики. При этом не усложняя кастомизацию и понимание отрендеренного дома, в отличие от различных форм изоляции.
Если фреймворк по настоящему умеет в БЭМ, то наоборот ниже на порядок
Ну, с-но, как тот же ангуляр, там ведь изоляция де-факто по БЭМу и работает. Вот, с-но, и вопрос — зачем руками делать параллельный БЭМ, если фреймворк делает тот же БЭМ под капотом автоматически. Ненужно, выходит.
Ангуляр не делает БЭМ, он делает изоляцию.
Семантически, он делает ровно то же самое, что и бэм.
А потом программист с этой изоляцией героически борется.
Зачем?
Семантически, он делает ровно то же самое, что и бэм.
БЭМ даёт каждой сущности уникальное имя, по которому понятно что она из себя представляет и кому принадлежит.
Изоляция позволяет разным сущностям давать одинаковые имена, если они объявляются в разных местах, а потом без конца путаться между этими именами.
Где вы тут увидели "ровно то же самое"? Особенно семантически.
Зачем?
Кастомизация компонента под контекст использования, например.
БЭМ даёт каждой сущности уникальное имя, по которому понятно что она из себя представляет и кому принадлежит.
И изоляция так же реализована.
Где вы тут увидели "ровно то же самое"? Особенно семантически.
Ну как где? И там и там добавляются "лишние" селекторы для возможности различить конкретное место применения стилей.
Кастомизация компонента под контекст использования
Эту возможность должен предоставлять сам компонент.
И изоляция так же реализована.
Ага, только эти нагенеренные имена понятны исключительно машине, но не человеку. И дают контекст лишь первого уровня. Примеры разных уровней на человеческом языке / в машиночитаемом бэм-виде (pin — сторонняя библиотека, ya_mail — конечное приложение) / "изолированном" виде :
- Кнопка /
pin_button
/wsri_button
- Кнопка очистки инпута /
pin_input_clear
/wqrl_clear
- Кнопка очистки поискового поля /
pin_search_clear
/wqrl_clear
где-то внутриwprl_search
- Кнопка очистки поиска по списку пользователей /
ya_mail_users_filter_clear
/wqrl_clear
где-то внутриwprl_search
где-то внутриvprl_users
- Кнопка очистки поиска по списку пользователей в выпадающем меню выбора адресата /
ya_mail_recepient_popup_filter_clear
/wqrl_clear
где-то внутриwprl_search
где-то внутриvprl_users
где-то внутриvqri_recepient
Эту возможность должен предоставлять сам компонент.
А программист должен писать без багов, а компьютеры не должны ломаться, а мир должен быть без войн. Выпьем же за идеальные сферические компоненты в вакууме, предоставляющие богатые возможности по любой кастомизации и поддержка которых не требует команды из 10 человек на постоянной основе.
Ага, только эти нагенеренные имена понятны исключительно машине, но не человеку.
А зачем их человеку понимать? В том-то и дело, что при наличии изоляции вам вообще не нужно смотреть на эти имена. Они не несут никакой информации, которую вы могли бы использовать. И не важно, нагенерены они рандомно или не рандомно.
Именно в этом смысл изоляции.
Было бы удобно, чтобы инспектор вообще их не выводил, и в этом плане как раз нагенеренные имена удобнее, т.к. сразу понятно что их надо игнорировать и они никакой информации не несут и ни на что не влияют. С другой стороны, если вы видите какое-то осознанное именование — в этом уже нельзя быть уверенным, что усложняет разбор стилей. То есть с рандомными идентификаторами стили смотреть проще.
Чтобы понимать что где откуда зачем и почему в незнакомом вам приложении.
Именно так, даже в незнакомом. Изоляция гарантирует что у вас сразу есть вся необходимая информация для понимания. Вам не надо чего-то искать, разбирать имя класса и т.п. вещи.
Какой компонент править, чтобы добавить стили в h1 а для каунетра уровнем выше?
Не совсем понял вопрос, стили можно добавить большим количеством способов, мы вароде говорили о том, чтобы определить каким именно добавлен, но для этого надо видеть селектор, очевидно. Дефолтно, если надо стиль для h1 — это элемент внутри counter, если для counter — это либо my-appz, если селектор на ngcontent, либо :host в самом counter, если селектор на nghost.
Сколько вы потратили времени на выяснение?
Секунд 5.
Как думаете, как это время зависит от размера и сложности приложения (константно/логарифмически/линейно/экспоненциально)?
Практически — константа, т.к. от сложности и размера приложения тут мало что вообще зависит, зависит от определенных особенной структуры дома. С-но, вы вполне намеренно вместо типичного кейза сделали более сложный. По сути, сложнее чем в вашем примере, ситуации быть не может (теоретически — можно построить, конечно, но в реальности очень сомнительно, что такой код будет встречаться чаще, чем на уровне стат. погрешности), т.к. counter прокидывается через 2 проекции.
Ну вот если вы попробуете написать переиспользуемый код, то куча проекций у вас будут идти вперемешку и владелец элемента будет находиться где-то вверху по дому, и его придётся выискивать глазами по чудесным именам атрибутов. И если ангуляр достаточно дубовый, в нём переиспользуемые компоненты наворотить сложно, то в реакте подобная динамика очень даже распространена.
Мне же будет достаточно пройтись по атрибутам самого элемента и всё.
Ну вот если вы попробуете написать переиспользуемый код, то куча проекций у вас будут идти вперемешку
Нет, не будет, я же стараюсь писать хороший код. Но даже если будет:
и его придётся выискивать глазами по чудесным именам атрибутов
ctrl+f в инспекторе и поиск первого вхождения атрибута.
Мне же будет достаточно пройтись по атрибутам самого элемента и всё.
Согласен, это формально удобнее (хотя практически на производительность не повлияет никак). Только какое отношение это имеет к цсс? Смысл-то один — фреймворк и там и там позволяет за время порядка секунд найти принадлежность элемента и исключить (при наличии изоляции) любые проблемы с поиском стилей.
Обратная сторона такого подхода в том, что может появиться 100500 стилевых файлов разных компонентов с одинаковыми классами .foo, .bar, .baz, различающимися только хешем.
Ну так и ладно, чем это может помешать? Я же эти стили все равно не увижу.
а на этапе разгребания этого bloatware.
На каком таком этапе? Вы же работаете с исходниками, а сгенеренных стилей не видите.
А если нужно пофиксить какой-нибудь стиль? Открываем инспектор, а там .foo--q1w2, .foo--a3s4, .foo--z5x6. Дальше приходится искать конкретный стиль методом тыка.
Не понял. Если вы смотрите в исходники — там нет никаких .foo--q1w2, .foo--a3s4, .foo--z5x6, если вы открыли инспектор — то нужный стиль уже перед вами, ничего искать не надо.
Сам так не делаю (привык к редактору), но кому-то может быть и зайдёт.
Ну вы же всегда знаете, где она, т.к. видите нужный элемент.
Название класса на нём неоднозначное.
А зачем вам название класса? Просто игнорируйте это название. При изоляции любой стиль применяется к одному единственному компоненту, то есть к тому, который вы сейчас смотрите в инспекторе. Стили других компонентов к нему применяться не могут. Это и есть смысл изоляции — ситуация, при которой есть какие-то неоднозначности с тем, как и к чему применяется стиль, становится в принципе невозможной. То есть если у вас есть button_3232 и button_5454, то не может быть элемента на котором будет сразу оба этих стиля и не может быть двух разных компонентов, в каждом из которых применяется один и тот же стиль.
Вы всегда сразу знаете что, как и куда — даже не глядя на селекторы стиля.
Здесь, видимо, проблема в ментальной модели — вы пытаетесь анализировать получившийся css как обычный css, что неверно. изоляция дает гарантии, при учете которых анализ существенно упрощается.
Получается, единственный выход — правильно настраивать source maps
Зачем? Еще раз — вы сразу знаете, к чему относится стиль, т.к. он не может относиться к чему либо кроме как к компоненту, который вы выбрали.
Вам не нужны ни сорус мапы, ни названия, ни какая-либо еще фигня.
нужно детектировать, в каком компоненте это произошло?
В каком компоненте произошла ошибка вам как раз известно сразу — вы же видите где верстка поехала. А вот в каком стиле ошибка — вы не знаете. Вы тыкаете в элементы компонента и смотрите, в каком из стилей что-то сломано.
Нет. В проекте может быть много похожих компонентов
Ну как нет? Вы знаете место в котором верстка поехала, т.к. вы его по факту видите. Ну, страницу открыли и видите, что на ней что-то не так. С-но, нужный вам компонент — это тот, что отображает данное место. Он вам сходу известен.
Часть из них может разделять одни и те же стили, часть нет.
Изолированные стили не разделяются в принципе, так что не может. Иначе они не изолированные. В этом-то и суть. Если у вас стиль button_3434 то он используется только в одном единственном компоненте, при этом никаких других button_n в этом компоненте быть не может.
Как я и сказал, у вас неверная модель, вы смотрите на получившийся цсс как на обычный цсс. А он не обычный, он обладает некоторыми дополнительными свойствами.
В некоторых реализациях можно разделять, например, в CSS Modules. При этом они остаются изолированными на уровне стилевого модуля, т.е. css-файла.
А это ничего не меняет. Вы знаете, для какого компонента стиль, и далее вы из этого компонента однозначно попадаете в соответствующий css-модуль. Наоборот, тут даже плюс — т.к. вы легко можете посмотреть, какие компоненты еще используют этот модуль и, с-но, где что может (или не может) сломаться, если вы данный стиль поменяете.
В результате у нас могут возникнуть button_3434, button_4343, button_3443, button_4334.
Ну и пусть возникают.
Искать же, какую именно тут использовали кнопку, — то ещё удовольствие.
В каком смысле, что искать? Вы же видите эту кнопку перед собой. Вот у вас кнопка, стиль которой надо оправить, жмакнули по ней и в инспекторе увидели, что это button_foo. Надо поправить стиль соседней кнопки — жмакнули по ней, и увидели, что это button_bar. Что вы ищете вообще? Опишите как-то flow работы для конкретного кейза, где у вас проблемы. Потому что я даже теоретически не могу представить, на каком этапе они могут возникнуть. Что вы конкретно делаете, что у вас возникает неопределенность, где какой стиль?
Не факт. Какой-то div без классов и айдишника не несёт информации какому компоненту он принадлежит. Но вот назначили баг что кнопка какая-то полезла в проекте который только что команда приняла от заказчика, потому что старую команду он разогнал из-за того что документацию не писали :)
Не факт. Какой-то div без классов и айдишника не несёт информации какому компоненту он принадлежит.
А почему у вас div без класса и идшника вместо тега с именем компонента?
Потому что инспектор ничего не знает про реакты и ангуляры.
Он то конечно не знает, но это уже проблема вашего фреймворка в том, что он хост-элементы затер. К цсс и изоляции это отношения уже не имеет.
У вас все компоненты состоят ровно из одного элемента?
Конечно же, нет. Но любой элемент принадлежит ровно одному единственному компоненту, в котором находится. Так что если вы видите конкретный элемент, то вы точно знаете, какому компоненту он принадлежит.
Почему вы решили, что я это знаю?
Его название написано. Если читать умеете — то знаете, верно?
Притом, как я уже сказал, похожих.
Да не важно, похожих или нет, имя компонента перед вами, конец истории.
Ну вон выше vintage скриншот кинул, wrappez, my-appz, counter — имена компонетов. В типичном случае вам надо просто по вложенности компонентов пройти вверх до первого "кастомного" компонента (что обычно эквивалентно "посмотреть на несколько строк вверх"), он и будет тот, что нужен. В более сложном (с проекциями) надо пройти выше, до компонента с номером меньшим, чем в ng-content элемента.
Да и 20 лет опыта разработки в вебе? Где же столько взять.
А что, в 1998 году интернета не было?
В 1998 году не было WebGL, HTML5, CSS3 и прочих.
Зато украшать сайты с помощью <marquee> было не западло. А сейчас никакого удовольствия от дизайна :(
Можно подумать, это мешало получать опыт разработки.
Подход был уже тогда — HTML так-то изначально подразумевает разметку смысла, а не внешнего вида (google://семантическая вёрстка). Другой вопрос, что надёжнее было сверстать на таблицах.
HTML5, CSS3 и сейчас нет.Воспринимается как фильм ужасов, когда у тебя для 90% аудитории код доставляется в стандарте ES2017 (ES8).
… выход книги «Сто авторов против Эйнштейна». Под этим названием были собраны мнения ста ученых, которые опровергали и ругали и теории, и самого Эйнштейна. Говорят, что когда он узнал об этой книге, он спросил: «Почему сто? Если бы я ошибался, хватило бы и одного»
Я же не запрещаю автору что-то критиковать, а просто обозначить на основании какого опыта он это делает. И не для того чтобы топать ногами и негодовать «молодо-зелено», а чтобы адекватно интерпретировать поданный материал. И еще раз — это относится только к критике технологий, методологий, языков и пр.
А вы верите авторам статей только на основании бекграунда (i.e. авторитет) или всё-таки на основании доказательств в самой статье?
А вот свежий взгляд тут и говорит о проблемах
«свежий взгляд» в вебе это на самом деле новая инкарнация «фатального недостатка» — проблемы одной технологии лечатся созданием новой, со своими проблемами.
Да, 20 лет в вебе. Такое бывает. Как и обречённость: «Щас школьники сайты клепают. Что я до сих пор в веб-разработке делаю?»
Препроцессоры, цссмодули наоборот поощрают бем. Ведь бэм включает в себя правила касающиеся вёрстки, а не только правила именования. Например взять хотя-бы правило по которому блоки не должны влиять на своё позиционирование — это очень многого стоит, и помогает избежать хаоса в крупных проектах через годик.
Или например модификаторы — это тоже лютый мастхев, и позволяет производить избавление от говнокода.
Когда верстаешь один то конечно ты можешь это делать как хочешь, а когда вас 10 разработчиков и ты там главный то тебе нужно чтобы каждый разработчик верстал правильно и не допускал говнокода. Правила бэма позволяют это сделать.
Бэм это когда 9 женщин за 1 месяц раждают здорового
Да и 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 {}) ?
Встретились ли вам какие-нибудь минусы ?
Но большая вложенность из безымянных тегов тоже не очень удобна. В этом случае удобнее присвоить класс нужным тегам и обратиться к ним напрямую.
И обосновывается это просто. Что серверу, что клиентскому фреймворку одинаково просто сформировать 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 — это одна из самых плохих практик, она всячески порицается, и к БЭМ-у имеет отношение… правильно, никакое.
Оно никак не влияет на обсуждаемые вопросы
БЭМ ничуть не противоречит спецификации, не нарушает правил, не вводит новый синтаксис
Я выше писал, что противоречит, нарушает, вводит.
И уж тем более необходимость считаться с seo никак не влияет на мое предложение аргументировать свои мысли, а не бросаться безапелляционными утверждениями. А то сами с собой поговорили, сами с собой согласились, поцокали над другими неумными, у них там каша в голове.
С утверждением что css и html в принципе разные формы я согласен конечно. Ну, вот я когда-то юзал всякие fieldset, legend, label, чтобы мои формы были семантичными и чтоб в них не было противных дивов. Уверен, БЭМщик этим заниматься не будет. Вы скажете, ну, БЭМ не запрещает, он вообще параллельно. Хорошо. Предложите свою объяснение, почему люди, использующие БЭМ переходят на сплошные дивы, только не игнорируйте общую практику. Она ж это самое, критерий истины. Я например в бэмовской верстке такое очень часто замечал. Методология БЭМа имхо к тому подталкивает. Не согласны — предложите другое объяснение моему наблюдению. Что, сам Яндекс плохой пример? Так они же эту методологию и разрабатывают. Где-то есть флагман, в котором все по-другому?
В целом же, уверен, что поддержка или неподдержка html семантики мало зависит от используемой методологии, это вопрос личного выбора разработчика/архитектора. А если даже корреляция сильная наблюдается между отказом от семантичности и использованием БЭМа, то скорее у них просто общая причина, а не причинно-следственная связь «раз используем БЭМ значит отказываемся от семантики». Ну, например, и БЭМ, и верстка только дивами/спанами делают более простым и предсказуемым в разработке и(или) поддержке код веб-приложений. В частности на дивы и спаны навешиваются минимальные (и одинаковые в разных браузерах) браузерные стили касательно шрифтов, границ, отступов и т. п., с которыми не нужно бороться в своих.
Если что-то делает Яндекс, это не означает, что так же делают все, кто использует БЭМ. А по поводу заворачивания ссылок в div
. В HTML5 согласно спецификации стало возможным помещать в ссылки блочные элементы. В предыдущей версии действительно с точки зрения спецификации это было недопустимо. Однако согласитесь, что иногда удобнее поместить весь большой блок в одну ссылку, нежели делать внутри блока несколько разных ссылок, которые ведут на одну страницу. Удобнее хотя бы потому, что область клика многократно расширяется: куда не ткни, не ошибёшься.
Я ссылаюсь на Яндекс, потому что ссылаться на своих знакомых — бэмщиков нет смысла, они кроме меня никому не знакомы. Но все описанные мной тенденции и у них на месте. И пример с бла-бла-title, вместо h1 не выдуман и показателен. Люди мыслят иначе, чем тегами + правилами css с дополнением классами. Мыслят одними классами + стилизация ss без c. Это уже совсем другое качество синтаксиса.
Я выше писал про то, что я использовал по максимуму теги форм т.к. это позволяло с одной стороны, поддержать код семантичным, с др. обернуть все в блоки и сделать по макету. Я использовал микроразметку например в адресах т.к. это опять же позволяло прицепиться ко многим элементам, не внося лишних элементов в html. Я использовал blockquote для цитат т.к. там не просто кавычки, а цитаты, их оформление может отличаться от просто текста с кавычками. И чем более семантичный код я получу, тем больше власти для стилизации css буду иметь, сохраняя код чистым от лишней инфы в классах. Связь прямая. Сохраняется ли она с использованием БЭМ? Когда в классах больше инфы, чем в самих тегах? Ну, нифига не сохраняется. Можно продолжать верстать семантично? Можно, но зачем? Кому оно надо? Сеошники конечно могут потребовать, но что-то я не наблюдаю такой тенденции.
Стили на тегах использовать не очень хорошая идея. Вы завязываете стили на структуру страницы. И если что-то где-то поменяется (даже небольшие изменения в структуре), стили придется переписывать. Естественно, что сброс браузерных стилей придется делать на тегах, иначе-то и не выйдет.
Когда в классах больше инфы, чем в самих тегах?
Когда классы имеют осмысленные названия. Теги обычно мало о чем говорят о том, что за блок перед нами, кроме пространного "список", "блок текста", "навигация" и т.д.
То, что какие-то верстальщики не соблюдают семантики HTML, когда работают по БЭМ, не проблема и не вина БЭМ. Она ничего подобного не требует и не рекомендует. Ну то есть вообще не связано это, кроме каких-то паразитных ассоциация в мозгах некоторых верстальщиков типа «теги в селекторах не используются — всё заменяем на div». Я не понимаю как к этому можно прийти, хотя сам в своё время практиковал чисто «дивную» вёрстку, без всякого, заметьте БЭМ, которой тогда даже в зачатке не было, если верить официальной истории.
<div class="бла-бла-бла-родословная-title">Я заголовок</div>
и говорит, что мол, смотри, я могу с помощью вот это длинной штуки с title на конце отловить все заголовки, у меня появляется вопрос, а почему бы не сделать h1, h2 и ловить все заголовки по данному тегу в css? Почему нужно забыть про первое слово в Cascading Style Sheets? И вы сколько угодно можете доказывать мне, что БЭМ не заставляет писать так, но вот посмотрю на верстку яндекса, на верстку использующих БЭМ знакомых — вижу, что как не бэмовец, так обязательно divиантное поведение замечаю. Есть у меня версии почему так происходит? Есть, озвучил выше. Я не заставляю вас с собой обязательно соглашаться, но мне кажется, меня легко понять, если не упрямиться.
Я так и знал.
Если серьезно, мне никто, никогда не говорил «мы делаем это из-за сеошников» т.е. пример конечно логичный, но насколько он реалистичный?
Я вам дополнительно говорю что никто не заставляет вас использовать в разметке только дивы. Но если используете h1 то у него должен быть class с чётким именем. Если в цссе будете навешивать стили на имена тегов то это увеличит вес селектора и в будущем может привести к проблемам. Как правило никто не любит проблемы, нолюбит поддерживаемость. Делайте как рекомендуется в бэм, и получите то любите
Но я при этом согласен с тем, что БЭМ задает четкие указания на именование классов, стандартизирует процесс верстки и делает его более поддерживаемым для больших команд. Это другой вопрос.
Отвечал выше
habr.com/post/422537/#comment_19088331
Но я ж не только теоретизирую, я делюсь практическим наблюдением. Бэмщики злоупотребляют div-ами. Можете не соглашаться или предложить свою версию, почему. Для меня ответ на кончиках пальцев. Семантика сместилась на классы.
, а имена CSS-классов никакого значения для HTML не имеют.
Имена классов, вообще говоря, и для css никакого значения не имеют. По крайней мере не большее значение, чем имена тегов.
А вот радикальные заявления в стиле «Технология\методология\соглашение X это плохо\не должно существовать\ненужна.» на хабре встречают, в первую очередь, скептические оценки. Часто заслужено.
Возможно, я не прав, но на мой пре-джуновский взгляд, так кажется
А вообще 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.
.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>
Что мешает настроить цссмодули чтоб не было хешей?
<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
Эм, нет. Моё сравнение абсолютно корректно. Я сравнил код, который получается на выходе. Потому что в самой статье, как я понимаю, также речь идёт об итоговом коде (который вполне себе появляется в веб-инспекторе, и его надо отлаживать). И тут 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 проектах это оооочень хорошо чувствуется.
Не надо говорить что с приходом стулед
Вы правильно говорите, но позволю вас дополнить:
Бэм не только про пространства имён.
Он ещё и про правила по уменьшению связанности кода, про формирования стилей отвечающих за внешнюю геометри блока, применение груповых стилей, и куча другого.
Цель всего этого увеличить поддерживаемость упростить переиспользование и рефакторинг.
Сегодня он у вас белый, а завтра дизайнеры решат сделать жёлтым. Более подходящие имена: -main, -primary, -payed.
С год назад пришёл к выводу, что даже "-main, -primary, -payed" не помогают.) Ибо через время, понятия что есть prymary, а что есть secondary — также достаточно сильно размываются. Поэтому начал все переменные обзывать просто $color_1, $color_2, $color_3 ..., $breakPoint_1, $breakPoint_2, $breakPoint_3… Как оказалось, в долгосрочной перспективе удобнее. При редизайнах не нужно думать, куда какой цвет прилепить, добавить новый или менять по всему проекту переменные.
PS ide и редакторы подсвечивают sass переменные соответствующим цветом — запоминать не нужно.
for (var zero = 0; zero < n; ++zero)
:root {
--primary-color: #f4d249 // корпоративный желтый
}
li {
background: var(--primary-color); /* хоть для фона */
border: 1rem solid var(--primary-color) /* даже сюда */
}
li a {
color: var(--primary-color) /* хоть для текста */
}
тыкаем во все необходимые блоки — меняем 1 раз. Нужен зеленый? Меняйте и все само встало. Не нужно бегать по всем блокам и менять цвета
.article-rewind {
& > .link {
...
}
}
Просто любым инструментом нужно уметь правильно пользоваться.
Похвалите BEM в статье, которую напишите вы, возможно, я передумаю, если хорошо опишите и докажете.
И да, много пишут: критикуешь — предлагай. Хочу предложить архитектуру и идею Bootstrap'a, похвалить SMACSS и OOCSS, чем и займусь в слудеющих статьях.
Bootstrap тоже не идеален, когда дело касается переопределения стилей его компонентов. Там тоже полно привязок к тегам, тройной и более вложенности селекторов.
Хотелось бы тогда увидеть приведенные вами альтернативы БЭМ'у, хотя-бы с краткими объяснениями почему они лучше.
Из минусов — постоянно находятся люди в интернете, которые говорят, что если добавить обертку вокруг элемента, то все сломается (т.к. все строится на непосредственной вложенности). Но за последний год ни одного такого случая не припомню. Может сам дурак, а может и нет этой проблемы.
Любой компонент — это одновременно:
- бэм-блок
- бэм-элемент владеющего им компонента (бэм-блока).
Так вот, как стилизовать бэм-элемент, если между ним и владельцем рендерится обёртка, добавляющая чёрт знает какие хтмл-элементы?
Ну, пример на Реакте:
<div class="app">
<Panel header={ <div class="title"> }/>
</div>
Надо лишь передать нужный класс компоненту Panel — а тот пусть сам его применит к элементу верхнего уровня.
<div class="app">
<Panel class="app_content" header={ <div class="title"> }/>
</div>
В любом случае, это общая проблема BEM и RSCSS.
А можно поинтересоваться, насколько большие вам доводилось делать? Какая была самая большая команда в которой приходилось работать?
Если проект небольшой и пишется в одно лицо, то можно много каскадных красивостей нагородить. При наличии даже двух разработчиков начнется ад.
Многолетний опыт верстки мне говорит: БЭМ не идеален, но это лучшее из имеющегося. Никакая другая методология не выдерживает конкуренции с ним на практике. (Единственное исключение — css-in-js, но это игрок с несколько другого поля). Существенно лучше него может быть только радикальная переделка всего стандарта CSS, с блекджеком и неймспейсами.
Ценой некоторой многословности он решает огромную кучу проблем.
Каскад БЭМ не отрицает, а лишь призывает к ограниченному его применению. Изобретался каскад в древние времена, когда сайты были на порядок проще, а сейчас условия изменились — вылезли на поверхность побочные эффекты.
Препроцессоры он тоже не отрицает, а наоборот прекрасно с ними сотрудничает.
Остальное даже комментировать нечего.
Короче, учиться и ещё раз учиться.
Ведь автор реально невежда, как и множество его предшественников.
На самом деле, я бы удовольствием отсыпал плюсов статье с серьезной критикой бэма и предложениями по его усовершенствованию/замене. Но таковых пока не видел.
Все виденные мною «разоблачители» — это люди, которые просто ни черта не поняли в теме. И на самом деле они критикуют не сам бэм, а свои очень кривые его трактовки.
Но теперь есть
all
и initial
/ unset
, которые, вероятно, сильно уменьшат востребованность БЭМ даже в больших, непрерывно развивающихся проектах конвейерного типа. Остаётся «лишь» дождаться поддержки этих возможностей CSS в браузере Edge и уменьшения доли устаревших версий браузеров Microsoft до пренебрежимо малой. Значения initial
и unset
поддерживаются уже начиная с EdgeHTML 13 (2015), но без свойства all
толку от них мало.На мой взгляд все проблемы описанные в статье — скорее преимущества методологии, а не недостатки.
И если строго следовать методологии — то как минимум БЭМ не позволяет говнокодить — а только дисциплинирует и закаляет.
Эта библиотека как раз и умеет прописывать всё. Писал аналог на vue, правда только для на простых случаях. Очень сильно сокращался код и всякие условия по генерации классов и т.п.
Абаснуй
И вообще не надо путать. Реакт — не для вёрстки придуман. А BEM для того, чтобы вёрстку не упростить, а зажать в рамки, чтобы своих велосипедов никто не придумывал.
Единственная проблема, которую решает БЭМ — это конфликт селекторов. Говнокодить он никак не запрещает.
Но такое, еще и с претензией
А ведь добрый мальчик pepelsbey уже давно все рассказал
wsd.events/2014/04/12/pres/bem-ok
www.youtube.com/watch?v=RM55tkWfHDc
И не только в данной презентации
БЭМ, конечно, спорная фигня, но циклы в стилях — это точно за гранью добра и зла.
А чем вас, простите, циклы в стилях не устраивают? :)
Тем, что стили должны иметь декларативный характер. Еще не хватало дебажить стили =)
Т.е. миксины, шаблоны, функции и прочую "ересь" тоже стоит запретить? :) Тогда мы придём к чистому 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? Или getElementById() тоже нельзя использовать?
Каскады вида .block--modifier .block__element можно применять, только осторожно. Дело в том, что если у вас в элементе окажется такой же блок (например, вы делаете древовидный компонент), то модификатор родителя будет влиять на элемент дочернего блока.
Вот это вот вообще непонятно. Я-то прекрасно знаю все селекторы CSS. В случае чего, можно с помощью контекста повысить специфичность, поставить дочерний/соседний селектор. Что значит «только осторожно» — для кого эта методика? Для тех, кто не в состоянии посчитать сколько раз блок встречается в документе? Так давайте пойдём ещё дальше и максимально упростим задачу для таких людей — будем вешать уникальный идентификатор на каждую сущность DOM. А потом для каждого прописывать свои СSS-правила (можно даже группировать одинаковые по стилям блоки, хотя судя по объёму кода в БЭМ — это далеко не первостепенная задача).
Если в большой команде появляется новый человек — ему первое время все равно придётся пользоваться веб-инспектором.
Понимаете, что лично у меня вызывает раздражение — это что «веб-евангелисты» Яндекс и Макеев (да и не только они — большинство фреймворков сейчас ориентированы на такой подход), пытаются представить вёрстку как сугубо механическую работу — наплоди тучу блоков, каждому присвой уникальный класс и автоматом пропиши для него правила. Да, скорее всего это работает быстрее. При этом вопросы чистоты кода и семантики идут просто лесом…
А мне вот как-то по старинке ближе, когда в начале подробно изучается проект, строится иерархия использования стилей, определяются глобальные классы, сразу продумывается «резерв» для медиа-запросов и т.д. Когда в итоге стилевой файл абсолютно читабелен и легко поддается изменениям, а HTML-структура выглядит понятно, семантично и легковесно. И потом не возникает никаких проблем (даже для новенького) — всунуть туда новый блок или изменить старый, потому что варианты развития проекта продумываются ещё на этапе построения абстрактной DOM-модели.
Ну и наконец, есть такой известный методологический принцип — «Не плодите сущности без нужды»(с) У. Оккам
Каскады вида .block--modifier .block__element можно применять, только осторожно. Дело в том, что если у вас в элементе окажется такой же блок (например, вы делаете древовидный компонент), то модификатор родителя будет влиять на элемент дочернего блока.
Если верстальщик/девелопер интерфейса не может представить, или даже просто записать структуру своего интерфейса, который делает — то чего он делает вообще в этом бизнесе?
Каким нужно быть… чтобы нагородить вложенные блоки прототипов, влияющих друг на друга.
Тут еще выше люди отписывались про ад при работе в команде, если без БЭМ, это просто жесть. Если команда сама себе придумывает проблемы на ровном месте, не имея каких либо общих договоренностей об именованиях при разработке, то это не команда — это бесполезное сборище.
Я уже просто десятилетие, не побоюсь этого слова, во всех проектах, с разными командами использую простейшее правило именования — цифровые индексы с буквенными приставками для разных типов селекторов. И ни разу еще после оглашения этого правила, никто не смог запутаться в коде. Именуем все классы, идентификаторы, прочие необходимые селекторы в пределах одной логической единицы интерфейса, строго цифровыми индексами от 1 и далее (к выданным буквенным префиксам этого интерфейса). В начале самого кода, каждый разработчик, работающий с этим кодом, указывает последний используемый индекс в этом интерфейсе — всё! Что там еще городить? Какие циклы? Какие вложенные структуры и блоки? Любой разработчик, открывая файл проекта с кодом, видит номер последнего примененного имени, просто продолжает дальше имена со следующими цифрами.
Понадобилось вам после нескольких лет работы приложения/интерфейса внести изменения (дополнить ли, или изменить код и внешний вид), продолжаете вносить модифкаторы для нужных блоков именуя их дальше по порядку цифровыми индексами, это гарантия, что вы никогда не столкнетесь с конфликтом имен в кодах проекта.
Если же ваш проект-менеджер сделал так, что у вас один ленд, или страницу интерфейса верстает сразу несколько человек — гоните такого менеджера в шею, в любой момент времени, отдельную логическую единицу верстает всегда, ВСЕГДА! один девелопер. Да млина, это не войну и мир писать группой — это одна видимая страница интерфейса, как могут там оказаться 2 верстальщика? Какими нужно быть упоротыми, чтобы до такого додуматься?
Если верстальщик/девелопер интерфейса не может представить, или даже просто записать структуру своего интерфейса, который делает — то чего он делает вообще в этом бизнесе? Каким нужно быть… чтобы нагородить вложенные блоки прототипов, влияющих друг на друга.
Уровень разработчиков даже в пределах одной команды всегда разный. Можно использовать соглашения, но потом ты такой перескакиваешь на другой проект, а там… Либо другие соглашения, либо отдельные чуваки с собственным видением того, как правильно.
Я уже просто десятилетие, не побоюсь этого слова, во всех проектах, с разными командами использую простейшее правило именования — цифровые индексы с буквенными приставками для разных типов селекторов.
А можно живой пример?
Уровень разработчиков даже в пределах одной команды всегда разный. Можно использовать соглашения, но потом ты такой перескакиваешь на другой проект, а там… Либо другие соглашения, либо отдельные чуваки с собственным видением того, как правильно.
Так это и с БЭМом так же. В одной команде использую свою систему именования, а в другой иную. Кто может просто наприсваивать одинаковых классов разным блокам (потому что как раз система именования в БЭМ не продумана).
Ну а когда ваша "команда" вырастает до двух человек буквенно-цифровые индексы будкт постоянно незаметно приводить к незримым ошибкам на пуллреквестах.
Я не говорю уже про команду в 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''».
Вы вроде даже приводите цитаты с 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 — гадость
Пожалуй, нет
Вообще все доп инструменты призваны улучшить опыт разработки, а никак не наоборот. Плюс есть ещё субъективный момент в использовании.
И как source-map поможет быстро начать редактировать? :-) с чистым CSS я просто копирую селектор, жму ctrl+shift+F
в редакторе, вставляю и в один клик перехожу к редактированию нужных стилей.
Работая сейчас с Реактом могу предположить, что это проблема не css (он у вас один глобальный?) а модульности самой вёрстки. Когда я работаю с каким-то селектором, я работаю в первую очередь с компонентой, а в стилях для компоненты нет никаких сложностей найти нужный селектор в SCSS из сгенерированного CSS, потому что я изначально знаю где искать.
Дак дело то не в этом. Есть компонента, есть css этой компоненты. Фиксите стиль компоненты — первым делом идёте в код и ищете саму компоненту (и её стили). По имени-иерархии-чему-угодно. А там уже находите нужный стиль. Или сразу ищете по ctrl+shift+f и отсеиваете (при совпадениях) заведомо ложные вхождения (из других компонент).
Крайне спорное утверждение.
Давайте гипотетически, один большой CSS по которому просто искать и куча SCSS исходников по компонентам.
Когда работа в процессе и мы работаем с одной-двумя компонентами удобнее (и быстрее конечно же) когда есть пара файлов с минимумом лишнего кода (стилей) по которым просто (и быстро, конечно же) ориентироваться.
Когда же вы возвращаетесь через полгода чтоб что-то подправить — согласен, быстрее добраться до места по глобальному поиску по точному совпадению строки.
Но давайте сравним, что же в итоге быстрее — десятки изменений в процессе работы, или пара изменений через полгода?
Мне кажется что именно через полгода можно потратить пару лишних минут, чем мучаться в процессе работы.
Но в общем, по большому счёту, модульно можно и с CSS работать, просто собирать в один файл, тут дело такое.
Неоднократно получал на поддержку подобные проекты.
Причём найти код ещё мелочь, нужно потом этот код ещё изменить, а если оказывается, что нужно подправить не только css, а ещё и html (что-то добавить или переместить), то зачастую летит вся описанная в css каскадность. Особенно это «радует» когда проект с адаптивной вёрсткой и описание каскадности идёт вперемешку с медиазапросами, такие вещи зачастую проще с нуля переверстать, чем поправить.
Как итог, последние пару лет всё, что делаю с нуля, делаю с применением БЭМ. Поддерживать такой код потом в разы легче.
И в какой-то момент наступает понимание, что это необратимо — даже если я и хочу сделать всё правильно, я уже не могу. Там такие авгиевы конюшни, что разгрести его не представляется возможным, только сжечь. И даже самый добросовестный разработчик смиряется и просто плывёт по течению.
Теперь слетайте в отпуск на месяц куда-нибудь в тайгу без ноута, а по возвращении пофиксите срочную багу «тут у нас менюшка из бокового виджета налезла на кнопку оплаты».
Открываете css менюшки из бокового виджета и фиксите. Две секунды делов, в чем проблема-то?
Правильно настроенный source map показывает конкретный номер строки в конкретном файле.
Вам настолько лень переключиться между окнами? :)
Нагуглить не получается, но ЕМНИП среды от JB могут понимать урлы вида localhost:65532/go/foo.cpp/80 (от урл написал от балды)
Меня больше всего раздражает, когда нельзя скопировать из отладчика селектор и быстро найти файл и место в этом файле, где на этот селектор наложены стили.
Попробуйте использовать карты исходников. Даже копировать ничего не придётся. =)

Кстати, в Chrome (как минимум) есть возможность подключения файловой системы исходников, так что править стили можно прямо в отладчике. Так даже путь копипастить не надо.
Отладчик, конечно, умеет в SCSS.
Найдите и посмотрите видео Харисова, он подробно рассказывал откуда, как и почему появился БЭМ.
Почему только СНГ? Новая библиотека от Гугла тоже использует БЭМ https://material.io/develop/web/
С БЭМом очень удобно добавлять свои стили. Четко ясно и понятно, где твои, а где библиотечные блоки.
Выше в комментариях упомянули что одно из преимуществ БЭМ это скорость рендеринга. Тут сложно сказать почему, но гугловая либа визуально быстрее materializecss. Но тут возможно из-за перехода от float на grid'ы
Новая библиотека от Гугла тоже использует БЭМ https://material.io/develop/web/
Где вы там его увидели?
Но тут возможно из-за перехода от float на grid'ы
Точно из-за этого.
Где вы там его увидели?
Вот, в гайдлайнах прописано: https://material.io/develop/web/docs/authoring-components/#follow-the-bem-pattern
https://material-components.github.io/material-components-web-catalog/#/component/button
Ну такой себе БЭМ у них получился. Спишем на неопытность.
Новая библиотека от Гугла тоже использует БЭМ material.io/develop/web
Где вы там его увидели?
material-components.github.io/material-components-web-catalog/#/component/tabs

Собственно всё сводится к тому, что у БЭМа «длинные» имена классов, и вам это не нравится. «Нечитабельный» — это не аргумент. Что для вас нечитабельно, для других может быть очень даже удобно.
<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 и заменить их на дивы. Ваши действия?
Посылаю сеошника лесом :-)
С остальным согласен.
Наконец-то кто-то это написал! Последние лет 5-10 программеры упорно тащат в мир дизайна кучу решений из своей практики, и решения эти для дизайнеров выглядят уродливо и неудобно.
Теперь уже простой сайт не сверстаешь без npm и прочих радостей командной строки, да и вообще вместо сайтов делают простоодностраничныеприложения (да, в одно слово)
Вот это вот всё БЭМгое — опять программеры натащили, и, конечно, будут защищать — см. комменты выше.
Только это все другая логика. Дизайнеры работают с визуальными подходом, и хотят видеть все текстовые вещи простыми и далекими от программирования. CSS задумывался просто и по-дизайнерски. Поэтому там нет наследования и так далее. Мы не пишем IScalableHeadingLevelInterface::_blockDivLayer, мы пишем div.h1… div.h5, и нам так удобнее. Нам не надо мейнтенить, рефакторить, супероптимизировать и асинхронно выполнять. Нам просто надо, чтобы flex уже везде заработал нормально...
Во-во! Понапридумывают своих pug, sass, less, bem, а другие страдают, учить приходится! <sarcasm_off>
Less отличная штука, только непонятно, почему для неё нужен отдельный компилятор, не встроенный во все среды разработки.
Да и вообще, почему нормальной среды визуальной разработки так и не появилось со времён DreamWeaver.
Less отличная штука, только непонятно, почему для неё нужен отдельный компилятор, не встроенный во все среды разработки.
Потому что это надстройка над CSS и смысла для неё пилить нативную поддержку браузерами нет. Сегодня есть LESS, SASS, Stylus. Завтра появится еще что-нибудь.
А дизайнеры хотят ли иметь право попросить передвинуть "вон ту штучку" "куда-нибудь туда"? Законное право для дизайнера.
А верстальщик хочет сделать это на раз, без лишних трудозатрат? Законное право и торжественная обязанность верстальщика.
А если внешний вид "вон той штучки" размазан по каскаду?
А если внешний вид "вон той штучки" завязан на конкретное местоположение?
Или пусть не дизайнер и верстальщик, а заказчик и фуллстек человек-оркестр, он же дизайнер, он же вёрстку творит.
Вы считаете уменьшение связности кода злом и ненужным усложнением? Возможно, Вы адепт одноразовой разработки: быстро сделал, отдал и забыл?
Программисты, конечно, себе на уме, но снижение связности кода (вёрстки а частности) удешевляет его изменения, в противовес микроменеджменту в отношении элементов вёрстки. Один раз научили элемент как-то выглядеть, а дальше он сам выглядит, как надо.
Не должно быть "штучки, вид которой зависит от местоположения". Это вот тот самый компонентный подход, который удобен программистам — и противоречит дизайнерскому подходу.
Если эта Штучка (такая, штучка!) выглядит в разных местах по-разному, то это две разные штучки. На уровне функциональности — пожалуйста, переиспользуйте. А то, что относится ко всему визуальному — не надо, правильно будет сделать заново.
Дизайн — это инженерная профессия. И решения в нем должны быть с инжереным подходом.
И поверьте, никого не волнует как удобно вам, удобно должно быть людям, которые код поддерживают.
А в это время в другой вселенной дизайнеры САМИ программируют дизайн систему:
Чтобы разобраться, можно ли безболезненно изменить стили для класса .active, разработчику придется просмотреть всю структуру страницы или проекта. Любое изменение потребует значительных временных затрат только на поиск зависимых компонентов.
Зачем тут изобретать велосипед? Прописываем стили для .nav .item, а потом для .nav .item.active. Если вы так боитесь что до этого вам кто-то мог насовать в .active всяких !important (что само по себе уже странно, так-то вам и без того в код могут насовать чего угодно, например уже использовать тот же «nav» — тоже ведь получается надо просматривать всю структуру данных) — ну обзовите как «nav-active».
Если не будет каскада, то как вы собрались повышать приоритет правила? Расположением ниже по коду? Но это же вообще дичь!
Имеем, например такой 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{...}
Но лично мне подобные задачи встречались крайне редко.
Это не «идиотская вёрстка», а реальный пример с продакшна. И такое, поверьте, встречается гораздо чаще, нежели какой-нибудь подход поадекватнее. Это похоже на страсть к сокращению названий переменных в коде или колонок в таблицах БД. Когда ты такой смотришь на это и только «просканировав» большую простыню кода понимаешь, а что тут, собственно, имелось-то в виду под этими названиями.
Так и здесь. .button
— что за .button
? .panel
— что за .panel
? .item
— что за .item
? Список можно продолжать… Добавьте сюда еще стили на тегах, понатыканный везде >
и не дай боже стили на идентификаторах) Туши свет, бросай гранату называется.
Значит, стили изначально неправильно переиспользовались или недостаточно гибко писались.
.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.
Я точно так же, как и БЭМ, могу спокойно обвешать классами каждую сущность. Только вот в отличие от БЭМ, я могу очень гибко пользоваться наследованием стилевых свойств. Определив классы для какой-то вышестоящей по иерархии сущности, я сразу их определяю для целого ряда вложенных сущностей, чтобы избавляет меня от нужды по несколько раз копипастить участки кода.
В то время я (не ограниченный жёсткими рамками БЭМ) могу как навесить доп.класс этому блоку, так и просто поставить цепочку контекстных селекторов (ведь у этого блока наверняка есть родитель с классом) — тут всё зависит от конкретного проекта. Есть гибкость. Я внизу статьи добавил комментарий о том, как инкапсуляция блоков сильно мешает поддерживать проект.
Не надо использовать "внезапные переиспользуемые компоненты". Они так же поломают БЭМ, при желании.
И когда окажется что ваш nav .item наследуется в коде другого чудного разраба, а какой-нибудь jquery плагин от пятого рукожопа вообще превращает его в карусель, вы, матерясь и проклиная всё на свете придете к БЭМу. Думаете те кто его юзают любят и поэтому защищают? Вы ошибаетесь. Я его ненавижу. Все хотят чистый и красивый html, но в реале у нас БЭМ + schema.org + a11y аттрибуты. Так и живем.
Используя БЭМ совместно с глобальными классами для цвета, фона, границ и прочего (определяемыми активной темой) можно вполне себе неплохо жить — будет меньше разных классов с одинаковым содержимым.
Следовать БЭМ буква-в-букву никто же не заставляет. Авторы методологии, конечно утверждают обратное. Но ведь мы же все со своими головами, правда?
Это нормально. Комментарии без критики просто не нужны — вместо них можно просто поставить плюс.
Комментарий — это «ты не прав, вот почему». Минус — это что-то среднее между «ты не прав» и «я не хочу это видеть на хабре», причём судя по интерфейсу хабра (приглушать заминусованные) скорее второе.
Или я тебя не правильно понял :)
Во первых есть модификаторы. Во вторых есть возможность сделать диугой блок с нуля. Выбирайте то что прощще.
Хабр отнёс мой коммент к вам. Это конечно же не к вам а к человеку в цепочке
CSS Modules к бему не относится, вопрос чисто про бем был.
Решение: запрещено использовать имена блоков, состоящие из одного слова, потому что однословные имена всегда слишком общие и расплывчатые.
Ну назову я список .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.
Иногда можно. Но вообще модификаторы предназначены для смены декора, а семантически и по конструкции блок должен быть один и тот же. В нашем примере список товаров в каталоге и корзине существенно отличаются по всем показателям.
Но тогда вы их как-то различаете? Условно говоря, один будет primary-catalog, другой secondary-catalog. Соответственно получаем .primary-catalog-products-list.
Или может один будет promo-catalog или ещё как-то. Ноги обычно растут из бизнес-логики, никакие имена классов не выковыриваются из носа.
Но если она случается, при использовании БЭМ-а она сравнительно легко решается, потому что блоки независимы — где-то что-то переименовали, и оно дальше работает. Просто небольшой рефакторинг, нормальный рабочий процесс.
А вот если там было месиво из многоступенчатых каскадов, да размазанных по разным файлам… Удачи в отладке :)
в проект пришел еще один разработчик, который не в курсе что где-то там есть еще один такой блок с таким же именем.
Очень просто: храните стили блоков в отдельных файлах. Имя файла == селектору блока. А дальше файловая система вам просто не позволит создать два файла с одинаковым именем.
Любую систему можно сломать при должном уровне криворучия.
Семантика в таких аппах строится на уровне компонент, а CSS/HTML — остается низкоуровневым таким ассемблером, где важно все ровно поставить, важно чтобы оно с другими компонентами не пересекалось, а какие там хаки и как это все в исходниках выглядит — вообще всё равно.
Часто не BEM, а вообще CSS-in-JS инлайнами, или CSS Modules, где классы вообще до «f2ds3» сжимаются.
Так что странно смотреть на BEM с позиции «CSS писать и смотреть не удобно». В проектах где BEM — этот весь лишний код генерируется, и всем пофиг как оно выглядит.
Руками по BEM писать на чистом CSS и HTML небольшой сайтик, или даже селекторы типа «hero-button__caption» — это бред, конечно, не надо так делать.
Keep it simplе and
Ты, дорогой друг, перед тем как давать ценные мудрые советы, сначала убедись что они не приводят к нищете и депрессии. Например, отыщи хоть один коммерчески успешный и семантично сверстанный сайт, с чем-то посложнее тупо статического контента.
Я не знаю, что в вашем представлении «коммерчески успешный». Но любой опытный разработчик вам скажет, что есть порог абстракции, после которого выгоды оптимизации процесса методом модульного абстрагирования, например, начинают проигрывать на фоне чрезмерной усложненности системы. Особенно если контуры будущего наращивания системы не очевидны. Не говоря уже о тенденции таскать из проекта в проект одни и те же убогие паттерны. И хорошо, если разработчик понимает, Что он таскает. Так зачастую же нет! Он просто увидел где-то и рад так же «запилить», просто потому что об этом уже написали в блоге другие такие же горе-разработчики, а так же из неофитского страха «отстать от тренда».
То, что нынче сайтов перегруженных модными девелоперскими свистелками, пруд пруди — не повод для того, чтобы делать так же.
Вообще, я вижу две основные причины тому:
а) мода на псевдоноваторские подходы (когда юный падаван не в состоянии отличить «те же яйца вид сбоку» от реально хороших идей, покуда его уровень понимания работы системы ограничивается уровнем отображения его верстки в браузере)
б) когда дедлайны и некомпетентность менеджмента диктуют рамки, в которых разработчики вынуждены находить быстрые но неэффективные решения, как в плане архитектуры самого проекта, так и бизнес-процесса в целом.
Применительно к нашей теме: ирония в том, что желание заглянуть в код возникает не тогда, когда ты не замечаешь frontend, а когда frontend по ощущениям настолько убого сделан, что невозможно устоять от искушения заглянуть «под капот». Но на вскидку…
Вот например сайт www.gov.uk
UK government services and information. Загляните в код, обратите внимание как все там аккуратно сделано. Так вот, это интерфейс автоматизированной системы полностью обслуживающей граждан Соединенного Королевства. Система налоговых отчетов, разного рода лицензирования, ИНН, выплаты на здравоохранение, все, что вам надо от гос сервиса. Там столько классно придуманных и просто сделанных нюансов внутри, что можно целый день рассказывать.
PS ну и за лексиконом я бы вам тоже посоветовал следить. А то, знаете ли, неприятно.
Заглянул в код gov.uk, впечатления соответствуют названию:
- Дикий каскад в селекторах (
#footer .footer-categories .footer-explore h2,#footer .footer-categories .footer-inside-government h2
). - Стили навешанные на теги и идентификаторы.
- Однако часть стилей сделана по БЭМ.
- Не собранные в бандлы стрипты и стили.
Для тех кто пилит интерфейсы, CSS, HTML и JS — выглядит как блевотно задизайненное, и хреново работающее говнище.
C 2009 (если считать с даты начала официальной работы, а не школьного баловства) пилю-попиливаю сайты разной сложности и могу сказать, что люблю и уважаю и HTML, и CSS, и JavaScript. Конечно, сейчас я в основном пользуюсь SASS вместо чистого CSS и препроцессором для JavaScript. Однако я не совсем понимаю таких комментариев, как ваш, а также разговоры о том, что, де, "верстка и фронтенд — говно, бекенд — зашибись". Причем на чем бы этот бекед ни писался.
Мой поинт в том, что не надо воспринимать CSS/JS как божью росу, и заводить разговоры типа «вы дураки со своими реактами и тайпскриптами, всё можно сделать в 10кб на прекрасном, мудром, семантичном JS/CSS». Flexbox не смог — ок, JS-ом div-ы подвигаем. Не выходит сделать плавную анимацию CSS — берем canvas и рисуем сами на нём. Не получается нормально сделать работу команды с одним CSS-файликом — берем пре-процессор и лепим всякие сложные миксины, и пофиг что там в результате в самом CSS получится.
Только так сложные приложения и делаются. А на божественно-семантичном, чистом как слеза CSS, можно разве что какой-нибудь простой статический сайт сделать. Банальный DatePicker — уже треш, угар, и хаки.
Но ваш пример плохой, поскольку сильно затрудняет поиск класса по проекту. Это из личного опыта. Просто подумайте как вы будете искать класс
.article-rewind__text
в исходном коде?Если подобный подход используется повсеместно и я об этом знаю — я найди блок .article-rewind
, а потом внутри него найду блок &__text
. Если я не знаю что такой подход используется повсеместно — я попробую найти .article-rewind__text
, не найду, начну смотреть файл с начала и увижу в чем дело.
А вот если такой подход используется ровно для одного стиля — да, это может стать проблемой...
.article-rewind {
... 500 строк
&__text {
... 100 строк
&--red {}
... 100 строк
}
... 500 строк
}
Я бы начал задумываться о декомпозиции уже после ~100-150 строк суммарно на весь блок, включая все элементы и модификаторы.
.article-rewind {
&__menu {
... 100 строк
}
&__link {
... 100 строк
}
&__text {
... 100 строк
&--red {}
... 100 строк
}
&__etc {
... 100 строк
}
}
Какой тут способ декомпозиции кроме как не использовать
&__element
?&__menu {
... 20 строк
@media-for-tablet{
...20 строк
}
@media-for-desktop{
...20 строк
}
@media-for-UHD-desktop{
...20 строк
}
@media-for-print{
...20 строк
}
@media-for-tv{
...20 строк
}
}
Итого 132 строки
Кого беспокоят лишние байты — есть специальные плагины для сборщиков, которые вытянут и скомпонуют.
Если у меня есть блок, то я хочу видеть его поведение сразу и полностью, а не ползать по нескольким файлам, сравнивая их построчно.
Есть плагин для gulp — group media query's.
Повторюсь: если там реально приходится писать 132 строки, нужна декомпозиция.
Раскладывайте элементы по файловой структуре и всё будет удобно и однозначно:
https://ru.bem.info/methodology/filestructure/
sourcemap. Сборщики умеют, браузеры (во всяком случае Хром точно) поддерживают. Видно и имя исходного файла, и номер строки.
Я могу сделать ctrl+клик по «ужасному, длинному» классу и моментально оказаться в определении селектора. Куда я попаду если сделаю такой клик по тегу или какому-нибудь классу ".active"? Правильно, в список из 146 различных файлов, где такое определние встречается.
Или нужно мне добавить враппер вокруг элемента, так я беру и добавляю его и ничего не ломается.
Маленький лайфхак в именовании классов, который мне нравится куда больше оригинала:
.Block-Name__element--mod
Именование может быть любым, главное, чтобы можно было программно определить где блок, где элемент, а где их модификаторы/значения:
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. Но самый последний пункт — «Ваша схема именования»
Ну и поехавший блок как раз может разворотить всю вёрстку. И искать причину (какой нибудь font-size:0;) вы можете очень долго.
P.S. Почему-то у сторонников БЭМ всегда есть аргумент — «поналепят каскады тэгов, а потом удивляются почему вёрстка поехала». При этом почему БЭМ противопоставляется исключительно каскадам тэгов — не очень понятно…
Есть страница, у неё есть шапка и подвал. Есть модальное окно, у него тоже есть шапка и подвал. Если написать так
body header { ... }
.modal header { ... }
то стили глобального хедера применятся не только где надо, но и к хедеру модалки тоже. Ну потому модалка очевидно входит тоже входит в body.
Но погодите! — скажет любой неофит, окончивший курс «Верстка за 24 часа» — ведь можно написать вот так:
body > header { ... }
.modal > header { ... }
Можно, но только в идеальном мире, где html-структура делается один раз и навсегда. А в мире реальном она в ходе жизни проекта меняется много раз — доработки дизайна, функционала, багофиксы… Хотелки заказчика, дизайнера, сеошника… И частенько бывает нужно вставить промежуточную обертку. Или переподчинить узел другому родителю. Или сменить тэг. Или перенести что-то в другое место страницы.
Каскад нужно во-первых переписывать, а во-вторых молиться, чтобы эти изменения не поломали что-то в совершенно другом месте. Поэтому часто никто этим не заморачивается, а просто херачит рядом перекрывающий более специфичный селектор. Очень скоро всё это дело выходит из-под контроля.
При БЭМ-е доработки тоже понадобятся, но точечные.
Не понимать побочных эффектов каскада может только либо полный новичок, либо верстальщик, всегда работавший по принципу «сверстал, отдал, забыл» — потому что для него страница статична, он никогда не видел что с ней происходит потом.
body header
body .modal-header
Почему противников тотального использования БЭМа принято считать полными идиотами? И всё у них разваливается постоянно, и классы они одни и те же используют, и каскады из тэгов строят… Если очевидно что стили затронут другой элемент DOM не имеющий каких-то наследственных признаков с родительским (сознательно не употребляю «блок»), то зачем к нему обращаться через подобный каскад? Причём тут вообще БЭМ? Дурак и на БЭМе напишет .header_wrap для обоих блоков.
Какими символами они при этом разделены, совершенно неважно, это вопрос договоренностей и вкуса. Вы на правильном пути. Осталось понять, а зачем во втором случае привязываться к body?
Ну так а при чём тут БЭМ? Это же всё довольно очевидные вещи. При этом БЭМ задаёт довольно жёсткие рамки, а я призываю к гибкости, а не копипастному следованию «философии БЭМ». Ладно, это всё бессмысленные споры и им уже не один год. Кто привык сидеть на БЭМ — будет защищать эту технологию и наоборот.
Я сам был не сторонником BEM'а думая что это уже излишества. Но чем сложнее становятся проекты и чем дольше ты работаешь непрерывно в «сфере» ты потихоньку изобретаешь велосипеды и потом сам видишь что твои мысли неутомимо сами собой стремятся к BEM'у.
BEM сверх читаем. Бэкендщики просто слюной изливаются видя верстку согласно BEM'а ибо знают, что здесь нет костылей, подводных камней и прочего. Бери и внедряй.
Та же кнопка. Это блок с различными модификаторами и отсутствием или присутствием тех или иных элементов внутри.
По поводу читаемости и понимания BEM.
Вот есть у нас кнопка (пишу чисто классы и поясняю)
.button.button_large
Я сразу понимаю что у нас есть кнопки .button и они где-то используются, а это частный случай и к ней применён модификатор. Согласно BEM модификатор отвечает за то КАК меняется блок и элемент.
Идём дальше. Внутри я вижу типа такого
.button__icon.icon
.button__text
Я понимаю что у нас внутри есть иконка и она выделена в отдельный блок .icon и это неспроста. Значит этот блок используется на странице ещё где-то и так просто его редактировать не стоит ибо повлияет глобально.
Это элементарный пример увидя который, просто как бы открыв код HTML наугад, я получил просто море информации. И вы хотите сказать что это понижает читабельность?
А давайте я вам теперь своё видение расскажу. Вот открываю я БЭМный код и вижу ".button.button_large". И мне это вообще ничего не говорит! Есть ещё блоки с таки классом и или нет. Мне это говорит только о том что человеек делавший вёрстку использовал синтаксис БЭМ. Всё! Мне все равно придётся открывать браузер и веб-инспектор, проверять, прокликивать и т.д. Или что, по-вашему БЭМный синтаксис сразу даёт какую-то гарантию?
«Вот открываю я email с ТЗ и вижу набор кириллических символов и это мне вообще ни о чём не говорит! Мне это говорит лишь о том что мне придётся запускать скайп и обговаривать с заказчиком ВСЁ! Неужто умение читать даёт какое либо преимущество?»
Вы совершенно не понимаете BEM вот о чём это говорит. И спор в виду этого факта становится бесполезным.
table (> tbody) > tr > td
select > option
Каскадные стили и наследование — это очень круто, когда один человек может охватить всю совокупность стилей на проекте сразу и целиком — и в состоянии построить карту зависимостей, карту наследований стилей от стилей.
Если этой возможности нет — приходится:
А) тратить каждый раз время верстальщика на изучение «А от чего там у нас наследуется
div
и откуда у него взялся background-color: red
(и это не гарантия того, что новый верстальщик охватит весь проект целиком и поймет, что вон там в одном месте »сделали вот так, потому что в другом месте эдак, а комментарий писать было лень, ибо лапки, да и так все очевидно".Б) использовать подход с суффиксами, переопределяющими поведение: `-active`, `-passive`, `-foobar` etc.
Этот подход ущербен, как мне кажется, тем, что опирается на умолчания, заданные где-то, что возвращает нас к проблеме «запомни-ка иерархию стилей, бро».
Б) индивидуализировать стили — как в БЭМ или в «обычном говнокодном» CSS.
Вопрос же в конечном итоге не просто в том, как сделать красиво, а как сделать так, чтобы потом это можно было переделать.
Как-то так.
Отмечу, еще раз, что я не верстальщик с 20-и летним стажем (хотя таки да, с HTML познакомился аж в 1997 году) и не работал в крупных командах. И не использую БЭМ (хотя надо бы, наверное, но у меня лапки).
БЭМ — это про упрощение разработки для людей
Да, всё верно. Про процесс разработки с БЭМ я рассказывал тут:
https://events.yandex.ru/lib/talks/686/
Пример хорошей верстки без БЭМ это 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>
В данном стиле верстки есть много схожего с БЭМ, но при этом нет такой каши в именах классов. Это золотая середина, а БЭМ это крайность. Любая крайность — зло.
БЭМ хоть и смотрится неуклюже, со временем не превращается в говнокод.
В реальном проекте...
В реальном проекте, если вы выбираете БЭМ, то у вас тоже будут проблемы, но они будут в других местах. Верстальщик по БЭМу верит (сходство с религией), что если бы он верстал без БЭМа, то проблем было бы больше.
Вот вам пример бреда, который рождает БЭМ:
toster.ru/q/425766
Можно возразить, что всегда есть плохие верстальщики, которые всё делают неправильно. Но тогда получается, что БЭМ этим плохим верстальщикам никак не помогает, а даже наоборот.
custom__button
— custom — это блок? Или mob-full__width
— width — это элемент?Каково вам было бы во всём этом разбираться? Куча блоков с двойными и тройными именами, куча модификаторов, блоки, которые одновременно являются элементами других блоков… Это так БЭМ решает проблемы? А по-моему он решает одни проблемы и создает другие. В документации всё более-менее красиво, а на практике…
Что именно вам не понятно в этих стилях?
Тут применён адский микс при котором одна хтмл-нода это одновременно 5 бем-элементов.
Под капотом всё собирается декларативным шаблонизатором и в этом месте нет никаких проблем — вы просто не трогаете вёрстку руками, а пишите всё отдельно, и вам не нужно разбираться сразу во всём.
Мы здесь все собрались чтобы обсудить бэм который мы видим в браузерах, давайте не будем лезть в серверный бэм, там отдельные технологии.
Никто не заставляет вас делать несемантично. Это вообще не про бэм, а скорее про целесообразность.
Не готов выступать адвокатом яндекса, поэтому всё что написано ниже лишь догадки.
Подозреваю что в данном случае дополнительная семантика не так важна, если я правильно понимаю о семантике с вашей точки зрения.
Я в коде яндекса встречал элементы элементов, чего не должно быть вообще то. Возможно также здесь ничто иное как человеческий фактор
элементы элементов, чего не должно быть вообще то.
Обоснуйте.
А вы инженер или прихожанин? :-)
Разделение на блоки и элементы — не более чем костыль к CSS, позволяющий реализовать каскад на уровне компонент, а не хтмл-элементов. В правильном CSS у нас были бы селекторы вида:
.button >>> .icon
.button >>> .text
.panel >>> .close >>> .icon
И никакой БЭМ даже бы не появился. Веб компоненты должны были позволить такие штуки, но их погубили фанатики-изоляционисты.
Разделение на блоки и элементы — не более чем костыль к CSS, позволяющий реализовать каскад на уровне компонент, а не хтмл-элементов.
Селектор дочернего элемента это у вас каскад ?
В правильном CSS у нас были бы селекторы вида:
И никакой БЭМ даже бы не появился
яхз при чём тут изоляция. бэм не только про изоляцию.
Что для вас семантика? Под семантикой часто понимается не только корректное использование конкретных тегов, но и осмысленное наименование классов. Например, чем не семантичное название класса .product-list__product
?
блоки, которые одновременно являются элементами других блоков
Это вполне допустимая ситуация. Как вы иначе будете делать композицию блоков?
Не потому, что его пишут глупые люди, а потому что он:
а) ориентирован на нишу верстального фаст-фуда (я не хочу думать, я хочу фигачить тэги);
б) тянет на себе легаси-концепции из прошлого десятилетия.
Вы не верите что бутстрап это плохо?
Тогда почитайте здесь https://gist.github.com/iAdramelk/d328b73c72cab92ef95f
Там очень подробно расписана боль при работе с ним
Самый простой способ перекрасить Бутстрап — это затянуть к себе его исходники и переопределить несколько переменных. А вот через CSS что-то переопределять — и правда сложно.
css очень сложно поддерживаемый язык. и его стандартизация немного улучшает ситуацию.
Первая проблема БЭМ — он по факту абсолютно не поддерживаем. Представьте, вам дают совершенно незнакомый проект на БЭМ и… скажем, говорят «у нас на сайте используется фирменный градиент с анимацией, надо бы поменять в нём цвета и сделать его двойным». Вы открываете стилевой файл и… что делать? Открывать веб-инспектор и вручную прокликивать каждый блок, потому что:
Не имеет смысла объединять разные по типу блоки, только потому что у них, например, одинаковый цвет или размер.
В любом вменяемом css-файле, где-нибудь ближе к началу наверняка будет определение а-ля ".blue-gradient".
Из этого вытекает вторая проблема БЭМ — он абослютно не гибок. Проекты бывают разные. Где-то надо нагородить несколько сотен блоков, а где-то хватит и пары (а всё остальное графика), а где-то вообще не используются блоки. И подходить ко всей этой кухне с такой категоричностью «не использует», «не должны», «не может», «не рекомендуется». То, что Яндекс вполне успешно пропагандирует внутри своей компании эту философию, вовсе не означает что её надо бегом возводить в разряд спецификаций. В разработке важен гибкий подход и выбор подходящего инструментария для каждой конкретной задачи, а вовсе не «только БЭМ, остальное говнокод».
Понимаете, вы смотрите на это со своей кухни — когда работаете в одной команде над одними и теми же проектами несколько лет — конечно, вам нет особой нужды смотреть на подобные вещи более абстрактно. Ну так вот пусть и яндекс проповедует это как собственную внутреннюю кухню, а не как «стандарт для веба».
Разве Яндекс говорил, что БЭМ следует всегда использовать всем? Вот автор данной статьи категорично заявляет, что никто никогда не должен им пользоваться.
Да, но занимается довольно активной рекламой. Так что мне неоднократно приходилось слышать требования к вёрстке одностраничного хомяка «БЭМ, 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: специфичность — не каскад
В любом вменяемом css-файле, где-нибудь ближе к началу наверняка будет определение а-ля ".blue-gradient".
Кроме градиентов там еще могут быть тени, заливки, оформление текста и много чего еще. Найти в такой куче нужный градиент будет уже не так легко.
А еще дизайн проекта может меняться. Легко можно докатиться до такой конструкции:
.blue-bakground {
background-color: green;
}
Staticlab правильно говорит. Переиспользуемые значения выносятся в миксины и константы. Причем в любом проекте, неважно, БЭМ там или нет.
Фактически сейчас css, как и html, превратился в эдакий машинный язык, который люди уже не читают и на котором не пишут. Мы давно уже используем другие языки, результатом работы которых является css или html, а с голым css или html сейчас уже почти никто не работает.
Думаю, что через несколько
А пока как-нибудь так, как-нибудь так.
БЭМ не костыльЯ воспринимаю это так: БЭМ решает проблему, которая возникает из-за того, что css плохо подходит, т.к. на сегодняшний день устарел.
Такой подход к оформлению хорош для оформления статей и книг, но плохо подходит для оформления веб-приложений.
Т.е. сегодня css используется именно для современных веб-приложений, но плохо для этого подходит. Значит правильным решением будет изменить css, а не придумывать способ обойти проблему.
А так как БЭМ является способом обойти проблему css, не меняя css и не устраняя эту проблему, то именно поэтому я считаю, что БЭМ — костыль.
в современных фреймворках он уже и не нужен
У вас есть сторонний компонент "button" в стороннем компоненте "calendar" в стороннем компоненте "datepicker". Вы пишете компонент "daterangepicker" и вам надо по особому стилизовать ту самую кнопку "selected_date" в календаре. Причём по разному в обоих пикерах. Как "современные фреймворки" решают эту проблему?
Вы пишете компонент "daterangepicker" и вам надо по особому стилизовать ту самую кнопку "selected_date" в календаре. Причём по разному в обоих пикерах. Как "современные фреймворки" решают эту проблему?
Если вам хочется стилизовать сторонний компонент — используйте публичное апи этого компонента. А за попытки править стили компонентов внешним цссом следует руки отрывать.
То есть, если дизайнер хочет градиентик на какой-то конкретной кнопочке, то нужно либо оторвать ему руки, либо форкать и патчить все три сторонних компонента, либо велосипедить свой датепикер с нуля? Но ни в коем случае не писать что-то типа:
[my_daterange_from_calendar_selected] { /* градиентик один */ }
[my_daterange_to_calendar_selected] { /* градиентик другой */ }
Я правильно вас понял?
Я правильно вас понял?
Правильно. Ведь в следующем апдейте ваш [my_daterange_from_calendar_selected] может совершенно незаметно для вас сменить название без нарушения обратной совместимости, и ваша верстка превратится в тыкву.
Естественно, на практике, когда ну совсем надо, использование недокументированного поведения, почерпнутого из потрохов используемой библиотеки, может быть допустимо, но это именно крайняя мера, требующая отдельного обсуждения и согласования с явным обоснованием допустимости в конкретном случае, с четким пониманием того, что вы закладываете бомбу замедленного действия.
Но нормой или чем-то к ней близким это быть не может.
Вы уж определитесь, либо без нарушения совместимости, либо тыква. Но знаете, после мажорного апдейта проверить зависимый компонент и поправить классы, если вдруг, — несоизмеримо проще, чем поддерживать 3 форка и уж тем более собственную реализацию.
Вы уж определитесь, либо без нарушения совместимости, либо тыква.
Нарушение обратной совместимости — это изменение публичного апи. Изменение деталей реализации (к каковым относятся верстка и стили) публичное апи не меняет, по-этому эти детали могут меняться как угодно в любом минорном апдейте. И вы сами себе злобный буратина что раскопали потроха реализации и теперь на них завязались, в результате чего у вас тыква.
Но знаете, после мажорного апдейта проверить зависимый компонент и поправить классы, если вдруг, — несоизмеримо проще, чем поддерживать 3 форка и уж тем более собственную реализацию.
Ну вы не забывайте, что это все еще надо обсудить, согласовать…
А можно просто сделать форк (одну кнопку нажать) и оформить возможности кастомизации требуемых компонент по-человечески, вместо того, чтобы лепить говнокод.
Изменение деталей реализации (к каковым относятся верстка и стили) публичное апи не меняет, по-этому эти детали могут меняться как угодно в любом минорном апдейте.
Всё, что видит пользователь — публично по определению. Вы можете сколько угодно фантазировать про инкапсуляцию, но если кнопка стала в 2 раза больше или из квадратной стала круглой без изменения JS API — дизайн будет сломан.
Ну вы не забывайте, что это все еще надо обсудить, согласовать…
Тут нечего обсуждать и согласовывать. Есть типичная задача — есть типичное решение. А вот разработку велосипеда надо и обсуждать и согласовывать. Также как и поддержку форков.
А можно просто сделать форк (одну кнопку нажать) и оформить возможности кастомизации требуемых компонент по-человечески, вместо того, чтобы лепить говнокод.
В первом форке переключить зависимость на второй форк. Во втором на третий. Потом надо в первом форке изменить апи, добавив прокидывание дополнительного параметра во второй. Во втором — в третий. В третьем реализовать добавление его в нужное место. И повторить эти действия для каждого элемента, который захочет кастомизировать дизайнер. Примечательно, что имена параметров вскоре выродятся в тот же "путь до нужной кишки" вида "from_calendar_selected". Потом вам нужно следить за апдейтами в апстриме, периодически накатывать их в каждый форк, каждый раз разрешая одни и те же конфликты и переключая каждый форк на новые версии зависимостей. Если вы ещё и решите использовать не git submodules, а локальный npm-repo, то к этому добавится ещё и обновление версий, изменение имён зависимостей и публикация всех этих зависимостей в npm-repo.
Всё, что видит пользователь — публично по определению.
Так пользователь не видит CSS, он видит результат его работы. В компоненте поменяли название стиля, компонента как выглядела так и выглядит, она не изменилась. Сломался ваш кастомный css, делая который вы использовали приватные детали реализации.
Тут нечего обсуждать и согласовывать. Есть типичная задача — есть типичное решение.
Так использование костылей, которые закладывают бомбу под ваш проект — это как раз нетипичное решение. Естественно, его требуется обсудить и согласовать.
А вот разработку велосипеда надо и обсуждать и согласовывать. Также как и поддержку форков.
А вот форк — решение как раз типичное, у такого решения нет никаких проблем.
Потом вам нужно следить за апдейтами в апстриме, периодически накатывать их в каждый форк, каждый раз разрешая одни и те же конфликты и переключая каждый форк на новые версии зависимостей.
Вы же апдейты ставить не собираетесь? А если собираетесь — все то же самое вам придется делать и в случае предлагаемых вами костылей, только сильно сложнее.
Вы сейчас топите за нарушение инкапсуляции, это просто не имеет смысла. Общая практика длиной в десятки лет показывает, что бесконтрольное нарушение инкапсуляции в итоге приводит к значительно большим проблемам, чем адекватные решения.
вы использовали приватные детали реализации
Это точка расширения, а не приватные детали. И просто так точки расширения не переименовываются.
Так использование костылей, которые закладывают бомбу под ваш проект — это как раз нетипичное решение.
Думаю автору фреймворка виднее что в нём является типичным решением, а что — нет. А не человеку, который не потрудился разобраться в предлагаемом подходе. Уже третий год я разрабатываю компоненты $mol, и веду разработки на их основе, где применены те же идеи. За это время подход показал себя более чем положительно и никаких "бомб" обнаружено не было. Потрудитесь, пожалуйста, разобраться или не делайте громких заявлений о том, что не пробовали.
А вот форк — решение как раз типичное, у такого решения нет никаких проблем.
На поддержку форков для каждого проекта вы потратите в 10 раз больше времени, чем на поддержку одного селектора, даже если тот будет ломаться при каждом обновлении (что далеко не так). Если для вас это не проблема, то на этом нашу дискуссию можно закрывать. Запилите 10 проектов, для каждого из них по 10 форков сторонних компонент. А когда устанете от этой православной рутины — буду ждать вашего возвращения и описания впечатлений.
А если собираетесь — все то же самое вам придется делать и в случае предлагаемых вами костылей, только сильно сложнее.
Что именно "всё то же самое"? Ничего из перечисленного делать не придётся.
Вы сейчас топите за нарушение инкапсуляции
За отсутствие сокрытия. Сокрытие капитально снижает гибкость. Горячо любимые вами форки — это ведь тоже ни что иное как "открытие" стороннего кода. Тот же пресловутый "паблик морозов", но на уровне репозиториев, а не классов. Благами инкапсуляции можно пользоваться и не закрывая компоненты от расширения — тогда не надо будет их мучительно открывать с форками, обсужениями и прочими замедлителями разработки.
На поддержку форков для каждого проекта вы потратите в 10 раз больше времени
Создаем пулл-реквест, ждем пока его вмержат. Если не хотят мержить, используем своё. Замержили и зарелизили? Используем дальше)
Запилите 10 проектов, для каждого из них по 10 форков сторонних компонент.
Именно поэтому вы запилили $mol и активно его везде форсите?
$mol я запилил для быстрой и качественной разработки. Упоминаю я его как живой пример реализации тех идей, о которых вам говорю. Будете ли вы использовать $mol или нет — мне по барабану.
Это точка расширения, а не приватные детали. И просто так точки расширения не переименовываются.
Точкой расширения является то, что автор явно указал, как точку расширения.
Уже третий год я разрабатываю компоненты $mol, и веду разработки на их основе, где применены те же идеи.
И при чем тут ваш mol$ вообще, если о нем речи и не шло?
За отсутствие сокрытия.
То есть, за нарушение инкапсуляции.
Сокрытие капитально снижает гибкость.
Так если вы хотите предоставить клиенту возможность стилизации вашего компонента — то и дайте ему возможность прокинуть конфиг в нужное место через пропсы, вместо того, чтобы говнокодить.
Благами инкапсуляции можно пользоваться и не закрывая компоненты от расширения — тогда не надо будет их мучительно открывать с форками, обсужениями и прочими замедлителями разработки.
Естественно, если автор библиотеки позаботился о расширении — то никаких проблем и нет, чего тогда обсуждать?
Вы сейчас находитесь в плену своих предубеждений. Попробуйте представить мир, где автору библиотеки, чтобы обеспечить расширяемость, не надо вываливать наружу конфиг из 100500 параметров, хитро влияющих друг на друга, и которые хоть и покрывают 80% кастомизаций, но которых не хватает для удовлетворения всех требований 80% приложений.
не надо вываливать наружу конфиг из 100500 параметров,
Зачем? Десяток параметров покроет чуть менее чем 100% кейзов.
несколько цветов темы, размеры, тип календарика, наличие тех или иных саб-контролов. с-но, для календарика даже десятка не набарется.
Что такое «тип»? Как добавить скругления кнопочкам? Как праздничные дни выделить пурпурным? Как выбор года переместить вниз? Как стрелки «вправо-влево» для месяца сделать «вверх-вниз»? Как привязать всплывающее окно к дням? Как изменить начало недели? Как убрать выходные дни? Как выделить диапазон дней? Как вывести текст между тулбаром и днями? Как изменить названия дней недели?
У вас половина вопросов к внешнему виду вообще никак не относятся и цссом не решаются.
Нет не всё. Вернее не всё из того, что видит пользователь входит в публичный контракт стороннего компонента. Банальный список поддерживаемых компонентом бразеров, который немного уже чем для вашего приложения, например вообще не включает IE. А вам последний IE нужен, и вы переопределили у себя один класс, который нашли в инспекторе и он так же выглядит и ведёт себя в последнем IE как и в поддерживаемых. Потом вышел патч апдейт у вас всё сломалось, потому что авторы в процессе фикса какого-то мелкого бага в поддерживаемых браузерах перенесли этот класс уровнем выше или ниже, на соседа или вообще убрали. И у вас всё сломалось даже в поддерживаемых — убираете свой класс — в поддерживаемых всё нормально, в IE сломано. И кто, по вашему, виноват, что у вас сломалось при патч-апдейте сначала везде, а потом только в IE?
Далее у вас идёт вымученный пример, основанный на том, что классы расставляются как попало, а потом на них через каскад навешиваются стили, что весьма хрупко. Однако присмотритесь к моим примерам. Там нет каскада. Там автоматически генерируемые на основе семантики элементов классы, расширяющие идею БЭМ. Эти классы не меняются при изменениях в вёрстке или стилях.
И пример не вымученный, если в документации компонента вообще ничего не сказано про кастомизацию через определение стилей, то вы не должны рассчитывать, что она вообще будет работать после патч-апдейта, даже если вам это адалось до него.
Такие вещи говорятся в документации фреймворка — как кастомизировать компоненты на его основе. Если в вашем фреймворке не продуман этот вопрос — ну вот такой фреймворк вы выбрали, не рассчитанный на активное переиспользование кода от разных разработчиков.
Такие вещи говорятся в документации фреймворка — как кастомизировать компоненты на его основе.
Вот именно. И если в документации написана фига — значит, имена классов в публичный интерфейс не входят.
Разумеется. Давайте я вам напомню о чём наша дискуссия: https://habr.com/post/422537/#comment_19087403
Озвучена проблема. Современные фреймворки эту проблему не решают. БЭМ эту проблему решить может, если его интегрировать во фреймворк. Приведён пример фреймворка будущего — $mol, где с помощью БЭМ-а эта проблема решена. О чём тут можно спорить? Что попытка извне навеситься на scoped стили либо невозможна, либо порождает очень хрупкие селекторы — очевидно. Мой тезис в том, что развивать инструментарий надо в сторону неймспейсов и гибкости в решении задач, а не в сторону изоляции и костылей с кастомизацией. А кастомизация сторонних компонент — наитипичнейшая задача.
Нет, не я, а вы упомянули про него в «из квадратной стала круглой без изменения JS API — дизайн будет сломан». Для меня контракт компонента более широкое понятие чем его JS API.
> И любые изменения в стилях и вёрстке являются изменением публичного интерфейса. Иначе они были бы попросту бессмысленными.
Нет. Если стили, разметка и вёрстка в целом не являются частью публичного контракта (читай — не документированы), то разработчики вправе их менять как деталь реализации в каждом патч-релизе. Ну это как приватные свойства и методы в ООП — от их, например, переименования ничего не должно ломаться.
А с какого перепугу дизайнер хочет градиентик на какой-то конкретной сторонней кнопочке?
Которая показывается в нашем приложении, вся визуализация которого находится в зоне ответственности дизайнера.
можно договорится обновить гайды, и изменения внесут в этот компонент
Расскажите ка Гуглу про ваши гайды. Поделитесь потом впечатлениями.
Не правильно. Хорошие компоненты должны уметь подмерживать стили пришедшие свыше. В БЭМ это называется миксом.
А если ваш сторонний компонент не умеет этого то штош… кроме хаков нет никакого способа кастомизировать.
Ок, критикуя — предлагай.
Предложите решение.
Просмотрел комментарии, раз здесь столько специалистов по БЭМ — воспользуюсь случаем и задам вопрос :)
Современный 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
который явно не является блоком. Как БЭМ предлагает работать с этими ситуациями?
но если тема меняется динамически — придётся прописывать этот модификатор всем элементам в 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
Использование БЭМ не противоречит применению каскада в каких-то конкретных местах. Он больше о том, что необходимо изолировать именно разные блоки друг от друга.
Индустрия ходит кругами. Сначала придумывают как передать бит информации, потом делают протокол для передачи потока битов, потом канал делают двунаправленым, потом на базе двунаправленного канала строят протокол который позволяет передать бит информации…
Индустрия ходит кругами. Сначала придумывают как отобразить информацию для пользователя. Создают библиотеки. Потом создают язык, с помощью которого можно декларативно описывать пользовательский интерфейс. Потом для этого языка придумывают библиотеки, для них придумывают свой язык.
Индустрия ходит кругами…
Первый, второй пункт про удлиннение имён классов
В третьем пункте автор не понял что такое семантическое наименование
В четвёртом пункте автор не наступал ещё на грабли перебивания специфичности.
В пятом пункте автор продолжает показывать своё невежество, и неумение в крупные поректы вертающиеся независимыми блоками.
Самый основной из них — это длинные и плохо читаемые названия классов. Нет, если у разработчика все взаимодействие с кодом ограничивается только версткой, то у него все хорошо. Есть 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
Зашквар какой-то ))) вы простите но такой набор классов на одном элементе это скорее антипаттерн чем поддерживаемая вёрстка.
Подозреваю, что то что вы называете каскадом на самом деле называется дочерним селектором, и он не запрещается в бэм, но рекомендуется не злоупотреблять.
Не совсем понял что имеется в виду под решением проблемы). В бэм не так много проблем чтобы их нужно было
BEM удобен в больших командах, где есть несколько не очень опытных верстальщиков и требуется чтобы они могли хоть как-то вместе работать. Естественно, что вопрос насколько удобно с этой версткой работать в дальнейшем здесь не стоит.
где есть несколько не очень опытных верстальщиков
несколько опытных верстальщиков тоже в конечном счете выработают какую-то конвенцию именования. Иногда это может оказаться БЭМ.
Вы так говорите будто бы в бэм есть только нэйминг классов и никаких других проблем бэм не решает. И будто бы в этом есть какая-то проблема.
Есть и другие трактовки, но мы же в контексте этой статьи говорим.
БЭМ помогает организовать процессы разработки.
Представьте что у вас 10 разработчиков, и крупный проект. Как объяснить им что хорошо, а что не очень. Что сделать чтобы проект не пришлось переписывать с нуля через год потому-что новые разработчики скрипят зубами и сроками при реализации фитч/исправлений, а старые разработчики давно уволились ?)
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 дружит никак.
Но.
Посмотрите на тот же bootstrap.
Никаким там бэмом и не пахнет, однако вложенные элементы часто носят в названии имя родительского блока, типа .form-control, .form-group и тд, только вот использовать их можно легко как утилиту с миксованием классов у родителя.
Что касается гибкости использования — тут сложно, согласен, вместо того чтобы гуглить по доке бутстрапа как у них там устроен тот или иной интерфейс конкретного компонента, проще ведь написать свой, но речь шла о миксовании подходов, которые нивелируют псевдо-минусы бема, описанные топикстартером. Я так работаю уже достаточно кол-во времени, и не вижу смысла нагружать себя теми проблемами, которые приносит с собою использование бэм для мега-проектов. Автор явно не из тех, который опробовал предложенный мною микс и остался при своём мнении. Насчёт копипаста из проекта в проект, возьмите тот же bootstrap — у него есть понятие «утилиты» — что мешает вам в рамках своей сборке запилить помимо компонентов ещё и утилиты которые будут выполнять узкий набор задач и решать типичные задачи у бэм компонентов? У меня например в проекте такими утилитами являются утилиты размера шрифтов, цветов фона и текста, отступов, дисплей-утилиты, и т.д. Это лишает меня потребности в создании абстрактного класса у которого единственная цель — задание цвета тексту или размера шрифта типовому заголовку.
А что касается переиспользования — никто Вам не запрещает написать мини-документацию к своей сборке с перечнем всех утилит, и расширять её из проект в проект.
Утилитарные классы же раздувают html, однако позволяют легко конструировать кастомные интерфейсы путём миксования классов, не только фронтовиком, но и бекендером.
Но тут, как говорится, на вкус и цвет. Всё зависит от проекта.
Когда, как я, верстаешь по большей части лендосы, от бэма никакого толку особо, отсилы 1-2 секции на ленде могут повторяться но иметь чуть другой вид.
А вот для single-dev разработки из проекта в проект, при учёте что в команде один и тот же дизайнер, который рисует интерфейсы из ранних наработок, добавляя им иные вариации — вот тут мой подход кажется аргументированным. А когда, иногда, дают верстать многостраничники с «похожими» компонентами, которых различают ну просто нереально кастомными отступами (как вариант), то не использовать утилитарные классы отступов и лепить для каждой вариации свой класс (причём ещё надо немало подумать, как же мы его назовём, привязывать ли название к контексту, без опасения что точно такие же отступы будут у секции с другим контекстом) — как минимум неразумно.
ИМХО.
У меня мультилендинг предположим.
В среднем у каждой второй секции отступы сверху и снизу по 70 пкс (60пкс на планшетах, 50 пкс на мобилках). У таких секций есть заголовок размер шрифта которого соответствует второго уровня заголовку (исходя из градаций разновидностей размеров в дизайне в целом) — 40пкс (32 пкс на планшетах, 25пкс на мобилках).
Ваши действия?
Опишите в рамках конкретной тестовой секции куда вы запихнёте отступы, куда запихнете размеры заголовка.
Затем отпишу я.
Вместо этого есть вот такое — acss.io/guides/atomizer.html
эта штука сканирует проект и генерирует цсс-файл только с используемыми классами
Кнопка это маленький компонент с достаточно объёмным размахов в кол-ве вариаций, поэтому у неё модификаторов может быть достаточно много.
Времени вы потратите на интеграцию моего компонента кнопки не более чем 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
Не обязательно использовать длиннющие модификаторы для каждого отдельного блока, БЭМ же не запрещает это.
Когда нужно сделать инверсию у блока, почему-то многие создают дохера модификаторов для элементов блока, когда можно навесить один модификатор блоку. (из-за этого верстка в итоге становится нечитабельной, а потом все говорят, что БЭМ — говно)
Все в документации описано.
А если вы, например, захотите создать класс ".text-danger" и использовать его везде, где нужен определенный цвет текста, то это будет не модификатор, как говорит нам логика, а блок или микс, потому что (цитата) «модификатор не может использоваться в отрыве от модифицируемого блока или элемента». Поправьте, если я не прав.
Это как посмотреть. Если рассматривать аналогию с ЯП, то класс ".text-danger" можно сравнить со статическим методом или константой. А когда мы пишем стиль для тега «button», это уже похоже на глобальную переменную. Странно когда в SASS может быть переменная "$text-error", а в CSS такого класса быть не может. Где логика?
В случае глобальных классов-модификаторов может получиться такая конструкция
В нормальной верстке такой конструкции получиться не может. Как я уже писал выше, из всего этого получается, что БЭМ это для тех кому пофигу что получается на выходе, главное чтобы быстро. Херак-херак и в продакшен.
В нормальной верстке такой конструкции получиться не может.
Приведите пример нормальной верстки, в которой такой конструкции не будет? А то тут все, кто против БЭМа, не могут привести адекватных контраргументов.
Если понадобится добавить на страницу другой компонент, содержащий пункты, то стили для нового item повлияют на пункты из существующего навигационного меню. Или предположим, что в навигационном меню нужно изменить правила класса .active. По имени непонятно, какие компоненты его используют. Может оказаться, что на другой странице существует...
Автор взял самый плохой пример (хороший я приводил выше — Bootstrap). Что это как не манипуляция?
Автор взял самый плохой пример
Автор взял самый очевидный пример. Чтобы разница между «плохой» и «хорошей» вёрсткой была более очевидна.
В каждом большом темплейте есть мелкие элементы, как кнопки, дропдауны, тайтлы, субтайтлы, секции и т.д. Но в БЭМе у вас их нету, так как любой элемент без блока использовать тоже запрещено.
Открою пару секретов:
1) Кнопки практически обязаны быть блоками;
2) То, что может использоваться повторно, надо делать блоком. БЭМ не обязывает все дропдауны делать элементами. Никто не говорит, что у вас не может быть базовых классов .title, .btn и т.д. Наоборот — они должны быть.
плавающие в тексте линки стилизованны под кнопки (обычно с глаголом внутри типа «Register») — стилизованные для поддержки метафоры «а тут вы перейдете из текста, на серьезную форму» — не могут быть блоками.
Может напишете им пару слов в письме, а то вдруг они не в курсе? ))
Вы считаете что у хабра скорость выката фитч зависит от выбранной методологии вёрстки? )))
Какой методологии вы придерживаетесь? или какую посоветуете и почему?
BEM'a не должно существовать