Comments 64
Например, так делать не следует: .redBox
Но почему? Ответ «А прост.:)» не катит, извините.
rel="js-site-navigation"
Вообще-то в отличие от data-*, у rel есть вполне определенное семантическое значение (даже можно сказать что и не одно). Что если мне надо будет этим способом выбрать из DOM хотя бы один из тех самых rel="stylesheet"
?
Использовать rel — почти отстой, но если честно, кроме основных линков и микроразметки он нигде и не используется.
Как по мне, .calculatorForm-field_required
(или даже — о кощунство! — .calculatorForm-field.required
) вполне достаточно.
Я согласен, что это вкусовщина, просто мне не нравится, что некоторая конкретная вкусовщина выдается за стандарт и божественное откровение (при всем уважении к авторам БЭМ).
Не в любой, не обобщайте. У нас, например, используется такое именование: my_calculator_form_field_required
. И с выделением ни в каком редакторе/вьювере нет проблем. И рефакторинг элементарен — просто заменяем подстроку по всем файлам. И не важно js это или css или даже json. Никакие js-
префиксы не нужны.
someObject.someName
и в html:
.someName
То по поиску-замене может получиться что-то плохое. Хотя современные IDE умею в исключение файлов из выборки, но тогда вы можете пропустить селектор. Да и искать его бдет проще по шаверма-кейсу, чем по camel.
Это так, из личного представления о вопросе. Раньше всегда кэмел любил везде.
Или есть минуса в этой схеме?
Не понимаю этой истерии «Так LANG_NAME же caseinsencitive, все заглючит, мы все умрем!!!111»
Если в одном проекте есть .redBox и .redbox — уволить верстальщика.
А с кашей из redBox/red-box/red_box работать значительно геморройнее, чем по всему стеку технологий придерживаться единой нотации и нормальных названий переменных.
Во-вторых, печатать конструкции вроде
.stick-man__feet
не самое приятное. И выделять их в тексте дабл кликом тоже.В третьих, названия классов из 4-5 слов
stick-man__head--small
штука тоже сомнительная. Половина разметки потом состоит из классов. Да и селекторы в css потом трёхэтажные
.big-city .baker-street-avenue .stick-man__head--small
Цель подобного использования атрибута rel заключается в том, чтобы указать на то, что элемент используется в JavaScript.А почему вместо этого не добавлять таким элементам просто класс «js»?
Да, визуально немного громоздко. Я когда впервые с этим столкнулся, тоже испытывал эмоциональное неприятие. Но практика показывает, что это более чем разумная плата за однозначность и надежность. Использование слишком коротких и «красивых» классов рано или поздно приводит к каким-то коллизиям, если они все находятся в одном скоупе (то есть не учитывая вариант некоторых js-фреймворков, которые эмулируют css-scopes через атрибуты). Особенно, если над кодом работают разные люди. Просто неизбежно, вопрос лишь времени.
В SCSS я использовал такие варианты:
.block-name {
&__element-1 {}
&__element-2 {
&--modification{}
}
}
В html всё понятно, что придется печатать, хотя не встречал проблем с этим.
Для команды взяли за правило писать в полную строку классы, чтобы потом найти можно было без проблем.
Никому не нужно искать стили глобально по полному имени класса, потому что они лежат в одном файле (соотв. блоку), в совершенно понятной папке и с совершенно понятным именем (имя блока).
Если у вас это не так — у вас проблема в чем-то другом.
Во всех остальных случаях (хотя даже и в вашем идеальном мире) я не будут доверять никому и выполню полнотекстовый поиск имени класса по всей кодовой базе, включая серверный код, прежде чем его удалить или изменить. И без префикса .b- мне придется разгребать сотни unrelated найденных результатов, и хорошо еще если не тысячи.
Если у вас это не так — у вас проблема в чем-то другом.
Миллион разных вещей может произойти и на мой взгляд разработчик ответственен за обеспечение как можно большей устойчивости к изменениям (вандализму) у кодовой базы. Без префиксов у имен классов единственный джуниор или сеньер с вашей attitude может все вашу красоту развалить в быстрые сроки и прибрать будет за ними в разы более тяжко.
Есть и другие аргументы за наличие префиксов, куда менее простые для описания и убеждения, поэтому если вас (или кого-то другого) это не убедило, то мне их будет бестолку приводить и распыляться, всего доброго.
Некоторые разработчики используют атрибуты data для организации работы с элементами DOM из JavaScript. Однако, это неправильно.
Зачем элементу хранить json? И гдетогда хранить информацию что toggle=«true or false»?
Могу ответить на первый вопрос: когда сервер рендерит разметку, а JS её потом оживляет, ему надо откуда-то получать данные. Чтобы не бегать AJAX'ом на сервер и не вытаскивать данные по клочкам из DOM-дерева, кладут их в data-*.
DOM — тормозная штука даже для разметки, тащить туда данные(когда такой необходимости нет) — это за гранью понимания.
Советы от Твиттера в ui/ux — это даже не смешно. Поражает, что компания умеет делать годные инструменты(спасибо за bootstrap), но собственный главный продукт — полный технологический отстой и собрание всех антишаблонов в одном месте.
Ну когда как, например, если вы продаете разноцветных котят, то логично что некоторые будут .kitten__pink, другие .kitten_orange и так далее.
Мы не продаем синих и зеленых котят, только розовых и оранжевых. От цветовой схемы сайта цвет котят не зависит.
один большой минус CSS: его очень сложно поддерживать.
Считаю что за счёт самого определения CSS, стили как раз таки и не сложно поддерживать по сравнению с другими языками/абстракциями. Благодаря каскадности и современным браузерным отладчикам — всё что угодно можно локализовать (найти), переопределить, выкинуть или переписать. Но для этого действительно нужно хорошо ориентироваться в css.
P.S. Допускаю, что просто не работал с по настоящему древним проектом с огромной простынёй «плохих стилей».
Поддерживать хороший css легко, нет, легчайшее занятие в вашей жизни. Однако одного css в вакууме для того чтобы сделать его легчайшим будет недостаточно. Необходимо будет и верстать определенным образом, и из js определенным образом взаимодействовать с DOM, и шаблонизацию применять определенным образом (серверную, клиентскую, любую). При этом все вот это будет влиять и на организацию самого css. Способ написания легчайшего для поддержки CSS в React-проекте будет отличаться от его же написания в jQuery одностраничнике или огромном легаси jQuery-монстре.
Я могу дать некоторые универсальные советы, за не следование которым я бы отрывал руки, но следовать им или нет уже дело каждого конкретного человека (равно как и читать их).
0. Прежде всего более-менее следовать тем ограничениям по связям стилей между блоками что есть в БЭМ.
0.1. Изолировать классы и стили разных блоков, у которых разный смысл, друг от друга.
0.2. Лучше повторить три четыре раза почти те же самые стили для разных по смыслу или способу работы блоков, чем лепить один блок-монстр. При этом монстром его сделает не размер, а слишком разное использование в разных местах.
0.3. Реально переиспользуемые маленькие блоки (такие как «кнопка») делать настолько понятным и прозрачными, насколько возможно. Вообще уделять особое внимание реально переиспользуемым вещам. Еще не пытаться делать переиспользуемыми не особо подходящие для этого блоки.
1. Всегда всем классам нужно добавлять префикс. Например b-, или несколько префиксов, например, l- (layout), u- (utility), g- (global), whatever else. Главное чтобы при полнотекстовом поиске по всему коду проекта, включая весь серверный код, не находилось бы ничего или почти ничего кроме непосредственно использования искомого класса. Нет никакого оправдания не использованию префиксов. Никакого. Такого человека просто сразу в утиль, либо если его жалко немного, то в говнолегаси без префиксов на год, пусть потом сообщит, нашел ли он там хоть один аргумент в пользу отсутствия префиксов.
2. Не использовать такой маразм как js- классы.
3. Не собирать имена классов в scss/less/etc. за исключением модификаторов и псевдоселекторов. Не собирать имена классов в JS и шаблонизаторах, за теми же исключениями.
4. Выбрать порядок свойств в правилах и следовать ему. Выбрать нормальный порядок, с группами свойств, отступами между ними. Следовать ему.
5. media-запросы писать прямо возле стилей элемента. НЕ выносить кучу стилей от разных элементов в 1 media-запрос. Лень повторять media-запрос 50 раз? Вынеси пиксельные значения в переменную или весь запрос в миксин.
6. Лень печатать 3-4 слова в одном имени класса? О**ел? Печатай столько, сколько требуется, чтобы понять что это за элемент и чтобы не гадать потом за тобой что ты там имел в виду. Если для этого требуется 10 слов, то что-то значит пошло где-то не так, и не в css, а в совокупности всего. Если требуется 7 слов, то ничего страшного, попечатаешь. Не сломаешься. А то ишь что, печатать ему лень, зато потом разбирайся несколько часов в тотально бессмысленном наборе классов из двух-трех слов, которые не характеризуют того что делает или чем является элемент. Сэкономишь пять минут в день на печатании, потеряешь уже в тот же день на воспоминаниях того что это за элементы, что они делают и какие у них между собой связи.
7. Не использовать 2 пробела, это нечитаемый рак мозга. Единственное оправдание, это если 2 пробела являются требованием работодателя по той или иной причине (есть несколько валидных причин, на мой взгляд крайне редких)
Еще было бы неплохо, но уже тяжело требовать такое конечно:
5. Соблюдать принцип единой ответственности насколько возможно, лучше добавить пару div'ов с понятными именами и единой ответственностью в стилях, чем мешать все стили в одну кучу на одном и том же элементе.
6. Тут же и вдобавок к предыдущему — не делать служебных div'ов, которые нужны только для верстки, и которые бы не имели четкого смыслового содержания. А если и требуются таковые, то выделять их настолько сильно, насколько возможно. Именованием, комментариями, отступами, чем угодно.
7. И еще пара вещей, на мой взгляд, необходимых, но и со своим минусом.
7.1. Ставить закрывающую скобку в том же столбце что и свойства.
7.2. Вот как-то вот так вот писать css/scss, с отступами, повторяющими структуру элементов в html:
.b-button {
// .. properties here
}
.b-button__content {
// .. properties
}
.b-button__icon {
// ..
&--left {
}
&--right {
}
}
.b-button__text {
// ..
}
Да, приходится следить за соответствием отступов в css при изменениях в структуре html, это один из минусов. Но сразу видно есть ли у блока адекватная структура или это бессмысленный каша с бессмысленно раскиданной версткой, классами и стилями, что на мой взгляд совершенно огромнейший плюс.
В итоге менять именно что структуру у блока не приходится почти никогда, а когда приходится, то это в основном из-за реально изменившихся требований к работе блока, а не по каким-то техническим причинам. Да и расширение функционала блока происходит куда легче из-за наличия смысла в его структуре.
Люди, у которых из аргументов тяжесть что-то в редакторе напечатать, отступы проставить или мышкой у которых что-то не выделяется, или идут в мануалы своего редактора или известно куда.
Что-то как-то слишком радикально все у вас...
Если .b-button
без проблем находится полнотекстовым поиском по проекту — то зачем искать отдельно .b-button__content
?
Мы же пишем нормальный (s)css вроде бы? В таком случае у нас .b-button__content
всегда будет рядом с .b-button
и его можно будет там найти поискав .b-button
!
А если теперь поменять местами дефис и подчеркивание, чтобы было .b_button--content
— то те самые редакторы которые раньше нужно было отдельно настраивать, будут уже помогать: выделять мышкой ровно первую часть (b_button
) для поиска.
Таким образом, ваше третье правило становится ненужным — и без него все успешно ищется.
Есть несколько проблем с собиранием классов (не считая сборку модификаторов и псевдоселекторов):
1. Поиск любого класса превращается в квест вместо нажатия сочетания клавиш для поиска, особенно если имя элемента начинает состоять хотя бы из трех слов, не считая имени блока (А три слова это нормально, и пять нормально). Глазами найти тоже становится значительно тяжелее, и думаю это достаточно объективное суждение, не так ли? Начиная примерно от первого же уровня собирания, стили превращаются все в более и более запутанные лабиринты и головоломки, вместо инструмента веб-разработки. Кому-то может это интересно, не спорю. Куда круче редактировать кашу из спец-символов вместо простого кода, человек начинает выглядеть прямо как кулцхакер, самооценка повышает, уволить становится его сложнее и т.д.
2. Становится невыполнимым требование 7.2 структуры css/scss-кода повторять html-структуру, даже в приблизительной интерпретации. Просто напросто deal breaker лично для меня.
3. Даже без требования 7.2 структура scss-кода начинает диктоваться словами в имени классов, что либо не совпадает совсем со смысловой нагрузкой на конкретные классы и с html-структурой, либо накладывает жесточайшие и неоправданные ограничения на именование классов. А плохие имена классов это, очевидно, очень плохо по всем фронтам.
4. И из совсем реальной жизни: плохо (или даже просто не супер хорошо) написанный код с собиранием классов в ~десять раз хуже плохого css-кода без собирания классов.
5. Код со сборкой классов становится адом для поддержки, да даже не адом, он просто не поддерживается. Любому человеку, не пишущему такой код в течение хотя бы нескольких месяцев, проще взять скомпилированную версию scss/less-файла, заменить исходник именно на нее, и с ним уже работать.
Я могу представить собирание имен классов хоть сколько-нибудь оправданным (not really) только в случае если вообще весь стек проекта завязан на БЭМ по всем направлениям — верстка, стили, скрипты, системы сборки, инфраструктура, линтеры, etc… Иными словами если это внутренний проект Яндекса.
К сожалению, мы живем не в идеальном мире, и если над проектом работают уже два человека, то риск того что код не будет идеальным начинает приближаться к ста процентам. Но это лирика.
Так на то правила и существуют.
Поиск любого класса превращается в квест вместо нажатия сочетания клавиш для поиска, особенно если имя элемента начинает состоять хотя бы из трех слов, не считая имени блока
Никакого квеста: ищем имя блока, а дальше все видно… Или у вас описания блоков по три экрана?
Даже без требования 7.2 структура scss-кода начинает диктоваться словами в имени классов, что либо не совпадает совсем со смысловой нагрузкой на конкретные классы и с html-структурой, либо накладывает жесточайшие и неоправданные ограничения на именование классов.
Я точно так же могу обозвать жесточайшим и неоправданным ваше требование чтобы структура css совпадала со структурой html.
И из совсем реальной жизни: плохо (или даже просто не супер хорошо) написанный код с собиранием классов в ~десять раз хуже плохого css-кода без собирания классов.
Чем измеряли?
Любому человеку, ...
Почему вы так уверены?
Будут ли у вас какие-нибудь аргументы кроме вашего мнения?
PS
Я могу представить собирание имен классов хоть сколько-нибудь оправданным (not really) только в случае если вообще весь стек проекта завязан на БЭМ по всем направлениям
Так вы, кажется, именно про БЭМ и говорили. В других методологиях проблем (например, в SMACSS) сложносоставных имен отродясь не было, и собирать попросту нечего.
Никакого квеста: ищем имя блока, а дальше все видно… Или у вас описания блоков по три экрана?
У вас нет блоков больше трех экранов? В идеальном мире живете. Но даже в этом случае хватает и одного экрана собранных имен классов чтобы это было именно что развлечение себя головоломками вместо работы и облегчения работы людям после вас.
Я точно так же могу обозвать жесточайшим и неоправданным ваше требование чтобы структура css совпадала со структурой html.
Да, весьма жесткое требование, однако я привел на мой взгляд более чем весомые причины, и на чей угодно взгляд эти причины по крайней мере есть. В отличие от вас с куда более жестоким требованием/подходом к сбору имен классов.
Чем измеряли?
Сложностью поддержки — внесения изменений, исправления ошибок и рефакторинга. Как на собственном опыте, так и наблюдая за работой других человек над разными базами кода, включая и тот где имена классов собираются.
Любому человеку, ...
Почему вы так уверены?
Потому что считаю свои способности к экстраполяции выше среднего? И не встречал никогда и нигде аргументов за сбор имен классов? И не встречал и не слышал ни об одном человеке, который бы собирал имена классов долгое время и считал это хорошей практикой? Зато постоянно натыкаюсь на тех кто только начал их собирать и уже продвигает это везде не приводя никаких аргументов за это. Предполагаю что затем такие люди тихо сливаются и не отсвечивают о своих предыдущих заблуждениях.
Можете ли вы сказать что за плюсы есть от сбора имен классов? (не считая сбор модификаторов и псевдоселекторов, с этим все в порядке и по моему мнению)
А то пока что я не слышал ни одного, кроме абсурда о том что печатать меньше или что-то мышкой выделять там проще, хотя даже «аргумент» про выделение был не про сборку, а про синтаксис.
Можете ли вы сказать что за плюсы есть от сбора имен классов? (не считая сбор модификаторов и псевдоселекторов, с этим все в порядке и по моему мнению)
Структурирование кода и упрощение поиска.
Без сборки имен селектор по "сложносоставленному" классу может быть описан в файле где угодно, со сборкой имен — только внутри родительского. Соответственно, в куче случаев можно обойтись вовсе без дополнительных операций поиска.
Есть очень простое правило — когда пытаешься выделить всё, на самом деле не выделяешь ничего. Если весь текст набрать жирным капсом — он будет весь одинаковый и его убедительность ни насколько не увеличится. С префиксами то же самое: добавляя их ко всем без исключения блокам, мы обесцениваем такое выделение до нуля. Это просто мусор, мельтешащий в глазах, и мешающий сразу прочитать содержательную часть имени.
С префиксами то же самое: добавляя их ко всем без исключения блокам, мы обесцениваем такое выделение до нуля.
Вот здесь прямо точно видно что вы не так поняли цель «выделения». Выделяются классы не друг от друга, а от остальной базы кода. Хотя и друг от друга тоже,
b-
сигнализирует начало имени класса для любого окружения. Зачем это надо и почему без этого реально плохо вы можете прочитать в моем комментарии к вашему посту выше, но здесь я просто приведу цитату:Если вы сидите в продуктовой разработке и годами работаете с одной и той же кодовой базой с вылизанной структурой, знаете коллег как облупленных и все они высокого уровня и следуют общим правилам, и правила собственно эти есть, то я вас поздравляю, but you're in a bubble.
Во всех остальных случаях (хотя даже и в вашем идеальном мире) я не будут доверять никому и выполню полнотекстовый поиск имени класса по всей кодовой базе, включая серверный код, прежде чем его удалить или изменить. И без префикса .b- мне придется разгребать сотни unrelated найденных результатов, и хорошо еще если не тысячи.
Если у вас это не так — у вас проблема в чем-то другом.
Миллион разных вещей может произойти и на мой взгляд разработчик ответственен за обеспечение как можно большей устойчивости к изменениям (вандализму) у кодовой базы. Без префиксов у имен классов единственный джуниор или сеньер с вашей attitude может все вашу красоту развалить в быстрые сроки и прибрать будет за ними в разы более тяжко.
Есть и другие аргументы за наличие префиксов, куда менее простые для описания и убеждения, поэтому если вас (или кого-то другого) это не убедило, то мне их будет бестолку приводить и распыляться, всего доброго.
Вы умеете использовать регексп конструкцию \b при поиске во всех файлах? С его помощью можно найти button но не buttons.
Префиксы это культ карго. Изначально его использовали в Яндексе во времена когда о беме ещё никто не знал, но в последствии решили что префиксы не нужны, но некоторые разработчики продолжают их использовать по инерции.
О том почему префиксы не нужны читайте здесь https://ru.bem.info/methodology/history/#%D0%9F%D0%BE%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2
Извините, ссылка устарела
Корректная ссылка: https://ru.bem.info/forum/158/
data-suggestion-json="{"suggestion_details": {"suggestion_type": ... }"
Есть тут знатоки стандарта? Не обязательно ли здесь экранирование символов?
Это не код страницы, это скриншот интерактивного инструмента для редактирования DOM (а не разметки — разметку уже давно распарсили и забыли!)
Соответственно, все кавычки тут отображаются в декодированном виде просто потому что так удобнее человеку. В разметке же они были все экранированы.
Перепутать кавычки которые границы атрибута с теми что внутри невозможно — они разных цветов :-)
«В информатике есть лишь две сложные задачи: инвалидация кэша и именование сущностей»
Фил Карлтон
Мне кажется, что более отражающей суть вещей будет чуть подправленная цитата:
There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.
Leon Bambrick
Да в общем-то на валидность всем пофигу. Просто когда такое видишь — начинаешь думать, а как это работает, а не ломает ли оно что-нибудь, не конфликтует ли, не будет ли тут подводных камней...
всем пофигу
Ну как всем. У нас, например, валидатор есть часть автотестов. Полезная и не требующая настройки часть, надо заметить. И его варнинги логично приравнивать к ошибкам.
Да в общем-то на валидность всем пофигу.Если «всё работает», то пользователю пофигу.
Но «всем пофигу» и на доступность:
<div class="site-navigation">
</div>
— это почти слайд из презентации "Людоедский интерфейс, Вадим Макеев", где рекомендуется использовать <nav>
</nav>
.nav-playlists__item__main
.nav-session__item__badge__text
Где-то прочитал, что в этом проекте всё неплохо сделано
Частенько не хватает дополнительного уровня вложенности для элементов
Спасибо, за статью, очень мало описания БЭМ простым языком, но больше всего не хватает реальных примеров проектов с использованием БЭМ.
Могли бы Вы написать парочку проектов на github'е, на которых сделано всё хорошо БЭМ+css
Также интересно как правильно группировать css свойства, сейчас они у меня отсортированы по алфавиту (sass-lint, airbnb)
<div class='menu'>
<div class='menu__item'>
<div class='menu__item__caption'></div>
</div>
</div>
Решения:
1. Добавить префикс
<div class='menu'>
<div class='menu-item'>
<div class='menu-item__caption'></div>
</div>
</div>
2. Разделить на блоки: сделать новый блок
<div class='menu'>
<div class='item'>
<div class='item__caption'></div>
</div>
</div>
3. Сделать БЭМ-дерево с одним уровнем вложенности элементов
<div class='menu'>
<div class='menu__item'>
<div class='menu__caption'></div>
</div>
</div>
Спасибо за этот перевод. Я рад, что в нём был озвучен способ именования с префиксом js- потому что это действительно помогает.
Могу добавить только что кэмэлКейс в цсс выручает если у вас css-модули или бем-реакт. Иначе время от времени в js придётся использовать обращение через квадратные скобки — <div className={styles['my-class']}>
Соглашения по именованию CSS-сущностей и экономия времени