Структурирование CSS в больших проектах

Структурирование CSS в больших проектах

Писать CSS — просто.
Писать сопровождаемый CSS — сложно.

Скорее всего вы уже слышали об этом 100 раз. Если вы пишите на C, то знаете что глобальные переменные это плохо. Если вы любого рода программист, вы знаете, что отдельные, компонуемые модули это ключ к построению поддерживаемой системы.

Чтобы помочь людям построить поддерживаемый CSS, было создано множество методологий CSS: SMACSS, OOCSS, BEM, ITCSS, ACSS, CCSS, Atomic Design, Maintanable CSS, rscss, и их намного больше.

Итак, в чем же проблема c CSS?

span {
  font-size: 11px;
}

.header-right {
  font-size: 22px;
  text-align: right;
}

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

В обычном языке программирования вы подключаете только те модули, необходимые для реализации конкретной функции, например.

# Python модули
import requests
from Flask import url_for

// Node модули
var express = require(‘express’)

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

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

Сейчас это вполне объяснимо, и имеет смысл в базовом дизайне, например в типографии. Это то для чего HTML и CSS были созданы. Это инструменты для публикаций. Чтобы понять, что стоит за этими языками, я часто представляю типографический набор для книги: вы же не хотите, чтобы каждая страница выглядела по-разному — нет, вы хотите простые связные стили на протяжении всей книги, без всякого мусора. Вот почему есть смысл в тегах <h1-6>, <section>, и стилях, которые глобальны и вездесущи.

Тем не менее, мир меняется, и интернет тоже. Мы больше не создаем интернет-страницы — мы создаем интернет-приложения. Метафора публикации, на которой построены HTML и CSS, в большинстве случаев уже не подходит.

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

Способ Peergrade.io создавать CSS

1-е правило: Используйте префиксы (для названий классов)

В Peergrade.io используют префикс .pg для всех классов. Не использовать префикс в вашем CSS — напрашиваться на неприятности. Причина в том, что класс без префикса в конце концов столкнется с важными стилями. Скажем, вам нужно поле выбора даты — конечно вы не хотите создавать его с нуля (надеюсь, что это так!), поэтому вы подключаете его. Теперь вы получаете классы вроде .prev, .next и .separator, которые потенциально могут столкнуться с вашими классами — если вы не используете префикс.

Долгое время Font Awesome не использовали префикс в своих названиях классов, что означало что вы часто начинали войну имен с их .icon-* (сейчас они используют префикс .fa). И нам очень жаль, что Bootstrap решили не добавлять префикс.

2-е правило: Не должно быть вложенности селекторов

В Peergrade.io используют Sass. Используя Sass вы быстро начнете использовать паттерн, когда ваша Sass структура повторяет структуру HTML, т.е:

#user-profile-page

  .profile-description
    h3

    ul
      li
        a

После того как вы это сделаете — вы поймете — это очень хрупко. Когда вы пишите это, вы можете думать что в .profile-description будет всего один список (ul), но спустя месяц или два вы выясните, что здесь необходим другой список и ваша структура быстро опережает ваши предложения.

Так же, стили определеные таким образом, будут применяться к любым элементам внутри родительского, а не только к тому же уровню в каком заданы в Sass.

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

3-е правило: Используйте БЭМ именования

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

// .блок__элемент--модификатор
.block__element--modifier

Чтобы достигнуть этого, мы структурируем наш Sass таким образом:

.pg-deadline
  &__date
    // станет \`.pg-deadline__date`
    color: $color-gray

  &__header
    // станет \`.pg-deadline__header`
    font-weight: 700

    &--highlight
      // станет `.pg-deadline__header--highlight`
      color: $color-green

Здесь видно, что мы используем вложенность Sass чтобы создавать имена классов согласно БЭМ. Несколько парадоксально, вложенность, на самом деле создаст абсолютно плоскую CSS структуру — никакой вложенности — классы только верхнего уровня.

Как исключение из второго правила, мы позволяем вложенность для классов с модификатором .block--modifier

.pg-deadline--editable
  .pg-deadline__header
    background-color: $color-blue

  .pg-deadline__date
    color: $color-black

В этом, особенном случае, допускается вложенность CSS селекторов. Это позволит нам определять модификатор только для блока — который и модифицируется — и избавиться от повторения модификатора на всех дочерних блоках (на элементах или "Э" в БЭМ).