Статьи

Структурирование селекторов классов CSS с помощью Sass

Соглашения об именах CSS являются легионами. Вы, наверное, уже знаете BEM и SMACSS (последние также являются не просто соглашениями по именованию). Существует также OOCSS, которая больше похожа на полную методологию. Все они в значительной степени полагаются на селекторы классов CSS, так как они многократно используются.

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

Вложенность родного селектора

Возможность использовать вложенные селекторы, чтобы не повторять оригинальное имя блока, давно задана в Sass. В версии 3.3 Sass эта функция наконец была представлена. Сначала с очень странным синтаксисом во время бета-тестирования, позже он изменился на лучший, когда появилась стабильная версия. Причины этого изменения объясняются Натали Вайзенбаум в этой статье .

В основном, селектор ссылок ( & ) может использоваться как часть имени подкласса, чтобы создать другое имя класса из первого на корневом уровне документа (здесь @at-root не требуется).

 .foo { // Styles for `.foo` &-bar { // Styles for `.foo-bar` } } 

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

 .media { // Styles for `.media` block &__img { // Styles for `.media__image` element &--full { // Styles for `.media__image--full` modified element } } &--new { // Styles for `.media--new` midifier } } 

Предыдущий код будет скомпилирован в:

 .media {} .media__img {} .media__img--full {} .media--new {} 

Pros

  • Он опирается на встроенную функцию, не требуя дополнительных помощников, таких как переменные или миксины.
  • В целом довольно просто понять, когда вы знаете, как работает селектор ссылок ( & ).

Cons

  • Он раскрывает синтаксис & , который может немного сбивать с толку, если не пугает разработчиков, не знакомых с Sass.
  • Вложенность обычно не печатается в корне, если не используется @at-root , что может сбить с толку.

БЭМ миксин

Поскольку во время бета-тестирования Sass 3.3 ( @at-root #{&}__element ) синтаксис для генерации классов был очень уродливым, мы быстро увидели, что тут и там появляются некоторые миксины, чтобы скрыть страдания и предоставить более дружественный API.

 @mixin element($element) { &__#{$element} { @content; } } @mixin modifier($modifier) { &--#{$modifier} { @content; } } 

Вы бы использовали их так:

 .media { // Styles for `.media` block @include element("image") { // Styles for `.media__image` element @include modifier("full") { // Styles for `.media__image--full` modified element } } @include modifier("new") { // Styles for `.media--new` midifier } } 

Мы могли бы также создать миксин block таким же образом, но это было бы не очень полезно, поскольку блок — это не что иное, как одно имя класса. Давайте будем проще. Хотя для некоторых людей modifier и element казались слишком длинными, поэтому мы видели несколько цветущих e и m .

 .media { // Styles for `.media` block @include e("image") { // Styles for `.media__image` element @include m("full") { // Styles for `.media__image--full` modified element } } @include m("new") { // Styles for `.media--new` midifier } } 

Pros

  • Эта версия предоставляет удобный API, который легко понять, если вы знаете, что такое БЭМ и как он работает.

Cons

  • Логика скрыта за миксинами, и если вы явно не знаете, что происходит, не так очевидно, что генерируются новые селекторы и классы.
  • Однобуквенные миксины, вероятно, не очень хорошая идея, так как они затрудняют понимание цели миксина. b и m может значить много вещей.

Гуманизированные БЭМ-миксины

В последнее время я читал о новом, похожем на БЭМ подходе Андерса Шмидта Хансена. Идея состоит в том, чтобы спрятать жаргон Block-Element-Modifier за общим словарным запасом, который имеет смысл при чтении вслух.

 @mixin new($block) { @at-root .#{$block} { @content; } } @mixin has($element) { &__#{$element} { @content; } } @mixin when($modifier) { &--#{$modifier} { @content; } } 

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

 @include new("media") { // Styles for `.media` block @include has("image") { // Styles for `.media__image` element @include when("full") { // Styles for `.media__image--full` modified element } } @include when("new") { // Styles for `.media--new` midifier } } 

Андерс идет на шаг дальше с is(..) и holds(..) mixins. Вся эта идея напоминает мне мой миксин « when-inside(..) чтобы скрыть «за» дружественный человеку миксин при стилизации элемента на основе его верхнего контекста.

 @mixin when-inside($selector) { #{$selector} & { @content; } } img { display: block; @include when-inside(".media-inline") { display: inline; } } 

Pros

  • Этот подход помогает сделать код более читабельным, например, когда мы начали именовать наши классы с состоянием с ведущим is- (популяризированным SMACSS).
  • Все еще придерживается определенной методологии (в данном случае БЭМ), но делает ее более дружелюбной для разработчиков.

Cons

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

Последние мысли

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

В любом случае, ребята, вот самые популярные способы написания CSS-селекторов с помощью Sass, и между вами и мной они мне не нравятся. И не только для поисковой проблемы, которая для меня не так уж важна.

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