Pull to refresh
0
Alconost
Localization in 70+ languages & video production

Пишем CSS лучше и красивее

Reading time9 min
Views22K
Original author: Thomas Lombart


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

Когда при разработке приложений приходилось браться за CSS, это была не самая радостная часть работы. Но ее ведь не избежать, верно? Сегодня порадовать пользователя дизайном приложения настолько важно, что без CSS — никак.

Когда проект только начинается, все идет хорошо. У вас всего пару селекторов: .title, input, #app — проще простого.

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


Это я, когда сражаюсь с CSS

Переведено в Alconost

Моя задача сегодня — научить вас писать CSS лучше. Я хочу, чтобы, взглянув на старые проекты, вы подумали: «О боги! Как можно было написать такое?»

А как же CSS-фреймворки? — спросите вы. Они ведь для этого и придуманы — писать хороший CSS-код.

Правильно. Но у них есть недостатки:

  • Дизайн на выходе часто получается скучный.
  • Бывает сложно сделать нужные настройки или выйти за рамки возможностей фреймворка.
  • Чтобы пользоваться фреймворками, сначала нужно их изучить.

Ну и вы же читаете эту статью — значит, есть причина, правда? Итак, без лишних слов — вперед, научимся писать CSS лучше.

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

SCSS


В примерах я буду использовать SCSS.

SCSS — это препроцессор CSS, по сути — надмножество CSS, которое добавляет некоторые классные возможности, например, переменные, вложенность, импорт и примеси («миксины»).

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

Переменные


В SCSS есть переменные, и основное их преимущество — повторное использование. Предположим, у вас есть палитра цветов для приложения, и основной цвет — синий.

Поэтому синий у вас везде: фон background-color кнопок, цвет color заголовков, ссылок. СИНИЙ — ПОВСЮДУ.

И вдруг синий вам разонравился. Новый фаворит — зеленый.

  • Если вы не использовали переменные, придется изменять все строки, в которых стоит синий.
  • А с переменными достаточно изменить значение одной из них.

// Объявление переменной
$primary-color: #0099ff;
// Ссылка на переменную
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</i> appear {
 0% {
   opacity: 0;
 }
 100% {
   opacity: 1;
 }
}
<i>// header.scss</i>
<b>@import "animations";</b>
h1 {
 animation: appear 0.5s ease-out;
}

Вы могли подумать: «Ага! У него здесь ошибка! Нужно писать _animations.scss, а не animations».

Не-а. SCSS достаточно умен, чтобы понять, что в этом случае речь идет о частичном файле.

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

Если вам интересно — почитайте документацию: она достаточно понятно и хорошо написана.

Упорядочивание CSS-кода: методология БЭМ


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

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

БЭМ помогает решить эту проблему. БЭМ — это соглашение об именовании; расшифровывается как блок, элемент, модификатор.

Эта методология поможет структурировать код, сделать его более модульным и упростить повторное использование. Разберемся, что же значат «блок», «элемент» и «модификатор».

Блоки


Блок можно представить себе как компонент. Возьмем, к примеру, конструктор Lego.

Как из конструктора сделать простой дом? Понадобятся окно, крыша, дверь, пару стен — и всё. Как раз это и есть наши блоки — они несут смысл сами по себе.

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

Элементы


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

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

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


Итак, мы сделали какое-то окно. Теперь нам понадобилось зеленое или, например, маленькое окно. Это будут наши модификаторы. Они представляют собой флаги на блоках и элементах, которые используются для изменения поведения, внешнего вида и т. д.

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

Примечания


  • БЭМ подразумевает именование классов и только классов. Не идентификаторов и не тегов — только классов.
  • Блоки и элементы могут вкладываться в другие блоки и элементы, но они должны быть полностью независимыми. Обязательно независимыми. Поэтому не нужно добавлять кнопке поля, чтобы она была под заголовком, иначе она будет привязана к заголовку. Лучше использовать вспомогательные классы.
  • Да, HTML-файл будет перегружен, но это не страшно: преимущества БЭМ перевешивают этот недостаток.

Пример


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

Например, такую картину я могу вообразить в магазине Google:



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

Упорядочивание CSS-файлов: принцип «7–1»


Я вас еще не утомил? Отлично! Давайте разберемся, как же упорядочить CSS-файлы. Это здорово повысит эффективность работы и поможет мгновенно находить CSS-код, который нужно поправить.

Пришло время познакомиться с принципом «7–1».
Эти цифры ни о чем вам не говорят, да?

Но всё довольно просто. Нужно следовать двум правилам:

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

Семь папок:


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

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


Сюда импортируются все частичные файлы.

@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: скорее всего, у небольшого приложения будет всего одна тема. Наконец, не будет и стилей для конкретных страниц — поэтому убираем соответствующую папку. Итак, осталось четыре папки — отлично!

Теперь у нас два варианта:

  1. Если следовать принципу «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.

Интерфейс у него довольно простой:

node-sass <вход> <выход> [параметры]

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

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

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

  • Создаем проект: 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"
 },
 …
}

  • Добавляем ссылку на скомпилированный CSS-файл в тег head файла index.html:

<!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">
 <b><link rel="stylesheet" href="css/style.css"></b>
 <title>My app</title>
</head>
<body>
 <h1 class="heading">My app</h1>
</body>
</html>

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

Кое-что еще


Перезагрузка на лету


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

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

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

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

Автоматические префиксы


Мы настроили инструменты разработки — отлично! Теперь поговорим об инструментах сборки, в частности — об этом: Autoprefixer.
Этот инструмент (а точнее, плагин «postcss») анализирует CSS и добавляет к правилам CSS префиксы поставщиков, используя значения из Can I Use.

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

Пример того, как оно будет выглядеть:

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

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

Итак, чтобы собрать CSS:

  1. Компилируем все SCSS-файлы в один CSS-файл.
  2. Добавляем префиксы, используя 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",
<b>   "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"</b>
 …
}

Теперь при запуске npm run build будут добавлены префиксы поставщиков, а сам CSS-код будет сжат. Просто магия!

А хотите еще немножко волшебства? Я поднял репозиторий — чтобы вы могли разобраться побыстрее?

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

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



О переводчике

Перевод статьи выполнен в Alconost.

Alconost занимается локализацией игр, приложений и сайтов на 68 языков. Переводчики-носители языка, лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджеры проектов 24/7, любые форматы строковых ресурсов.

Мы также делаем рекламные и обучающие видеоролики — для сайтов, продающие, имиджевые, рекламные, обучающие, тизеры, эксплейнеры, трейлеры для Google Play и App Store.

Подробнее
Tags:
Hubs:
+6
Comments30

Articles

Information

Website
alconost.com
Registered
Founded
2004
Employees
201–500 employees