Логотип Code Guide

Посібник з написання коду

Стандарти для розробки послідовних, легких для редагування та підтримки HTML і CSS.

Автор @mdo · Переклад @igor-baluev · v4.0.0 · GitHub repo

Зміст

HTML

CSS

Золоте правило

Завжди дотримуйтеся цих чи власних узгоджених правил написання коду. Якщо знайшли помилку, велику чи маленьку, дайте знати. Для доповнень або внесків до цього посібника з коду, будь ласка, відкрийте issue на GitHub.

Кожен рядок коду має бути написаний однією особою, незалежно від кількості учасників.

HTML

Синтаксис

<!doctype html>
<html>
  <head>
    <title>Заголовок сторінки</title>
  </head>
  <body>
    <img src="images/company-logo.png" alt="Company">
    <h1 class="hello-world">Вітаю, світ!</h1>
  </body>
</html>

HTML5 doctype

Для більш передбачуваного відтворення сторінок в усіх браузерах застосовуйте стандартний режим за допомогою цього простого типу документа. Дотримуючись запропонованого синтаксису, пишіть у нижньому регістрі.

<!doctype html>
<html>
  <head>
    <!-- ... -->
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

Атрибут мови

Зі спеціфікації HTML5:

Авторам рекомендується вказувати атрибут lang у кореневому елементі html, вказуючи мову документа. Це допомагає інструментам синтезу мовлення визначати, яку вимову використовувати, інструментам перекладу визначати, які правила використовувати, і так далі.

Дізнайтесь більше про атрибут lang у спеціфікації. Перейдіть на сайт IANA, щоб побачити список кодів мов.

<html lang="uk">
  <!-- ... -->
</html>

Режим сумісності з IE

Сьогодні немає потреби включати тег <meta> для сумісності документів в Internet Explorer, якщо вам не потрібна підтримка IE10 і старіших версій. Тег було відкинуто в IE11 і не використовується в Microsoft Edge (у поточній чи попередніх версіях).

Щоб отримати додаткові відомості, прочитайте цю чудову статтю на сайті Stack Overflow.

<!-- IE10 and below only -->
<meta http-equiv="x-ua-compatible" content="ie=edge">

Кодування символів

Забезпечте належне відтворення вмісту, оголосивши явне кодування символів. Це також дозволяє використовувати звичайні символи замість їхніх HTML-сутностей, наприклад замість &emdash;, за умови, що їхнє кодування збігається з кодуванням документа. Для деяких зарезервованих символів XML, як-от амперсанд, нерозривні пробіли, менше/більше та лапки, вам все одно може знадобитися використовувати сутності символів HTML.

UTF-8 є рекомендованим кодуванням.

<head>
  <meta charset="utf-8">
</head>
<body>
  <p>Використовуйте довге тире "—", бо "emdash;" не потрібний в цьому кодуванні.</p>
</body>

Підключення CSS і JavaScript

Відповідно до специфікації HTML5, як правило, немає необхідності вказувати атрибут type, коли підключаються файли CSS і JavaScript, оскільки text/css і text/javascript є відповідними значеннями за замовчуванням.

Посилання на специфікації HTML5:

<!-- Зовнішній CSS -->
<link rel="stylesheet" href="code-guide.css">

<!-- CSS в документі -->
<style>
  /* ... */
</style>

<!-- JavaScript -->
<script src="code-guide.js"></script>

Практичність понад чистоту

Прагніть підтримувати стандарти та семантику HTML, але не на шкоду практичності. Використовуйте найменшу кількість розмітки з найменшою кількістю складнощів, коли це можливо.

<!-- Добре -->
<button>...</button>

<!-- Не добре -->
<div class="btn" onClick="...">...</div>

Порядок атрибутів

Щоб легше було читати код, атрибути HTML краще ставити в такому порядку:

Атрибути, які найчастіше використовуються для ідентифікації елементів, мають стояти на першому місці — class, id, name та data-*. Різноманітні атрибути, унікальні для певних елементів, йдуть на другому місці, за ними йдуть атрибути, пов’язані зі спеціальними можливостями та стилем.

<a class="..." id="..." data-toggle="modal" href="#">
  Посилання
</a>

<input class="form-control" type="text">

<img src="..." alt="...">

Булеві атрибути

Булевий атрибут — це атрибут, який не потребує наданого значення. XHTML вимагав надавати значення таким атрибутам, але HTML5 не має такої вимоги.

Для подальшого читання зверніться до секції WhatWG про булеві атрибути

Наявність булевого атрибута елемента представляє істине значення, а відсутність атрибута представляє хибне значення.

Якщо вам необхідно включити значення атрибута, а це не потрібно, дотримуйтеся цієї вказівки WhatWG:

Якщо атрибут присутній, його значенням має бути порожня строка або […] канонічне ім’я атрибута без пробілів на початку або в кінці.

Тобто, наприклад, checked="checked" або checked="".

Якщо підсумувати, не додавайте значення булевим атрибутам.

<input type="text" disabled>

<input type="checkbox" value="1" checked>

<select>
  <option value="1" selected>1</option>
