Я слышал, как многие разработчики говорят, что ненавидят CSS. Опыт подсказывает мне, что причина здесь в том, что они не уделяют достаточно времени для того, чтобы изучить CSS. Да, речь идёт о не самом дружелюбном «языке», но он успешно используется для стилизации веб-страниц уже более 20-ти лет. Это впечатляет, и с технологиями такого уровня распространённости приходится считаться. Однако, по мере роста объема стилей, задействованных в некоем проекте, проявляется один большой минус CSS: его очень сложно поддерживать. А плохо написанные стили быстро превращаются в кошмар.

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


Вы уже бывали в подобной ситуации, правда?

Использование имён, состоящих из слов, разделённых дефисами


Если вы много пишете на JavaScript, это значит, что вы привыкли к именам переменных в верблюжьем стиле.

var redBox = document.getElementById('...')

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

Например, так делать не следует:

.redBox {
  border: 1px solid red;
}

Вместо этого лучше применить такую запись:

.red-box {
   border: 1px solid red;
}

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

// Верно
.some-class {
   font-weight: 10em
}
// Неверно
.some-class {
   fontWeight: 10em
}

Соглашение по именованию БЭМ


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

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

  • Роль селектора.
  • Область использования селектора.
  • Взаимоотношения между сущностями.

Доводилось ли вам когда-нибудь видеть имена классов, записанные так:

.nav--secondary {
  ...
}
.nav__header {
  ...
}

Это — результаты применения соглашения по именованию БЭМ.

Основы БЭМ на простом примере


?Что такое «Б»?


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

Взгляните на следующее изображение.


Это изображение человечка выиграло множество престижных наград

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

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

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

Компонент следует стилизовать следующим образом:

.stick-man {
  
 }

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


Человечек — это .stick-man в CSS

?Что такое «Э»?


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

Так, например, у нашего человечка (stick-man) есть голова (head), две замечательных руки (arms) и ноги (feet).


Составные части человечка

Сущности head, feet, arms — это элементы, которые находятся внутри главного компонента (блока). Их можно рассматривать как дочерние компоненты, то есть, они являются потомками родительского компонента.

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

.stick-man__head {
}
.stick-man__arms {
}
.stick-man__feet {
}

?Что такое «М»?


Буква «М» в аббревиатуре «БЭМ» символизирует модификаторы. Что если нашего человечка можно модифицировать, и он может быть либо синим (blue), либо красным (red)?


Синий человечек и красный человечек

В веб-приложении это может быть чем-то вроде красной (red) или синей (blue) кнопки. Это — те самые модификаторы компонентов, о которых идёт речь.

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

.stick-man--blue {
}
.stick-man--red {
}

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


Варианты человечка с головой разного размера

В этот раз модифицируется лишь элемент основного блока. Помните о том, что элемент — это компонент, вложенный в основной компонент. Конструкция .stick-man представляет собой блок, а .stick-man__head — элемент.

Как видно из вышеприведённого примера, дефис можно использовать и так:

.stick-man__head--small {
}
.stick-man__head--big {
}

Обратите внимание на применение двух дефисов. Такая конструкция используется для обозначения модификатора.

Полагаю, теперь всё должно быть понятно. Это и есть основы БЭМ.

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

Зачем использовать соглашения по именованию?


«В информатике есть лишь две сложные задачи: инвалидация кэша и именование сущностей»
Фил Карлтон


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

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

CSS-имена и JavaScript


Поговорим об использовании CSS-имён в JavaScript. Тут нам поможет начинающий программист Джон. Сегодня — его первый рабочий день. Ему предложили заняться следующим HTML-кодом:

<div class="siteNavigation">
</div>

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

<div class="site-navigation">
</div>

Хорошо получилось, правда? Но, к неожиданности Джона, проект, частью которого является доверенный ему код, перестал нормально работать. В чём же дело? Проблема заключается в том, что где-то в JavaScript-коде было использовано применяемое ранее имя класса — siteNavigation:

