Обновить

Комментарии 12

Браузеры парсят CSS справа налево.

А каким образом происходит выборка в случае
.blog-list > .card > img {}

?

Сначала браузер находит все теги <img />, затем все .card и дальше по цепочке. Берет пересечения и применяет стили (точнее добавляет в очередь к другим правилам)

Последний пример несёт неоднозначное поведение в случае асинхронной загрузки компонентов.
Например:
загрузили список блогов, с ним bloglist.css и селектор .blogList__card (класс на элементе списка)
В списке используется компонент Card -> грузим card.css и селектор .card (класс на корневом элементе компонента)

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

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

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

А с другой стороны в html-коде порой столько стилей, что проще было бы через style="" написать.

Давайте проведём рефакторинг кода, следуя принципу DRY

/* С использованием принципа DRY */
.status {
padding: 0.5rem;
font-weight: bold;
}

.status--warning {
color: #eba834;
}

.status--error {
color: #eb3d34;
}


Интересно, если удобнее писать так:
.status {
  padding: 0.5rem;
  font-weight: bold;

  &.warning {
      color: #eba834;
  }

  &.error {
      color: #eb3d34;
  }
}

это нарушает какие-то принципы? или нормально?
Просто в итоговом html будет меньше рябить в глазах (т.е. в данном случае слово status в классах какого-то тега будет только один раз — «status.error» вместо «status status--error»)
это нарушает какие-то принципы?

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

Просто в итоговом html будет меньше рябить в глазах

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

Конфликтов по идее не должно быть.

Это
  .status .error{
    // ...
  }


не тоже самое что это
  .status.error{
    // ...
  }


Во втором случае стили ошибки применятся только в тегах с обоими классами сразу.
В реальной жизни может так случиться, что приплывёт сторонний .error из стороннего компонента/библиотеки (тот же бутстрап) и начнутся сюрпризы.
Составные именя пусть не исправляют проблему, но позволяют сильно снизить вероятность коллизии, объединяя составные части под префиксом блока.
Насчет скорости CSS-селекторов в современных браузерах беспокоиться не нужно, разве что у вас какая-то совсем уж дичь.
Мы разбили стили нашего button на несколько классов, которые могут использоваться для расширения базового класса.

И получается как-то так:
<button class="button button--radialBorder button--large button--primary">Брр</button>

Далеко не всегда удается придумать название класса с чётким и однозначным толкованием.
Css-правила в таких случаях читаются легче, чем длинная строка загадочных классов.
И DRY это несколько противоречит:
class="button button... button... button..."
DRY это несколько противоречит

Эту сложность поглотит шаблонизатор, например, так:
<button className={css('button', ['radialBorder', 'large', 'primary'])}>
    Click me!
</button>
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации