Как овладеть CSS на более высоком уровне




Перевод How to get better at writing CSS

Не будем ходить вокруг да около: писать отличный CSS-код может быть трудно. Многие разработчики не хотят этим заниматься: «Я могу сделать что угодно, но это нафиг! Никакого CSS». Когда создаёшь приложение, работа с CSS не приносит удовольствия. Но от него никуда не деться, верно? В смысле, мы сегодня так зациклены на пользовательском опыте и дизайне, что пренебречь CSS не получится.

В начале проекта всё работает прекрасно. У вас есть несколько CSS-селекторов: .title input #app, проще простого. Но когда приложение разрастается, оно становится уродливым. Вам уже не нравятся ваши селекторы, и вы начинаете писать конструкции наподобие div#app .list li.item a. Пишете один и тот же код снова и снова. Пихаете весь код в конец файла, потому что вам плевать и CSS отстой. И вот результат: 500 строк CSS, который совершенно невозможно сопровождать.

Сегодня мы хотим помочь вам лучше овладеть CSS. Чтобы вы посмотрели на свои старые проекты и подумали: «Блин, как я мог это написать?»

«Ладно, — можете подумать вы, — убедили. А что насчёт CSS-фреймворков? Ведь они как раз для этого и предназначены, разве нет? Именно так мы и пишем хороший CSS-код».

Само собой. Но у фреймворков есть ряд недостатков:

  • Их использование часто приводит к шаблонному дизайну.
  • Трудно настраивать фреймворки или выходить за пределы их возможностей.
  • Прежде чем использовать фреймворки, нужно их сначала изучить.

Если на то пошло, вы сейчас читаете эту статью, и на то есть причина, верно? Так что без дальнейших разглагольствований давайте лучше разберёмся в CSS.

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

SCSS


В примерах мы будем использовать SCSS. Это CSS-препроцессор. По сути, он представляет собой расширенный набор CSS: добавляет классные возможности вроде переменных, вложенности, импорта и миксинов.

Давайте рассмотрим возможности, которыми сразу и воспользуемся.

Переменные


SCSS позволяет использовать переменные. Их главное преимущество: многократное использование. Предположим, у вас есть палитра цветов для приложения, и основной цвет синий. Вы используете его везде: как background-color кнопок, color шапки, в ссылках. СИНИЙ ВЕЗДЕ.

И вдруг вам разонравился этот цвет. Теперь вы предпочитаете зелёный.

  • Без переменных: придётся изменить каждую строку кода, в которой использован синий цвет.
  • С переменными: просто меняете одну переменную ;)

// Declare a variable
$primary-color: #0099ff;
// References a variable
h1 {
  color: $primary-color;
}

Вложенность


Благодаря SCSS можно использовать вложенность. Тогда этот код

h1 {
  font-size: 5rem;
  color: blue;
}
h1 span {
  color: green;
}

можно превратить в такой:

h1 {
  font-size: 5rem;
  color: blue;
  
  span {
    color: green;
  }
}

Так гораздо удобнее, верно? Благодаря вложенности вы будете тратить меньше времени на написание сложных селекторов.

Частичные файлы и импорт


Когда речь заходит о сопровождении и читабельности, оказывается невозможно хранить весь код в одном большом файле. Это допустимо при экспериментах или создании маленьких приложений, но на профессиональном уровне… даже не пытайтесь. К счастью, SCSS позволяет нам это делать.
Вы можете создавать частичные файлы, давая им имена с открывающим нижним подчёркиванием: _animations.scss, _base.scss, _variables.scss и т.д.

А для импорта мы воспользуемся директивой @import. Например, можно сделать так:

// _animations.scss
@keyframes appear {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
// header.scss
@import "animations";
h1 {
  animation: appear 0.5s ease-out;
}

«Ага!» — подумали вы, — «тут ошибка! Написано _animations.scss, а не animations» ;)

Нифига не ошибка. SCSS достаточно умён и знает, что вы имеете в виду частичный файл, когда вы называете его подобным образом.

Это всё, что вам нужно знать о переменных, вложенности, частичных файлах и импорте. У SCSS есть ещё много других возможностей, например, миксины, наследование и прочие директивы (@for, @if и т. д.), но их мы касаться не будем.

Если нужны подробности, почитайте документацию. Она хорошо написана и легка для понимания.

Организация CSS-кода: методология BEM


Я несметное количество раз давал своим классам всеобъемлющие имена. Ну, вы понимаете: .button .page-1 .page-2 .custom-input.

Мы часто не знаем, как давать правильные имена. А это важно делать. Представьте, что вы делаете приложение, и по какой-то причине решили отложить его на несколько месяцев. Или ещё хуже, кто-то забрал у вас проект. Если ваш CSS-код не будет содержать нормальных имён, то в нём трудно будет разобраться.

