Лучшие практики (S)CSS, о которых вы еще не знали

Лучшие практики CSS

Даже если вы сейчас строите свои приложения используя популярные фреймворки, такие как React, Angular или Vue.js, вам все равно нужно добавить к ним какие-нибудь стили. Способ написания стилей зависит от используемой вами технологии. Например, в случае с React, из-за его компонентной природы, лучше писать стили используя CSS-модули. Если вы хотите использовать совершенно новые функции CSS, будет мудро остановить свой выбор на CSSNext. Не забудьте о старых добрых CSS-препроцессорах, таких как Saass или LESS. Возможно, вы думаете: “Так много инструментов. Поручусь, что у них разное написание стилей”. Да, вы правы. Но основа одна и та же.

В этой статье я хочу представить несколько отличных рекомендаций для написания понятного и обслуживаемого CSS, причем неважно, являетесь ли вы поклонником CSS-модулей или Sass/LESS. Данные рекомендации представлены в синтаксисе SCSS, так что стоит немного познакомиться с Sass. Если вы используете простой CSS, расширенный с помощью CSS Next, вам также пригодится эта статья. Приведенные базовые концепции с легкостью могут быть использованы с другими инструментами CSS или препроцессорами.

Структурируйте ваши стили

Хорошо продуманная структура папок поможет с обслуживанием вашего проекта. То же самое касается и ваших стилей. Это важно, разделять ваш код в зависимости от элементов, которые к нему относятся. Сохранение всех ваших директив в одном огромном файле styles.scss наверняка приведет к проблемам. Особенно если вы хотите масштабировать свой проект и добавлять новые компоненты.

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

Ниже приведен пример структуры папки:

├── /base
│  ├── _core.scss
│  ├── _colors.scss
│  ├── _settings.scss
│  └── _typography.scss
├── /utils
│  ├── _animations.scss
│  ├── _easings.scss
│  ├── _grid.scss
│  └── _misc.scss
├── /components
│  ├── _header.scss
│  ├── _footer.scss
│  ├── _button.scss
│  └── _sidebar.scss
└── main.scss

И main.scss:

// *** Vendor ***
@import 'sanitize.css';

// *** Settings ***
@import './base/settings';
@import './base/colors';

// *** Utils ***
@import './utils/easings';
@import './utils/animations';
@import './utils/grid';
@import './utils/ui';

// *** Base ***
@import './base/core';
@import './base/typography';

// *** Components ***
@import './components/header';
@import './components/footer';
@import './components/button';
@import './components/sidebar';

Давайте названия цветам

Итак, у вас есть дизайн сайта и вы хотите приступить к написанию кода для макета. Как разумно подойти к управлению цветами в вашем проекте? Вы можете просто записать обозначения цветов прямо в стилевые правила. Но такой подход в будущем принесет проблемы. К счастью, как CSS, так и Sass дают нам переменные.

В Sass вы можете сохранять любое значение в качестве переменной, так что будет разумным сохранять код цвета как переменную. Главным образом мы используем HEX (hexadecimals, шестнадцатеричную систему) для определения значения цвета. Для людей HEX выглядит как шифр, потому что этот формат разрабатывался для компьютеров. Тяжело сказать, какой цвет записан как #7fffd4 или #ffd700 (если вы их понимаете, возможно, вы бы не прошли CAPTCHA-тест). Первый это «аквамарин», а второй — золотой. Не проще ли будет именовать их таким образом?

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

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

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

Вот пример установок цвета:

// Names
$white: #fff;
$black: #000;

$aquamarine: #7fffd4;
$alabaster: #f9f9f9;
$alto: #d9d9d9;
$mine-shaft: #333;

// Roles
$primary: $white;
$secondary: $alabaster;
$accent: $aquamarine;

$text: $mine-shaft;
$border: $alto;

Упрощайте вложенные объявления

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

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

Посмотрите на этот пример:

// Bad
.article {
  .title {
    color: $accent;
  }
  
  .text {
    color: $text;
    
    .img {
      width: 100%;
    }
    
    @media only screen and (min-width: 720px) {
      .text {
        .img {
          width: 300px;
          height: auto;
          margin: 0 auto;
        }
      }
    }
  }
}