//код на JavaScript
const nav = document.querySelector('.siteNavigation')

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

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

?Применение имён классов, начинающихся с js-


Один из способов борьбы с подобными ошибками заключается в использовании имён классов, сформированных по шаблону js-*. Такие имена указывают на то, что к рассматриваемому элементу DOM обращаются из JS. Например:

<div class="site-navigation js-site-navigation">
</div>

В результате в JavaScript-коде можно будет использовать такую конструкцию:

//код на JavaScript
const nav = document.querySelector('.js-site-navigation')

Программист, знакомый с таким соглашением по именованию и увидевший имя класса js-site-navigation, сразу понял бы, что это имя используется в JS-коде для работы с элементом DOM и не стал бы менять его без крайней нужды (и без внесения соответствующих исправления в программу на JavaScript).

?Применение атрибута rel


Я этот подход не использую, но я видел тех, кто его применяет. Вам знакома такая конструкция?

<link rel="stylesheet" type="text/css" href="main.css">

Атрибут rel определяет отношения между ресурсом, на который сделана ссылка, и текущим документом. В предыдущем примере с Джоном сторонники этого подхода поступили бы так:

<div class="site-navigation" rel="js-site-navigation">
</div>

В JS с этим можно работать следующим образом:

const nav = document.querySelector("[rel='js-site-navigation']")

У меня есть сомнения по поводу этого подхода, но вы вполне можете встретить его в каком-нибудь проекте. Цель подобного использования атрибута rel заключается в том, чтобы указать на то, что элемент используется в JavaScript.

?Об атрибутах data


Некоторые разработчики используют атрибуты data для организации работы с элементами DOM из JavaScript. Однако, это неправильно. Такие атрибуты используются для хранения данных. Вот пример правильного использования data-атрибутов из кода Твиттера.

Правильное использование атрибутов data

Итоги


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

Уважаемые читатели! Какие схемы именования сущностей вы используете при работе с CSS?