</select>

Зменшуйте кількість розмітки

По можливості уникайте зайвих батьківських елементів під час написання HTML. Це буде частіше вимагати додаткових ітерацій та рефакторингу при розробці сторінок, але HTML буде коротший.

<!-- Не дуже добре -->
<span class="avatar">
  <img src="...">
</span>

<!-- Краще -->
<img class="avatar" src="...">

Налаштування редактора

Встановіть у своєму редакторі такі параметри, щоб уникнути поширених непослідовностей в коді та зайвих- відмінностей:

Спробуйте задокументувати та застосувати ці налаштування до файлу .editorconfig вашого проекту. Для прикладу дивіться такий у Bootstrap. Дізнайтеся більше про EditorConfig.

CSS

Синтаксис

Запитання щодо використаних тут термінів? Див. розділ синтаксису статті CSS у Вікіпедії.

// Поганий CSS
.selector, .selector-secondary, .selector[type=text] {
  padding:15px;
  margin:0px 0px 15px;
  background-color:rgba(0, 0, 0, 0.5);
  box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}

// Гарний CSS
.selector,
.selector-secondary,
.selector[type="text"] {
  padding: 15px;
  margin-bottom: 15px;
  background-color: rgb(0 0 0 / .5);
  box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}

Порядок декларацій

Декларації властивостей мають бути згруповані разом у такому порядку:

  1. Позиціонування
  2. Блочна модель
  3. Типографика
  4. Візуалізація
  5. Інше

Позиціонування стоїть на першому місці, оскільки воно може видалити елемент із звичайного потоку та замінити стилі, пов’язані з блочною моделлю. Блочна модель — flex, float, grid, чи table — відповідає розмірам, розміщенню та вирівнюванню компонента. Усе інше відбувається всередині компонента або без впливу на попередні два розділи, тому вони йдуть останніми.

Хоча border є частиною блочної моделі, більшість систем скидають box-sizing на border-box, щоб border-width не впливала на загальні розміри. Це, у поєднанні зі збереженням border поблизу з border-radius, є причиною того, чому він знаходиться в розділі “Візуалізація”.

Міксини та функції препроцесора мають з’являтися там, де це найбільше підходить. Наприклад, міксин border-top-radius() буде замінювати властивості border-radius, а функція responsive-font-size() – замість font-size.

Щоб отримати повний список властивостей і їх порядок, перегляньте порядок властивостей для Stylelint, який використовується у Bootstrap.

.declaration-order {
  // Позиціонування
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  // Блочна модель
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 100px;

  // Типографика
  font: normal 14px "Helvetica Neue", sans-serif;
  line-height: 1.5;
  color: #333;
  text-align: center;
  text-decoration: underline;

  // Візуалізація
  background-color: #f5f5f5;
  border: 1px solid #e5e5e5;
  border-radius: 3px;

  // Інше
  opacity: 1;
}

Булеві властивості

Булеві властивості є альтернативою властивостям напрямку і розміру, таких як блоковий і рядковий. За замовчуванням блок відноситься до вертикального напрямку (з гори до низу), тоді як рядковий відноситься до горизонтального напрямку (праворуч і ліворуч). Ви можете почати використовувати ці значення у своєму CSS у всіх сучасних браузерах.

Навіщо використовувати булеві властивості? Не в кожній мові написання йде з ліва на право, як в українській, тому режим написання має бути гнучким. За допомогою булевих властивостей ви можете легко підтримувати мови, які можна писати горизонтально або вертикально (наприклад, китайську, японську та корейську). Крім того, вони зазвичай коротші та простіші для написання.

Додаткове читання:

// Без булевих властивостей
.element {
  margin-right: auto;
  margin-left: auto;
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
}

// З булевими властивостями
.element {
  margin-inline: auto;
  border-block: 1px solid #eee;
}

Кольори

Завдяки підтримці CSS Color Levels 4 у ​​всіх основних браузерах rgba() і hsla() тепер є тотожніми з rgb() і hsl(), тобто ви можете змінювати альфа-значення (прозорість) в rgb() і hsl(). Разом із цим з’являється підтримка нового синтаксису значень кольорів, розділених пробілами. Для сумісності з майбутніми функціями кольорів CSS використовуйте цей новий синтаксис.

Незалежно від ваших значень кольорів і синтаксису, завжди переконайтеся, що вибрані кольори відповідають мінімальному коефіцієнту контрастності WCAG (4.5:1 для шрифта 16 пікселів і менше, 3:1 для більших шрифтів).

Додаткове читання:

.element {
  color: rgb(255 255 255 / .65);
  background-color: rgb(0 0 0 / .95);
}

Уникайте використання @import

Порівняно з <link>, @import повільніший, генерує додаткові запити ресурсів і може спричинити інші непередбачені проблеми. Уникайте їх і замість цього оберіть альтернативний підхід:

Для отримання додаткової інформації прочитайте цю статтю Стіва Соудерса.

<!-- Використовуйте елементи link -->
<link rel="stylesheet" href="core.css">

<!-- Уникайте використання @import -->
<style>
  @import url("more.css");