Решить эту проблему помогает BEM — соглашение по наименованию, расшифровывается как Block Element Modifier — блок, элемент, модификатор.

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

Блоки


Блок можно считать компонентом. У вас в детстве был конструктор вроде Lego? Как вы строили простой дом? Вам нужны были окно, крыша, дверь, стены, и больше ничего. Это и есть блоки. Они имеют смысл сами по себе.

Именование: имя блока: .block
Примеры: .card, .form, .post, . user-navigation

Элементы


А как вам сделать окно для дома из деталей Lego? Возможно, какие-то из них выглядят как части рамы, и если собрать вместе четыре детали, получится прекрасное окно. Так вот эти детали — элементы. Они являются частями блока и нужны для его создания. Но вне блока элементы бесполезны.

Именование: имя блока + __ + имя элемента: .block__element
Примеры: .post__author, .post__date, .post__text

Модификаторы


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

Именование: имя блока ИЛИ имя элемента + — + имя модификатора: .block__element--modifier, .block--modifier
Примеры: .post--important, .post__btn--disabled

Замечания


  • При использовании BEM вы именуете классами и только классами. Ни ID, ни тегов. Только классы.
  • Блоки/элементы могут быть вложены в другие блоки/элементы, но они должны быть полностью независимые. Запомните это слово: независимые. Так что не вставляйте поля в кнопку потому, что вы хотите поместить её под заголовком, иначе кнопка окажется к нему привязана. Вместо этого используйте утилитарные классы.
  • Да, ваш HTML-файл раздуется, но не переживайте: это не большая плата за преимущества BEM.

Пример


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



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


Организация CSS-файлов: паттерн 7–1


Вы всё ещё тут? Отлично! Посмотрим, как можно организовать CSS-файлы. Эта глава поможет вам стать продуктивнее и вы сразу увидите, где можно модифицировать свой CSS-код. А для этого мы познакомимся с паттерном 7-1.

Всё просто, достаточно следовать двум правилам:

  1. Сохраняйте все частичные файлы в 7 разных папок.
  2. Импортируйте их в один файл main.scss, лежащий в корне. И всё.

7 папок


  • base: сюда кладите весь шаблонный код. Под этим подразумевается CSS-код, который вы будете писать в начале каждого нового проекта. Например: правила типографики, анимации, утилиты (то есть всякие классы вроде margin-right-large, text-center, …) и т.д.
  • components: имя говорит за себя. В этой папке лежат все компоненты, используемые для создания страниц — кнопки, формы, свайпы, всплывающие окна и т.д.
  • layout: используется для шаблонизации разных частей страницы — заголовок, подвал, навигация, секции, сетка и прочее.
  • pages: иногда у вам может быть страница с каким-то собственным стилем, отличающимся от обычного. Этот стиль кладите в папку pages.
  • themes: если для вашего приложения есть несколько тем (тёмный режим, администраторская и т. д.), кладите их в эту папку.
  • abstracts: сюда кладите все функции, переменные и миксины. То есть это папка для вспомогательных средств.
  • vendors: у каких приложений или проектов нет внешних библиотек? В эту папку кладите все файлы, которые от вас не зависят.

Основной файл


Импортируем все частичные файлы:

@import abstracts/variables;
@import abstracts/functions;
@import base/reset;
@import base/typography;
@import base/utilities;
@import components/button;
@import components/form;
@import components/user-navigation;
@import layout/header;
@import layout/footer;
...

Ну да, выглядит громоздко. Именно так вы и должны были подумать. Эта архитектура адаптирована под большие проекты, а не маленькие. Так что поговорим о версии для проектов поскромнее.

Прежде всего, вам не нужна папка vendors. Размещайте весь внешний CSS-код в шапке с тегом link. Также можете отказаться от папки themes, если у вас в приложении будет лишь одна тема. Наконец, если не будете использовать на страницах много специфических стилей, то можете избавиться и от папки pages. Осталось 4 папки!

У вас есть выбор:

  1. Хотите организовать CSS-код и следовать паттерну 7–1, тогда сохраните папки abstracts, components, layout и base.
  2. Предпочитаете одну большую папку со всеми частичными файлами и main.scss, тогда используйте что-то подобное:

    sass/
      _animations.scss
      _base.scss
      _buttons.scss
      _header.scss
      ...
      _variables.scss
      main.scss


Вам решать.

«Убедили! Но как мне это использовать? Ведь браузеры не поддерживают SCSS-файлы».
Верно подмечено! И теперь мы узнаем, как SCSS компилировать в CSS.

