Изучение SMACSS: масштабируемая и модульная архитектура для CSS

Опубликовано: 2022-03-11

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

Так что многие люди создали архитектуру CSS, чтобы помочь стилизовать свой код, чтобы CSS стал более читабельным. SMACSS — то есть масштабируемая и модульная архитектура для CSS — нацелена именно на это. Это определенный набор рекомендаций по архитектуре CSS от Джонатана Снука, который я принял.

Теперь архитектурный подход SMACSS немного отличается от фреймворка CSS, такого как Bootstrap или Foundation. Вместо этого это набор правил, больше похожий на шаблон или руководство. Итак, давайте углубимся в некоторые шаблоны проектирования CSS, чтобы узнать, как мы можем использовать их, чтобы сделать наш код лучше, чище, легче для чтения и более модульным.

Каждая структура проекта SMACSS использует пять категорий:

  1. Основание
  2. Макет
  3. Модули
  4. Состояние
  5. Тема

Основание

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

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

Вот пример того, как должна выглядеть базовая файловая единица:

 html { margin: 0; font-family: sans-serif; } a { color: #000; } button { color: #ababab; border: 1px solid #f2f2f2; }

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

SMACSS или нет, я настоятельно рекомендую по возможности избегать использования !important и не использовать глубокую вложенность, но я расскажу об этом позже в этом посте. Кроме того, если вы практикуете использование сброса CSS, это то место, где вы должны включить его. (Я предпочитаю использовать Sass, поэтому я просто включаю его в начало файла, вместо того, чтобы копировать или ссылаться на него отдельно от элемента <head> каждой страницы.)

Связанный: Темы с Sass: Учебник по SCSS

Макет

Стили макета будут делить страницу на основные разделы — не такие, как навигация или, например, аккордеон, а действительно разделы верхнего уровня:

Примеры стилей макета SMACSS: заголовок, боковая панель, контент/основной и нижний колонтитул.

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

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

Пример веб-страницы, которую можно организовать в стили макета верхнего, основного и нижнего колонтитула с помощью SMACSS.

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

Также вы должны предварять правила для стилей макета буквой l , чтобы отличить их от стилей модуля. Обычно здесь вы стилизуете вещи, характерные для макета, такие как граница, выравнивание, поля и т. д. Также может иметь смысл фон этой части страницы, даже если он кажется не совсем специфичным для макета.

Вот пример того, как это должно выглядеть:

 #header { background: #fcfcfc; } #header .l-right { float: right; } #header .l-align-center { text-align: center; }

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

В качестве другого примера вы можете использовать некоторые поля по умолчанию для поля макета, например .l-margin с полем 20px . Затем, где бы вы ни захотели заполнить какой-либо контейнер, элемент, карточку или коробку, вы просто добавляете к нему класс l-margin . Но вы хотите что-то многоразовое:

 .l-full-width { width: 100%; }

Не что-то внутренне связанное, как это:

 .l-width-25 { width: 25px; }

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

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

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

 .box--label { color: blue; } .card--label { color: red; }

Модуль

Как я упоминал ранее, модули SMACSS — это небольшие фрагменты кода, которые можно повторно использовать на странице, и они являются частью единого макета. Это части CSS, которые мы хотим хранить в отдельной папке, так как их будет много на одной странице. И по мере роста проекта мы можем разделить его, используя лучшие практики структуры папок, то есть по модулям/страницам:

Пример иерархии файлов/папок с использованием SMACSS и Sass

Итак, в предыдущем примере у нас была статья, которая может быть отдельным модулем. Как здесь должен быть структурирован CSS? У нас должен быть класс .article , который может иметь дочерние элементы title и text . Поэтому, чтобы сохранить его в том же модуле, нам нужно добавить префикс дочерних элементов:

 .article { background: #f32; } .article--title { font-size: 16px; } .article--text { font-size: 12px; }

Вы можете заметить, что мы используем два дефиса после префикса модуля. Причина в том, что иногда имена модулей состоят из двух слов или собственных префиксов, таких как big-article . Нам нужно иметь два дефиса, чтобы указать, какая часть является дочерним элементом — например, сравнить big-article-title с big-article--title и big-article--text .

Кроме того, вы можете вкладывать модули внутрь модулей, если конкретный модуль занимает большую часть страницы:

 <div class="box"> <div class="box--label">This is box label</div> <ul class="box--list list"> <li class="list--li">Box list element</li> </ul> </div>

Здесь, в этом простом примере, вы можете видеть, что box — это модуль, а list — это другой модуль внутри него. Итак, list--li является дочерним элементом модуля list , а не box . Одной из ключевых концепций здесь является использование максимум двух селекторов для каждого правила CSS, но в большинстве сценариев должен быть только один селектор с префиксами.

Таким образом, мы можем избежать дублирования правил, а также иметь дополнительные селекторы для дочерних элементов с одинаковыми именами, тем самым повышая скорость. Но это также помогает нам избежать использования нежелательных правил !important -style, которые являются признаком плохо структурированных проектов CSS.

Хорошо (обратите внимание на единственный селектор):

 .red--box { background: #fafcfe; } .red-box--list { color: #000; }

Плохо (обратите внимание на повторение внутри селекторов и метод перекрывающихся ссылок):

 .red .box { background: #fafcfe; } .red .box .list { color: #000; } .box ul { color: #fafafa; }

Состояние

То, что определяет состояние в SMACSS, — это способ описать, как наши модули выглядят в различных динамических ситуациях. Так что эта часть действительно для интерактивности: мы хотим другого поведения, если элемент считается скрытым, развернутым или измененным. Например, аккордеону jQuery потребуется помощь в определении того, когда вы можете или не можете видеть содержимое элемента. Это помогает нам определить стиль элемента в определенное время.

Состояния применяются к тому же элементу, что и макет, поэтому мы добавляем дополнительное правило, которое переопределит предыдущие, если таковые имеются. Правилу штата отдается приоритет, так как оно является последним в цепочке правил.

Как и в случае со стилями макета, здесь мы обычно используем префиксы. Это помогает нам распознавать их и отдавать им приоритет. Здесь мы используем префикс is , например is-hidden или is-selected .

 <header> <ul class="nav"> <li class="nav--item is-selected">Contact</li> <li class="nav--item">About</li> </ul> </header>
 .nav--item.is-selected { color: #fff; }

Здесь можно использовать !important , так как состояние часто используется как модификация JavaScript, а не во время рендеринга. Например, у вас есть элемент, который скрыт при загрузке страницы. При нажатии кнопки вы хотите показать это. Но класс по умолчанию такой:

 .box .element { display: none; }

Итак, если вы просто добавите это:

 .is-shown { display: block; }

Он останется скрытым даже после того, как вы добавите класс .is-shown к элементу через JavaScript. Это связано с тем, что первое правило имеет два уровня глубины и переопределяет его.

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

 .is-shown { display: block !important; }

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

Тема

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

 .button-large { width: 60px; height: 60px; }
 <button class="button-large">Like</button>

Не путайте эти правила темы SMACSS с базовыми, поскольку базовые правила нацелены только на внешний вид по умолчанию, и они, как правило, представляют собой что-то вроде сброса настроек браузера по умолчанию, тогда как блок темы — это скорее тип стиля, придающий окончательный вид, уникальный для этой конкретной цветовой схемы.

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

Методологии организации CSS

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

Да, вы, вероятно, можете использовать более продвинутые методологии, такие как OOCSS и BEM. Последний охватывает почти весь рабочий процесс интерфейса и его технологии. Селекторы БЭМ могут отлично работать для некоторых людей, но некоторые могут найти их слишком длинными и громоздкими, а также слишком сложными в использовании. Если вам нужно что-то более простое, что легче подобрать и включить в рабочий процесс, а также что-то, что определяет основные правила для вас и вашей команды, SMACSS идеально подходит.

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