Статьи

Атомная OOBEMITSCSS

Люди любят называть вещи. И разработчики любят аббревиатуры. И вот мы здесь, находясь со всеми этими соглашениями и методологиями именования CSS: BEM , SMACSS , Point North , ITCSS , OOCSS , Title CSS , Idiomatic CSS , Atomic Design , SUIT CSS , Kickoff CSS и т. Д.

Мы часто слышим «Вы используете OOCSS или BEM?», Но эти вещи не являются взаимоисключающими. Фактически, в большинстве случаев мы берем концепции и идеи вышеупомянутых идеологий и смешиваем их, настраивая их в соответствии с нашими потребностями (без каламбура).

Так что я использовал в эти дни? Ну, это было бы атомное OOBEMITSCSS. Ага. Атомная OOBEMITSCSS.

Смотреть стать CSS-героем вашего офиса с CSS-архитектурой
Craft структурированный, поддерживаемый и масштабируемый CSS

Впервые я услышал этот нелепый термин из твита Дана Идена , который написал в Твиттере:

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

Атомный CSS

Начнем с атомного дизайна . Атомный дизайн — методология системного мышления, укрепленная Брэдом Фростом . После дальнейших исследований, чтобы выяснить, как это связано со стилем, я наткнулся на эту статью об Atomic Sass. Хотя я не использую описанную там структуру каталогов, я использую концепции и идеи, выраженные методологией атомного дизайна Брэда, в проектных работах и ​​распространяю их на свои разработки (с помощью модулей и компонентов Sass).

Суть в основном заключается в том, чтобы проектировать и развивать с точки зрения системного мышления — создавать отдельные молекулы или элементы, которые, будучи объединены и объединены вместе, создают сеть из модулей, компонентов и, в конечном итоге, целых систем макетов. (Официально существует 5 компонентов: атомы, молекулы, организмы, шаблоны и страницы). Вы можете увидеть это в следующем примере:

Возьмите этот пример с моей доски Pinterest:

открытка

Здесь мы видим карту. Эта карта состоит из нескольких атомов :

  • текст подписи
  • текст заголовка (тип пин-кода)
  • основной текст (подпись)
  • текст выноски (сообщение)
  • текст выноски (заголовок)
  • изображение выноски (мини-доска)
  • исходные иконки
  • местные иконы
  • числовая обработка
  • основное изображение
  • циркуль

Затем они объединяются в наборы молекул :

  • Изображение и цитата (основное изображение + значок источника + текст подписи)
  • Метаданные булавки (текст пин-кода + час + основной текст + [локальная иконка + цифровая обработка] x2)
  • Выноска (изображение выноски + текст выноски (сообщение) + текст выноски (заголовок))

Затем эти молекулы составляют организм, то есть саму карту:

  • (Изображение и цитирование) + (метаданные Pin) + делитель + (выноска)

Домашняя страница Pinterest полна этих организмов . Они составляют большую часть макета домашней страницы:

Главная страница Pinterest

Эти элементы повторно используются и смешиваются в других местах на сайте:

Pin It Модальный

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

Нажав на изображение

Это вид от нажатия на само изображение. Обратите внимание на то, как одинаковая обработка заголовка и значок * type * pin и source следуют за нами в обоих этих представлениях на сайте. Атомное мышление позволяет нам создавать модульные, согласованные системы проектирования.

BEM

БЭМ — это система, которую я использую для разметки. БЭМ обозначает блок, элемент, модификатор . Это особенно полезно для огромной команды, вроде той, в которой я сейчас работаю в IBM. Я написал пост об этом один раз, но другие люди написали лучшие посты с тех пор (я не могу поверить, что это был 2013 год!).

Итак, давайте вернемся к нашему первому примеру карты:

открытка

Как бы мы это отметили? Ну, мы бы сначала разделили разметку на основе ее атомной структуры. Это означает, что мы начнем с самого базового уровня и продолжим дальше. Давайте выделим небольшой раздел, чтобы изучить его разметку. (примечание: я намеренно игнорирую обработку ссылок и взаимодействия здесь в этом примере, но идеи для их маркировки сохраняются. Использование атомарной разметки позволяет легко повторно использовать действия скрипта при создании компонентов. Т.е. действие по щелчку сердца всегда будет меняться его стиль, например, цвет заливки и увеличение количества сердец)