Из SCSS в CSS


Для этого нам понадобятся Node.js и NPM (или Yarn).

Воспользуемся пакетом node-sass, который позволяет компилировать .scss-файлы в .css-файлы. Его CLI (Command Line Interface) прост в использовании:

node-sass <inрut> <outрut> [options]

Тут можно использовать разные опции, но нам хватит двух:

  • -w: отслеживание директории или файла. Это означает, что node-sass отслеживает изменения в коде, которые автоматически компилируются в CSS. Действительно полезно в разработке.
  • --output-style: что мы получим на выходе из CSS-файла, одно из: nested|expanded|compact|compressed.

Если вы любопытны (надеемся, это так, ведь разработчик должен быть любопытным!), то здесь найдёте всю документацию.

Теперь мы знаем, какими инструментами воспользуемся. Дальше ещё проще:

  • Создайте проект: mkdir my-app && cd my-app
  • Инициализируйте его: npm init
  • Добавьте библиотеку: node-sass: npm install node-sass --save-dev
  • Создайте папки и файлы index.html и main.scss:

    touch index.html
    mkdir -p sass/{abstracts,base,components,layout} css
    cd sass && touch main.scss
  • Положите в файл package.json эти скрипты:

    {
      ...
      "scripts": {
        "watch": "node-sass sass/main.scss css/style.css -w",
        "build": "node-sass sass/main.scss css/style.css --output-style compressed"
      },
      ...
    }
  • Добавьте в тег head файла index.html ссылку на скомпилированный CSS-файл:

    <!DOCTYPE html>
    <html lang=”en”>
    <head>
      <meta charset=”UTF-8">
      <meta name=”viewport” content=”width=device-width, initial-scale=1.0">
      <meta http-equiv=”X-UA-Compatible” content=”ie=edge”>
      <link rel=”stylesheet” href=”css/style.css”>
      <title>My app</title>
    </head>
    <body>
      <h1 class=”heading”>My app</h1>
    </body>
    </html>

Вот и всё! Когда будете кодить, выполните npm run watch и откройте в браузере index.html. Если хотите минифицировать CSS, просто выполните npm run build.

Бонусы


Добавляем горячую перезагрузку live reload


Для повышения продуктивности вам может понадобиться горячая перезагрузка вместо ручной перезагрузки локального index.html.

Для этого:

  • Установите пакет live-server: npm install -g live-server
    Обратите внимание: это глобальный пакет.
  • Добавьте npm-run-all в зависимости проекта: npm install npm-run-all --save-dev: это позволит одновременно исполнять много скриптов.
  • Добавьте в package.json эти скрипты:

    {
      ...
      "scripts": {
        "start": "npm-run-all --parallel liveserver watch",
        "liveserver": "live-server",
        "watch": "node-sass sass/main.scss css/style.css -w",
      },
      ...
    }

Теперь выполните npm run start и будете сразу видеть все изменения.

Добавляем автоматический префиксер


Отлично, инструменты для разработки настроены! Теперь поговорим об инструменте для сборки: Autoprefixer (postcss-плагин). Он парсит CSS и добавляет к правилам вендорские префиксы, используя значения с Can I Use.

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

Например:

-webkit-animation-name: myAnimation;
-moz-animation-name: myAnimation; 
-ms-animation-name: myAnimation;


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

Итак, нам нужно:

  1. Компилировать все SCSS-файлы в один основной CSS-файл.
  2. Запрефиксить CSS-файл с помощью Autoprefixer.
  3. Сжать CSS-файл.

Остался последний, третий шаг, так что не расходитесь, мы почти закончили:

  • Добавляем две зависимости, postcss-cli и autoprefixer: npm install autoprefixer postcss-cli --save-dev
  • Модифицируем скрипт build и добавляем в package.json эти скрипты:

    {
      ...
      "scripts": {
        "start": "npm-run-all --parallel liveserver watch",
        "liveserver": "live-server",
        "watch": "node-sass sass/main.scss css/style.css -w",
        "compile": "node-sass sass/main.scss css/style.css",
        "prefix": "postcss css/style.css --use autoprefixer -o css/style.css",
        "compress": "node-sass css/style.css css/style.css --output-style compressed",
        "build": "npm-run-all compile prefix compress"
      ...
    }

Если теперь выполнить npm run build, ваш CSS-код будет сжат и будут добавлены вендорские префиксы!

Но знаете, что лучше всего? Мы подготовили для вас репозиторий на тот случай, если хотите быстро начать.


Иииииии на сегодня всё! Теперь вы готовы писать удобный в сопровождении, модульный и многократно используемый CSS-код.




К сожалению, не доступен сервер mySQL