</style>

Розміщення @media

Розташовуйте @media запити якомога ближче до відповідних наборів правил, коли це можливо. Не об’єднуйте їх усі в окрему таблицю стилів або в кінці документа. Це лише полегшить людям сумувати за ними в майбутньому. Ось типове налаштування.

.element { ... }
.element-avatar { ... }
.element-selected { ... }

@media (min-width: 480px) {
  .element { ...}
  .element-avatar { ... }
  .element-selected { ... }
}

Одиночні декларації

У випадках, коли набір правил містить лише одну декларацію, подумайте про видалення розривів рядків для зручності читання та швидшого редагування. Будь-який набір правил із декількома оголошеннями має бути розділений на окремі рядки.

Ключовим фактором тут є виявлення помилок, наприклад, валідатор CSS повідомляє, що у вас є синтаксична помилка в рядку 183. За допомогою однієї декларації її неможливо пропустити. З кількома деклараціями окремі рядки є обов’язковими для вашого розуму.

// Одиночні декларації в один рядок
.span1 { width: 60px; }
.span2 { width: 140px; }
.span3 { width: 220px; }

// Декілька декларацій, кожна займає свій рядок
.sprite {
  display: inline-block;
  width: 16px;
  height: 15px;
  background-image: url("../img/sprite.png");
}

Скорочена нотація

Обмежте використання скорочених декларацій випадками, коли ви повинні явно встановити всі доступні значення. Часто використовувані скорочені властивості включають:

Зазвичай нам не потрібно встановлювати всі значення, які представляє скорочена властивість. Наприклад, заголовки HTML встановлюють лише верхнє та нижнє значення margin, тому, коли необхідно, замінюйте лише ці два значення. Значення 0 означає заміну стандартного значення браузера або попереднього значення.

Надмірне використання скорочених властивостей призводить до більш неохайного коду з непотрібними замінами та ненавмисними побічними ефектами.

Mozilla Developer Network має чудову статтю про скорочені властивості для тих, хто не знайомий із цією нотацією.

// Поганий приклад
.element {
  margin: 0 0 10px;
  background: red;
  background: url("image.jpg");
  border-radius: 3px 3px 0 0;
}

// Гарний приклад
.element {
  margin-bottom: 10px;
  background-color: red;
  background-image: url("image.jpg");
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
}

Вкладеність в препроцесорах

За можливості уникайте непотрібної вкладеності в препроцесорах — будьте простими та уникайте зворотного вкладення. Розглядайте вкладеніcть лише в тому випадку, якщо ви повинні застосувати стилі до батьківського елемента та якщо для вкладення є кілька елементів.

Додаткове читання:

// Без вкладеності
.table > thead > tr > th { ... }
.table > thead > tr > td { ... }

// З вкладеністю
.table > thead > tr {
  > th { ... }
  > td { ... }
}

// Зворотна вкладеність - це дуже спантеличує
.child {
  .parent & { ... }
}

Оператори в препроцесорах

Для кращої читабельності візьміть усі математичні операції в дужки з одним пробілом між значеннями, змінними й операторами.

// Поганий приклад
.element {
  margin: 10px 0 @variable*2 10px;
}

// Гарний приклад
.element {
  margin: 10px 0 (@variable * 2) 10px;
}

Коментарі

Код пишуть і підтримують люди. Переконайтеся, що ваш код є само-описовим, добре прокоментованим і зрозумілим для інших. Чудові коментарі до коду передають контекст або мету. Не повторюйте просто назву компонента чи класу. Використовуйте // синтаксис під час написання CSS із препроцесорами. Під час підготовки CSS для продакшена видаліть усі коментарі.

Великі коментарі обов’язково пишіть повними реченнями, а примітки - короткими фразами.

// Поганий приклад
// Модальний заголовок
.modal-header {
  ...
}

// Гарний приклад
// Елемент-обгортка для .modal-title та .modal-close
.modal-header {
  ...
}

Імена класів

Також корисно застосовувати багато з цих самих правил під час створення настроюваних властивостей і імен змінних препроцесора.

// Поганий приклад
.t { ... }
.red { ... }
.header { ... }

// Гарний приклад
.tweet { ... }
.important { ... }
.tweet-header { ... }

Селектори

Додаткове читання:

// Поганий приклад
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }

// Гарний приклад
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }

Дочірні та нащадкові селектори

За потреби може бути корисним використовувати дочірній комбінатор (>), щоб обмежити каскад деяких стилів у таких елементах, як <table>, які часто є рекурсивно вкладеними. Використовуйте його, щоб обмежити стилі безпосередніми дочірніми елементами батьківського елемента, щоб уникнути непотрібних перевизначень пізніше.

.custom-table > tbody > tr > td,
.custom-table > tbody > tr > th {
  /* ... */
}

Організація

//
// Заголовок секції компонента
//

.element { ... }


//
// Заголовок секції компонента
//
// Іноді потрібно включити додатковий контекст для всього компонента. Зробіть це тут, якщо це досить важливо.
//

.element { ... }

// Дочірній компонент або модифікатор
.element-heading { ... }