Главная | Все статьи | Код

10 полезных практик при написании CSS

Время чтения статьи ~11 минут
10 полезных практик при написании CSS главное изображение

Написание таблиц стилей не заканчивается использованием свойств и подбором значений исходя из шаблона. Это объёмный процесс, который включает:

  • Грамотное именование
  • Структурированность
  • Понятность селекторов
  • Хорошую переиспользуемость
  • Соответствие принципам доступности
  • Оптимизацию

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

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

Практика № 1: организация рабочей среды

Запись стилей напрямую в файл .css может сопровождаться различными проблемами. Множество ошибок в проекте случается из-за забытой точки с запятой или неправильно закрытой фигурной скобки. Частое копирование одних и тех же CSS-стилей тоже не приносит удобства для будущих изменений.

Сейчас существует много инструментов, которые позволяют автоматизировать процессы вёрстки и сделать написание CSS более осмысленным. В первую очередь это использование препроцессоров. Неважно, какой именно вы используйте препроцессор: SASS, Less или Stylus — они позволяют удобнее выносить повторяющийся CSS, а так же определить функции для работы с кодом.

Сравните написание одного и того же кода с помощью CSS и препроцессора SASS

.icon-32-cat {
  height: 32px;
  width: 32px;
  background: url("../icon/svg/32/cat.svg");
}

.icon-64-cat {
  height: 64px;
  width: 64px;
  background: url("../icon/svg/64/cat.svg");
}

.icon-32-dog {
  height: 32px;
  width: 32px;
  background: url("../icon/svg/32/dog.svg");
}

.icon-64-dog {
  height: 64px;
  width: 64px;
  background: url("../icon/svg/64/dog.svg");
}

.icon-128-dog {
  height: 128px;
  width: 128px;
  background: url("../icon/svg/128/dog.svg");
}

.icon-32-whale {
  height: 32px;
  width: 32px;
  background: url("../icon/svg/32/whale.svg");
}

.icon-64-whale {
  height: 64px;
  width: 64px;
  background: url("../icon/svg/64/whale.svg");
}
$icons: (
  "cat": (32, 64),
  "dog": (32, 64, 128),
  "whale": (32, 64)
);

@mixin icon($icon-name, $icon-size) {
  .icon-#{$icon-size}-#{$icon-name} {
    height: $icon-size;
    width: $icon-size;

    background: url("../icon/svg/#{$icon-size}/#{$icon-name}.svg");
  }
}

@each $icon, $sizes in $icons {
  @each $size in $sizes {
    @include icon($icon, $size);
  }
}

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

В случае с SASS был определён миксин, который генерирует иконку в зависимости от переданных данных и цикл, в котором вызывается миксин. Для добавления новых иконок достаточно изменить массив $icons. Остальное препроцессор сделает за нас.

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

Последним в списке, но не по назначению, является линтер — пакеты, которые проверяют CSS на следование стандартам. Это позволяет стандартизировать стили и не допустить досадных ошибок. Самым популярным линтером для CSS на сегодня является Stylelint. Именно его можно увидеть при прохождении курсов по вёрстке на Hexlet.

Сравните код, который написан без использования линтера:

body {
  line-height: 1.5;
  margin: 0px;
  font-size: 16px;
  color: #303846;
  padding: 0;
  background: #f0f3f4;
  font-family: sans-serif;
}

и с линтером:

body {
  margin: 0;
  padding: 0;

  color: #303846;
  font-size: 16px;
  font-family: sans-serif;
  line-height: 1.5;

  background: #f0f3f4;
}

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

Практика № 2: (не) использование фреймворка

CSS-фреймворк — набор модулей, компонентов и расширений, которыми можно пользоваться в проекте. Одним из самых популярных фреймворков на сегодня является Bootstrap. Это мощный инструмент, но надо понимать, что загрузка Bootstrap негативно сказывается на времени загрузки всего проекта. Минифицированный файл стилей Bootstrap 4 весит 156 килобайт. Для корректной работы также необходимы JavaScript-файлы.

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

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

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

Практика № 3: разделение стилей

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

Пример на SASS. Главный файл:

@import "variables";
@import "mixin";

// Components
@import "./components/avatar";
@import "./components/contact";
@import "./components/messages";
@import "./components/message";

// Utitlies
@import "./utilities/width";
@import "./utilities/height";
@import "./utilities/hide-scrollbar";
@import "./utilities/border";
@import "./utilities/radius";

Этот пример плавно подводит к следующему пункту.

Практика № 4: переменные для настроек проекта

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

  • Цветовая схема
  • Отступы
  • Шрифт
  • Базовый размер шрифта

Используя препроцессор, можно указать все стили в едином файле variables или settings. Теперь управление базовыми настройками будет происходить из одного файла.

Читайте также Зачем изучать HTML и CSS, или Когда роботы заменят верстальщиков на рынке труда

Практика № 5: уменьшение специфичности

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

.main section p.main-title {
  color: #333;
  font-size: 20px;
}

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

Уменьшив специфичность, можно использовать класс на любом HTML-элементе при любой структуре.

.main-title {
  color: #333;
  font-size: 20px;
}

Практика № 6: группировка стилей

В статье Что верстальщик должен знать про OOCSS и организацию CSS описывалась одна из распространённых методологий — OOCSS. Она позволяет разделять структурные и визуальные стили элемента. Помимо такого разделения использование методологий позволяет не дублировать повторяющиеся стили.