<div class="card"> <img src="..." alt="..." class="card__source-icon"> <a href="" class="card__source-link"></a> <section class="card__metadata"> <h2 class="metadata__pin-type"></h2> <hr> <p class="metadata__caption"></p> <span class="metadata__pins"></span> <span class="metadata__hearts"></span> </section> <hr> <section class="card__callout"> <img src="..." alt="..." class="callout__board-preview"> <p class="callout__msg"></p> <a href="..." class="callout__board-title"></a> </section> </div> 

Эти имена классов семантичны представленному контенту и разбиты по атомарным молекулам. Эти молекулы становятся блоками в БЭМ. У нас нет модификаторов в вышеприведенном примере, но если мы хотим разделить метаданные сердец (например, если бы * только * сердце было кликабельным), например (обычно я просто использовал бы псевдоэлемент для иконки) мы могли бы написать это так:

 <div class="metadata__hearts"> <a href="..." class="metadata__hearts--icon"></a> <p class="metadata__hearts--count"></p> </div> 

Некоторые утверждают, что это приводит к длинным селекторам (да), но семантически это имеет массу смысла и действительно очищает вашу разметку, ограничивая количество используемых вами классов. Под ограничением я имею в виду, серьезно, старайтесь использовать только ** один класс на элемент **, если можете. Честно говоря, я считаю, что БЭМ бесценен для использования в командах и действительно хорошо работает в объектно-ориентированной манере (читай, друзья!).

OOCSS

OOCSS расшифровывается как объектно-ориентированный CSS . Из мастерской OOCSS Николь Салливан :

По сути, CSS-объект — это повторяющийся визуальный шаблон, который можно абстрагировать в независимый фрагмент HTML, CSS и, возможно, JavaScript. Затем этот объект можно повторно использовать на всем сайте.

Примеры, которые Николь показывает в своей мастерской, используют несколько классов для достижения этого формата, что на данный момент может заставить вас задуматься: «Подождите. Разве это не противоречит БЭМ? Это не обязательно. У нас есть Sass, чтобы все исправить ? Так что меньше OOCSS и больше OOSCSS !

Мне нравится думать о том, как я пишу свой Sass как объектно-ориентированный. Если мы думаем о карте как о «объекте», который включает в себя различные «классы», чтобы составить ее, мы все равно можем сохранить все вложенным красиво и аккуратно, используя всемогущий амперсанд (если вы читали любой из моих предыдущих постов в блоге ты узнаешь, как сильно я люблю амперсанд.

Пример времени! Давайте для этого воспользуемся разделом метаданных, поскольку он является хорошим примером скрытой сложности:

 <section class="card__metadata"> <h2 class="metadata__pin-type"></h2> <hr> <p class="metadata__caption"></p> <span class="metadata__pins"></span> <span class="metadata__hearts"></span> </section> 

Мы хотим мыслить модульно и в сфере объектно-ориентированной инкапсуляции. Иконки — отличное начало:

 %icon { content: ''; display: block; &--pins { @extend %icon; background-image: url('../img/pins.svg'); } &--heart { @extend %icon; background-image: url('../img/heart.svg'); } } 

Ого. Что тут происходит? А) Как я уже говорил ранее, я слишком часто использую амперсанды, поэтому убедитесь, что вы знакомы с ними. Б) Мы создаем невидимый (он же « селектор заполнителя ») в Sass. Это означает, что ни один из этого кода не будет обработан в CSS, пока мы не @extend его. Все наши значки будут иметь некоторые общие свойства (в данном случае, content: '' и display: block ). Затем мы указываем фоновое изображение для каждого отдельного значка, * расширяя * стиль из родительского блока. Это можно сделать с помощью простого цикла @each а значки можно организовать на карте, чтобы сделать вещи чище. Здесь ничего не выводится, но технически это то, что происходит за кадром:

 %icon, %icon--pins, %icon--heart { content: '; display: block; } %icon--pins { background-image: url('../img/pins.svg'); } %icon--heart { background-image: url('../img/heart.svg'); } 

Итак, продолжим, давайте посмотрим, как выглядит блок, когда он написан объектно-ориентированным способом Sassy. Давайте просто получим основание для некоторой типографии, которую мы создадим в момент при создании нашего компонента:

 %font-stack--body { // actual Pinterest font stack (!) font-family: 'Helvetica Neue','Helvetica','ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ','Meiryo','MS Pゴシック',arial,sans-serif; } %font-stack--headers { @extend %font-stack--body; font-weight: 600; //headers are the same typeface as everything else but have a heavier weight } %type--base-body { @extend %font-stack--body; //extend the body stack } %type--base-h2 { @extend %font-stack--headers; //extend headers (which extend body stack and give them a heavier weight) font-size: 1.5em; //font-size adjustment } 

А теперь к молекуле! Вот где это становится действительно вкусным:

 .metadata { &__pin-type { @extend %type--base-h2; //extend base header styling } &__caption { @extend %type--base-body; //extending normal body copy } &__hearts { &:hover { color: red; //unique hover color } &:after { @extend %icon--heart; // extending heart icon on pseudo element } } &__pins { &:hover { color: green; //unique hover color } &:after { @extend %icon--pins; // extending pins icon on pseudo element } } } 

Как это выглядит в CSS? Несмотря на всю вложенность, мы выводим один класс для всего!

 .metadata__pins:after, .metadata__hearts:after { content: '; display: block; } .metadata__pins:after { background-image: url('../img/pins.svg'); } .metadata__hearts:after { background-image: url('../img/heart.svg'); } .metadata__pin-type, .metadata__caption { font-family: 'Helvetica Neue','Helvetica','ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ','Meiryo','MS Pゴシック',arial,sans-serif; } .metadata__pin-type { font-weight: 600; } .metadata__pin-type { font-size: 1.5em; } .metadata__hearts:hover { color: red; } .metadata__pins:hover { color: green; } того, как .metadata__pins:after, .metadata__hearts:after { content: '; display: block; } .metadata__pins:after { background-image: url('../img/pins.svg'); } .metadata__hearts:after { background-image: url('../img/heart.svg'); } .metadata__pin-type, .metadata__caption { font-family: 'Helvetica Neue','Helvetica','ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ','Meiryo','MS Pゴシック',arial,sans-serif; } .metadata__pin-type { font-weight: 600; } .metadata__pin-type { font-size: 1.5em; } .metadata__hearts:hover { color: red; } .metadata__pins:hover { color: green; } 

Bellisimo!

ITCSS

Хорошо, это то, где мы собираем все это вместе. Мы почти на финише! Так. Давайте поговорим об ITCSS. Прежде всего, что такое ITCSS ? Хорошо, ИТ (смеется) — это методология для создания ваших таблиц стилей, которая отвечает на неотложный вопрос о том, как, черт возьми, я заказываю свои стили?

Вот отличное изображение, украденное прямо из блога Гарри Робертса на графике специфики (извините, надеюсь, вы не против!)

По сути:

Вот как выглядит ваш график специфичности (вероятно):

График специфичности

Вот как должен выглядеть ваш график специфичности:

Специфичность График Идеал

График специфичности — это анализ специфики вашего кода CSS. При использовании оператора !important Important и переопределении вашего кода раньше, чем необходимо, он создает эти драматические пики, заставляя вас затем снова его переопределить, чтобы переопределить слишком специфичное переопределение. Вы понимаете, почему это проблематично? Это не только сбивает с толку и не является семантическим, но также заставляет вас писать менее производительный код и создавать большие таблицы стилей из-за всех ваших переопределений. Ваш размер таблицы стилей может быть представлен как область под графиком.

Как, спросите вы? В приведенном выше примере мы видим, что сначала мы предоставляем самые широкие стили, а затем мы применяем только определенные стили, когда это необходимо, к элементу или модификатору. В противном случае мы расширяем существующий код, который был создан ранее в потоке стилей. Это помогает организовывать ваши таблицы стилей по модульному принципу и использовать первые несколько импортов в качестве помощников или переменных, которые не выводят CSS (например, селекторы-заполнители для значков и типографики). Я мог (и написал) целые посты на эту тему (и даже создал инструмент для создания вашей архитектуры таблиц стилей, вынуждая вас планировать маршрут, прежде чем углубляться в него).

Итак, вот оно, Атомная OOBEMITSCSS .