Комментарии (50)


  1. k12th
    22.01.2018 12:13
    +1

    Например, так делать не следует: .redBox

    Но почему? Ответ «А прост.:)» не катит, извините.


    rel="js-site-navigation"

    Вообще-то в отличие от data-*, у rel есть вполне определенное семантическое значение (даже можно сказать что и не одно). Что если мне надо будет этим способом выбрать из DOM хотя бы один из тех самых rel="stylesheet"?


    1. dom1n1k
      22.01.2018 13:53

      Ответ «так сложилось исторически». Например, в JS органичен camelCase, а snake_case смотрится инородно. Тут то же самое.


      1. Azan
        22.01.2018 14:00
        +1

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


        1. dom1n1k
          22.01.2018 15:02

          1. Azan
            22.01.2018 15:11

            Да, хаки есть, но не исправлять же весь этот зоопарк программ…
            Это поведение для браузеров, блокнотов, того-же notepad++ и.т.д.


            1. c4boomb
              22.01.2018 16:50

              выкинуть мышь и использовать VIM


        1. DaturInnoxia
          23.01.2018 10:26

          Аналогично, прям бесит. Намного лучше разделять дефисом именно семантику.

          Например,
          .box-red {}
          .box-blue {}

          А названия, которые логично употреблять слитно, можно через нижнее подчеркивание:
          .my_box-blue {}


    1. marapper
      22.01.2018 14:18

      В случае любой модульной системы именования в css требуется как минимум два разных способа классификации (БЭМ через __ или --) и разделение слов в блоке/элементе. Например, calculator-form__field_required или calculatorForm--field-required. Нормальные IDE умеют выделять такие классы в css. Остальное — удел кодстиля и вкусовщины, на самом деле.

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


      1. k12th
        22.01.2018 14:26

        Как по мне, .calculatorForm-field_required (или даже — о кощунство! — .calculatorForm-field.required) вполне достаточно.
        Я согласен, что это вкусовщина, просто мне не нравится, что некоторая конкретная вкусовщина выдается за стандарт и божественное откровение (при всем уважении к авторам БЭМ).


        1. dom1n1k
          22.01.2018 15:12

          Пару лет назад я тоже придумал для себя такие вот «пристёгивающиеся» однословные модификаторы. Решение казалось очень элегантным. Но только до того момента, когда начинаешь менять эти модификаторы из скриптов. Потому что есть такая штука, как микс классов и иногда бывает так, что из скрипта не можешь понять, к чему именно относится этот модификатор. Особенно для модификаторов типа small, large, light, dark — практически что угодно может быть большим или светлым. Да, такие коллизии встречаются сравнительно редко, но встречаются.


      1. vintage
        22.01.2018 22:56

        Не в любой, не обобщайте. У нас, например, используется такое именование: my_calculator_form_field_required. И с выделением ни в каком редакторе/вьювере нет проблем. И рефакторинг элементарен — просто заменяем подстроку по всем файлам. И не важно js это или css или даже json. Никакие js- префиксы не нужны.


    1. punkkk
      22.01.2018 17:15

      А потому, что рефакторинг не всегда хорошо работает в IDE и, например, в случае, Если в js используется селектор по этому классу, то поискм и заменой вы сможете переименовать класс CSS, а есди у вас есть что то в духе:

      someObject.someName

      и в html:
      .someName


      То по поиску-замене может получиться что-то плохое. Хотя современные IDE умею в исключение файлов из выборки, но тогда вы можете пропустить селектор. Да и искать его бдет проще по шаверма-кейсу, чем по camel.

      Это так, из личного представления о вопросе. Раньше всегда кэмел любил везде.


      1. k12th
        22.01.2018 17:23

        Рефакторинг тем и отличается от поиска/замены, что учитывает, строковый это литерал или переменная/поле объекта:)


  1. Azan
    22.01.2018 13:28

    А как-же, использование class для css, а id для js.
    Или есть минуса в этой схеме?


    1. Rastishka
      22.01.2018 14:20
      +1

      Для JS может потребоваться несколько элементов, а ID может быть только один.


  1. iFamily
    22.01.2018 14:13
    +1

    Как по мне, так camelCase везде смотрится органично.


    1. Rastishka
      22.01.2018 14:19

      Вот вот.
      Не понимаю этой истерии «Так LANG_NAME же caseinsencitive, все заглючит, мы все умрем!!!111»

      Если в одном проекте есть .redBox и .redbox — уволить верстальщика.

      А с кашей из redBox/red-box/red_box работать значительно геморройнее, чем по всему стеку технологий придерживаться единой нотации и нормальных названий переменных.


  1. ExploZeR
    22.01.2018 14:56

    Во-первых, нет никаких оснований называть camelCase плохим только потому что так кажется автору.

    Во-вторых, печатать конструкции вроде

    .stick-man__feet
    не самое приятное. И выделять их в тексте дабл кликом тоже.

    В третьих, названия классов из 4-5 слов
    stick-man__head--small
    штука тоже сомнительная. Половина разметки потом состоит из классов.

    Да и селекторы в css потом трёхэтажные
    .big-city .baker-street-avenue .stick-man__head--small


    Цель подобного использования атрибута rel заключается в том, чтобы указать на то, что элемент используется в JavaScript.
    А почему вместо этого не добавлять таким элементам просто класс «js»?


    1. dom1n1k
      22.01.2018 15:20

      Селекторы из 3-4 слов (5+ всё же встречаются редко) это нормально.
      Да, визуально немного громоздко. Я когда впервые с этим столкнулся, тоже испытывал эмоциональное неприятие. Но практика показывает, что это более чем разумная плата за однозначность и надежность. Использование слишком коротких и «красивых» классов рано или поздно приводит к каким-то коллизиям, если они все находятся в одном скоупе (то есть не учитывая вариант некоторых js-фреймворков, которые эмулируют css-scopes через атрибуты). Особенно, если над кодом работают разные люди. Просто неизбежно, вопрос лишь времени.


    1. Bluz
      22.01.2018 16:11

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

      В SCSS я использовал такие варианты:

      .block-name {
          &__element-1 {}
      
          &__element-2 {
              &--modification{}
          }
      }
      


      В html всё понятно, что придется печатать, хотя не встречал проблем с этим.


      1. VinBear
        23.01.2018 11:42
        +1

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


      1. Jumper_In
        23.01.2018 11:42
        +1

        При таком именовании возникает проблема, что невозможно найти стиль .block-name__element-1 или .block-name__element-2--modification через глобальный поиск.

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


        1. dom1n1k
          24.01.2018 09:20

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


          1. VinBear
            24.01.2018 11:52

            Если вы сидите в продуктовой разработке и годами работаете с одной и той же кодовой базой с вылизанной структурой, знаете коллег как облупленных и все они высокого уровня и следуют общим правилам, и правила собственно эти есть, то я вас поздравляю, but you're in a bubble.

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

            Если у вас это не так — у вас проблема в чем-то другом.

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

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


  1. vasIvas
    22.01.2018 15:12

    Некоторые разработчики используют атрибуты data для организации работы с элементами DOM из JavaScript. Однако, это неправильно.


    Зачем элементу хранить json? И гдетогда хранить информацию что toggle=«true or false»?


    1. k12th
      22.01.2018 15:24

      Могу ответить на первый вопрос: когда сервер рендерит разметку, а JS её потом оживляет, ему надо откуда-то получать данные. Чтобы не бегать AJAX'ом на сервер и не вытаскивать данные по клочкам из DOM-дерева, кладут их в data-*.


      1. vire
        22.01.2018 17:52
        -1

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

        Советы от Твиттера в ui/ux — это даже не смешно. Поражает, что компания умеет делать годные инструменты(спасибо за bootstrap), но собственный главный продукт — полный технологический отстой и собрание всех антишаблонов в одном месте.


        1. k12th
          22.01.2018 17:57

          Я лично никакую, я так давно не делаю:)
          Тормозит не разметка сама по себе, а её отрисовка. Атрибуты, которых браузер не знает, на скорость не влияют (ну разве только на парсинг строки).


        1. vasIvas
          23.01.2018 07:43

          В том же bootstrap data-*атрибуты используются для хранения состояния, к примеру data-toggle=""


  1. bro-dev
    22.01.2018 15:15

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


    1. k12th
      22.01.2018 15:27

      Ну когда как, например, если вы продаете разноцветных котят, то логично что некоторые будут .kitten__pink, другие .kitten_orange и так далее.


  1. noodles
    22.01.2018 15:51

    один большой минус CSS: его очень сложно поддерживать.

    Считаю что за счёт самого определения CSS, стили как раз таки и не сложно поддерживать по сравнению с другими языками/абстракциями. Благодаря каскадности и современным браузерным отладчикам — всё что угодно можно локализовать (найти), переопределить, выкинуть или переписать. Но для этого действительно нужно хорошо ориентироваться в css.

    P.S. Допускаю, что просто не работал с по настоящему древним проектом с огромной простынёй «плохих стилей».


    1. VinBear
      23.01.2018 12:09

      Работал и с древними проектами и простынями, и с настолько запутанными стилями, что их распутывание (без ломания всего в процессе) требовало многочисленных итераций рефакторинга/переделывания сразу по всему проекту, начиная с БД и заканчивая на фронте.

      Поддерживать хороший 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, это один из минусов. Но сразу видно есть ли у блока адекватная структура или это бессмысленный каша с бессмысленно раскиданной версткой, классами и стилями, что на мой взгляд совершенно огромнейший плюс.
      В итоге менять именно что структуру у блока не приходится почти никогда, а когда приходится, то это в основном из-за реально изменившихся требований к работе блока, а не по каким-то техническим причинам. Да и расширение функционала блока происходит куда легче из-за наличия смысла в его структуре.

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


      1. mayorovp
        23.01.2018 16:27

        Что-то как-то слишком радикально все у вас...


        Если .b-button без проблем находится полнотекстовым поиском по проекту — то зачем искать отдельно .b-button__content?


        Мы же пишем нормальный (s)css вроде бы? В таком случае у нас .b-button__content всегда будет рядом с .b-button и его можно будет там найти поискав .b-button!


        А если теперь поменять местами дефис и подчеркивание, чтобы было .b_button--content — то те самые редакторы которые раньше нужно было отдельно настраивать, будут уже помогать: выделять мышкой ровно первую часть (b_button) для поиска.


        Таким образом, ваше третье правило становится ненужным — и без него все успешно ищется.


        1. VinBear
          23.01.2018 20:03
          -1

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

          Есть несколько проблем с собиранием классов (не считая сборку модификаторов и псевдоселекторов):
          1. Поиск любого класса превращается в квест вместо нажатия сочетания клавиш для поиска, особенно если имя элемента начинает состоять хотя бы из трех слов, не считая имени блока (А три слова это нормально, и пять нормально). Глазами найти тоже становится значительно тяжелее, и думаю это достаточно объективное суждение, не так ли? Начиная примерно от первого же уровня собирания, стили превращаются все в более и более запутанные лабиринты и головоломки, вместо инструмента веб-разработки. Кому-то может это интересно, не спорю. Куда круче редактировать кашу из спец-символов вместо простого кода, человек начинает выглядеть прямо как кулцхакер, самооценка повышает, уволить становится его сложнее и т.д.

          2. Становится невыполнимым требование 7.2 структуры css/scss-кода повторять html-структуру, даже в приблизительной интерпретации. Просто напросто deal breaker лично для меня.

          3. Даже без требования 7.2 структура scss-кода начинает диктоваться словами в имени классов, что либо не совпадает совсем со смысловой нагрузкой на конкретные классы и с html-структурой, либо накладывает жесточайшие и неоправданные ограничения на именование классов. А плохие имена классов это, очевидно, очень плохо по всем фронтам.

          4. И из совсем реальной жизни: плохо (или даже просто не супер хорошо) написанный код с собиранием классов в ~десять раз хуже плохого css-кода без собирания классов.

          5. Код со сборкой классов становится адом для поддержки, да даже не адом, он просто не поддерживается. Любому человеку, не пишущему такой код в течение хотя бы нескольких месяцев, проще взять скомпилированную версию scss/less-файла, заменить исходник именно на нее, и с ним уже работать.

          Я могу представить собирание имен классов хоть сколько-нибудь оправданным (not really) только в случае если вообще весь стек проекта завязан на БЭМ по всем направлениям — верстка, стили, скрипты, системы сборки, инфраструктура, линтеры, etc… Иными словами если это внутренний проект Яндекса.


          1. mayorovp
            23.01.2018 21:03

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

            Так на то правила и существуют.


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

            Никакого квеста: ищем имя блока, а дальше все видно… Или у вас описания блоков по три экрана?


            Даже без требования 7.2 структура scss-кода начинает диктоваться словами в имени классов, что либо не совпадает совсем со смысловой нагрузкой на конкретные классы и с html-структурой, либо накладывает жесточайшие и неоправданные ограничения на именование классов.

            Я точно так же могу обозвать жесточайшим и неоправданным ваше требование чтобы структура css совпадала со структурой html.


            И из совсем реальной жизни: плохо (или даже просто не супер хорошо) написанный код с собиранием классов в ~десять раз хуже плохого css-кода без собирания классов.

            Чем измеряли?


            Любому человеку, ...

            Почему вы так уверены?


            Будут ли у вас какие-нибудь аргументы кроме вашего мнения?


            PS


            Я могу представить собирание имен классов хоть сколько-нибудь оправданным (not really) только в случае если вообще весь стек проекта завязан на БЭМ по всем направлениям

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


            1. VinBear
              24.01.2018 01:00

              Никакого квеста: ищем имя блока, а дальше все видно… Или у вас описания блоков по три экрана?

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

              Я точно так же могу обозвать жесточайшим и неоправданным ваше требование чтобы структура css совпадала со структурой html.

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

              Чем измеряли?

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

              Любому человеку, ...

              Почему вы так уверены?

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

              Можете ли вы сказать что за плюсы есть от сбора имен классов? (не считая сбор модификаторов и псевдоселекторов, с этим все в порядке и по моему мнению)

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


              1. mayorovp
                24.01.2018 06:52

                Можете ли вы сказать что за плюсы есть от сбора имен классов? (не считая сбор модификаторов и псевдоселекторов, с этим все в порядке и по моему мнению)

                Структурирование кода и упрощение поиска.


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


                1. VinBear
                  24.01.2018 11:32

                  Понятно, спасибо.

                  Но вот 7.2 как раз делает все это и больше. Минусов от 7.2 меньше чем от сборки и они другие. Ограничения приносят пользу, а не вред. Плюсы крупнее.

                  Ну вы поняли мое отношение.


      1. dom1n1k
        24.01.2018 09:26
        -1

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


        1. VinBear
          24.01.2018 11:58

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

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

          Если вы сидите в продуктовой разработке и годами работаете с одной и той же кодовой базой с вылизанной структурой, знаете коллег как облупленных и все они высокого уровня и следуют общим правилам, и правила собственно эти есть, то я вас поздравляю, but you're in a bubble.

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

          Если у вас это не так — у вас проблема в чем-то другом.

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

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


  1. baldr
    22.01.2018 16:56

    Вот интересно, почему вот это считается «правильным использованием data-атрибутов»?
    data-suggestion-json="{"suggestion_details": {"suggestion_type": ... }"
    Есть тут знатоки стандарта? Не обязательно ли здесь экранирование символов?


    1. mayorovp
      23.01.2018 10:15

      Конечно же оно тут обязательно.


    1. mayorovp
      23.01.2018 11:33

      Наконец-то нашел где вы увидели эту конструкцию.

      Это не код страницы, это скриншот интерактивного инструмента для редактирования DOM (а не разметки — разметку уже давно распарсили и забыли!)

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

      Перепутать кавычки которые границы атрибута с теми что внутри невозможно — они разных цветов :-)


  1. baldr
    22.01.2018 16:58

    Насчет этой цитаты,

    «В информатике есть лишь две сложные задачи: инвалидация кэша и именование сущностей»
    Фил Карлтон

    Мне кажется, что более отражающей суть вещей будет чуть подправленная цитата:
    There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.
    Leon Bambrick


  1. vanxant
    22.01.2018 17:41

    Юзать rel со своими значениями невалидненько


    1. k12th
      23.01.2018 00:37

      Да в общем-то на валидность всем пофигу. Просто когда такое видишь — начинаешь думать, а как это работает, а не ломает ли оно что-нибудь, не конфликтует ли, не будет ли тут подводных камней...


      1. vanxant
        23.01.2018 01:56

        всем пофигу

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


        1. k12th
          23.01.2018 02:01

          Это похвальная практика, но я очень редко такое встречаю.


      1. ainoneko
        25.01.2018 10:08
        +1

        Да в общем-то на валидность всем пофигу.
        Если «всё работает», то пользователю пофигу.
        Но «всем пофигу» и на доступность:
        <div class="site-navigation">
        </div>
        — это почти слайд из презентации "Людоедский интерфейс, Вадим Макеев", где рекомендуется использовать
        <nav>
        </nav>