Распространённый пример:

.btn {
  width: 150px;
  height: 50px;
  font-size: 13px;
  background: white;
  border: 1px solid #333;
}

.btn-order {
  width: 150px;
  height: 50px;
  font-size: 13px;
  background: blue;
  border: 1px solid #333;
}

В примере находятся стили для двух кнопок, но они различаются только одним свойством. Остальные стили полностью повторяются. Это приводит к невозможности быстро изменить общие стили для кнопок. Решение достаточное простое — выделить отдельный класс под структурные свойства.

.btn {
  width: 150px;
  height: 50px;
  border: 1px solid;

  font-size: 13px;
}

.btn-white {
  color: #333;
  background: white;
}

.btn-blue {
  color: #f9f9f9;
  background: blue;
}

Данный приём доступен как для CSS, так и для препроцессоров. Некоторые методологии ориентированы на полную изоляцию модулей друг от друга. В таком случае можно использовать миксины и переменные для создания таких стилей. Главное — возможность изменения свойств в одном месте. Вот как это может выглядеть на SASS:

// Button Settings
$btn-width: 150px;
$btn-height: 50px;
$btn-border: 1px solid;
$btn-font-size: 13px;

@mixin btn($color-bg, $color-text) {
  width: $btn-width;
  height: $btn-height;
  border: $btn-border;

  color: $color-text;
  font-size: $btn-font-size;

  background: $color-bg;
}

.pricing {
  padding: 20px 40px;
  color: #333;

  .pricing-btn {
    @include btn(#f9f9f9, #333);
  }
}

Практика № 7: построение стилей от общего к частному

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

  • Общие классы (утилиты, атомарные классы)
  • Классы, отвечающие за общий вид страницы
  • Классы для различных компонентов

Использование комментариев поможет в быстром ориентировании внутри CSS-файла.

/* General */

body {
  margin: 0;
  padding: 0;
}

h1,
h2,
h3 {
  color: #333;
  font-family: serif;
}

p {
  margin: 0.5em 0 1.2em;
}

/* Utitlities */

.mb-1 {
  margin-bottom: 1em;
}

.text-bold {
  font-weight: 600;
}

/* Pricing */

.pricing {
  display: flex;
  margin: 0 -15px;
}

.pricing__item {
  width: 300px;
  padding: 0 15px;
}

Практика № 8: использование инлайновых стилей

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

<!-- Вместо такого элемента -->
<div style="font-weight: bold"></div>

<!-- Используйте такой -->
<style>
  .text-bold {
    font-weight: bold;
  }
</style>

<div class="text-bold"></div>

Практика № 9: добавление focus к интерактивным элементам

Верстальщики часто добавляют новые интерактивные элементы, которые не знает браузер. Это могут быть кастомные чекбоксы, радиокнопки, кнопки отправки сообщения и так далее. Для удобства используют не стандартные теги, которые предназначены для таких взаимодействий, а простые <div></div> и <span></span>. Здесь кроется главная опасность: проставляя таким элементам стили при наведении с помощью :hover, разработчики забывают про пользователей, которые используют клавиатуры.

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

  • При возможности используйте стандартные HTML-элементы для интерактивных элементов. Даже при случае несовпадения этих элементов с дизайном постарайтесь оставить стандартное отображение или вносите небольшие изменения.
  • Не удаляйте focus у интерактивных элементов. Если такой элемент скрыт в угоду кастомизации, добавьте фокус для новых элементов.
  • Убедитесь, что ваши интерактивные элементы могут взаимодействовать с клавиатурой.

Практика № 10: именование классов

Не стоит забывать про хорошее именование классов. Идеально, если название класса описывает то, что происходит на странице или какой блок перед нами. Подробнее об этом я описывал в статье Ошибки именования в вёрстке. Вот небольшой пример неудачного именования:

.block-1 {
  ...
}

.block-two {
  ...
}

.blok-3 {
  ...
}

Помимо различного вида именования, здесь указан чёткий порядок классов. Если в HTML-элементы поменяются местами, то весь смысл таких классов исчезнет. Определяйте название класса исходя из того, что за элемент перед вами или какие характеристики он имеет. Здесь всё зависит от той методологии, которой вы придерживаетесь.

Изучайте вёрстку на Хекслете — пройдите профессию «Верстальщик». Во время обучения вы выполните три проекта, которые останутся в вашем портфолио на GitHub.

Аватар пользователя Nikita Mikhaylov
Nikita Mikhaylov 13 ноября 2020
25
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 2 мая
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 2 мая
профессия
от 6 183 ₽ в месяц
Ручное тестирование веб-приложений
4 месяца
с нуля
Старт 2 мая
профессия
от 6 300 ₽ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 2 мая
профессия
от 5 025 ₽ в месяц
новый
Сбор, анализ и интерпретация данных
9 месяцев
с нуля
Старт 2 мая
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Laravel
10 месяцев
с нуля
Старт 2 мая
профессия
от 5 840 ₽ в месяц
Создание веб-приложений со скоростью света
5 месяцев
c опытом
Старт 2 мая
профессия
от 9 900 ₽ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 2 мая
профессия
от 6 300 ₽ в месяц
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 2 мая
профессия
новый
Автоматизированное тестирование веб-приложений на JavaScript
8 месяцев
c опытом
в разработке
Старт 2 мая
профессия
Верстка с использованием последних стандартов CSS
5 месяцев
с нуля
Старт в любое время