// Good
.article {
  .title {
    color: $accent;
  }
  
  .text .img {
    width: 100%;
  }
}

@media only screen and (min-width: 720px) {
  .article {
    .text .img {
      width: 300px;
      height: auto;
      margin: 0 auto;
    }
  }
}

Не переусердствуйте с родительскими ссылками

В Sass можно делать отсылки к селектору родителя. В комбинации со вложенностью, вы можете определить правила для родительского селектора. Например:

.link {
  &:hover {
    color: $accent;
  }
  
  &::after {
    display: inline-block;
    content: '\0362';
    vertical-align: middle;
  }
}

Иногда использование & может вводить в заблуждение. Вот пример плохого использования этого селектора:

.text {
  // compiles to .article .text
  .article & {
    color: $text;
  }
  
  // compiles to .text + .text
  & + & {
    margin-top: 15px;
  }
}

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

Записывайте свойства в правильном порядке

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

  • Контейнер (позиция, отображение, ширина, отступы и т. д.)
  • Текст
  • Фон
  • Граница
  • Другие (по алфавиту).
// Before
.action-button {
  height: 30px;
  z-index: 3;
  background-color: $accent;
  position: fixed;
  width: 30px;
  color: $white;
  bottom: 15px;
  right: 15px;
}

// After
.action-button {
  position: fixed;
  right: 15px;
  bottom: 15px;
  z-index: 3;
  width: 30px;
  height: 30px;
  color: $white;
  background-color: $accent;
}

Используйте соглашение по названиям классов

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

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

Пример:

// Bad
.menu {
  li {
    display: inline-block;
    padding: 0 20px;
    border-bottom: 1px solid $accent;
  }
  
  ul li {
    padding: 0 10px;
    border-bottom: 0; // Unnecessary border reset
  }
}

// Good
.menu-item {
  display: inline-block;
  padding: 0 20px;
  border-bottom: 1px solid $accent;
}

.nested-menu-item {
  padding: 0 10px;
}

Написание обслуживаемых селекторов не так сложно, если мы используем одно из популярных соглашений по именованию классов: BEM, OOCSS или SMACSS. Я предпочитаю BEM, очень популярную методологию, созданную разработчиками Яндекса. Это название является сокращением слов «контейнер», «модификатор» и «элемент» (block, modifier, element). Если вы не знакомы с BEM, я советую почитать документацию.

Вот наш пример после «бемификации»:

.menu {
  &__item { // it compiles to .menu__item
    display: inline-block;
    padding: 0 20px;
    border-bottom: 1px solid $accent;
  }
}

.submenu {
  &__item {
    padding: 0 10px;
  }
}

Пишите описательные медиа-запросы

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

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

// target devices with min width of 768px (possibly tablets) and with wide screen
@media only screen and (min-width: 768px) and (max-device-aspect-ratio: 9 / 16) {
  body {
    font-size: 20px;
  }
}

Чтобы сделать медиа-запросы более дружественными к разработчику, мы можем назначить эти правила переменным. В Sass можно использовать строку как обычный CSS-код при помощи вставки фигурных скобок #{}.

$medium: 768px;
$screen-medium-wide: 'only screen and (min-width: #{$medium}) and (max-device-aspect-ratio: 9 / 16)';

@media #{$screen-medium-wide} {
  body {
    font-size: 20px;
  }
}

Тот же фокус можно использовать для других правил со знаком @ (at-rules). Это может быть удобно для определения комплексных правил @supports.

Добавляйте модульные стили

CSS имеет набор очень полезных селекторов. В большинстве случаев вы используете селектор класса или селектор потомка. Но есть другой селектор, эффективный при написании модульных стилей. Это селектор «ближайшего соседа» (adjacent sibling selector), известный также как селектор плюс.

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

.article {
  &__title {
    color: $accent;
  }
  
  // Applies margin only, when .article__title is present
  &__title + &__text {
    margin-top: 15px;
  }
  
  &__text {
    color: $text;
  }
}

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

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

***
Подписывайтесь на наш канал в Telegram
[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх