Оглавление
Золотое правило
Строго соблюдайте предложенные здесь или свои собственные соглашения. Если вы нашли ошибку, будь она большая или маленькая, сразу сообщите об этом. Если у вас есть что дополнить или вы хотите принять участие в разработке этих соглашений, пожалуйста, создайте issue на GitHub.
Каждая строка кода должна казаться написанной только одним человеком, вне зависимости от количества разработчиков.
Настройки редактора кода
Установите в вашем редакторе следующие настройки, которые помогут избежать распространенных несогласованностей в коде и грязи:
- Использовать мягкие отступы размером в два пробела.
- Обрезать конечные пробелы при сохранении.
- Кодировка файлов UTF-8.
- Добавлять новую строку в конец файлов.
Подумайте над документированием и применением этих настроек в файле .editorconfig вашего проекта. Для примера, ознакомьтесь с файлом настроек для Bootstrap. Узнайте больше об EditorConfig.
Синтаксис
- Используйте мягкие отступы с двумя пробелами — это единственный способ гарантировать, что ваш код будет везде одинаково выглядеть.
- Вложенные элементы должны иметь отступ (два пробела).
- В атрибутах всегда используйте двойные ковычки, но не одинарные.
- Не добавляйте слэш ("/") в конец одиночного тега — Спецификация HTML5 говорит, что это необязательно.
<!DOCTYPE html>
html(lang="en-us")
head
meta(charset="UTF-8")
meta(http-equiv="X-UA-Compatible" content="IE=Edge")
meta(name="viewport" content="width=device-width,initial-scale=1")
title Title page
link(rel="stylesheet", href="css/main.css")
body.page
include blocks/header/header.pug
...
include blocks/text/text.pug
script(src="js/main.js")HTML5 doctype
Укажите в начале каждой вашей HTML-страницы этот тип документа. Это заставит браузер работать в режиме соответствия стандартам, что обеспечит единообразное отображение ваших страниц в разных браузерах.
<!DOCTYPE html>
html
headАтрибут языка
Из спецификации HTML5:
Для указания языка документа авторам рекомендуется прописывать атрибут языка в корневом элементе html. Это поможет инструментам синтеза речи определить какое произношение использовать, а инструментам перевода - какие правила, и так далее.
Подробнее познакомиться с атрибутом lang можно в спецификации.
Список кодов различных языков на Sitepoint.
html(lang="en-us")Режим совместимости Internet Explorer
IE поддерживает использование специального <meta>-тега, который указывает в режиме совместимости с какой версией IE следует отрендерить страницу. Если обстоятельства не требуют какой-то специальной версии IE, то самым правильным будет заставить браузер использовать режим самой последней версии (edge mode).
Для получения дополнительной информации следует познакомиться со статьей на Stack Overflow.
meta(http-equiv="X-UA-Compatible" content="IE=Edge")Кодировка символов
Явно объявив кодировку символов, вы быстро и легко обеспечите правильное отображение вашего контента. При этом, вы сможете избежать использования символьных сущностей в вашем HTML-коде, при условии, что их кодировка совпадает с кодировкой документа (как правило, UTF-8).
head
meta(charset="UTF-8")Подключение CSS и JavaScript
Согласно спецификации HTML5, при подключении CSS и JavaScript файлов не требуется указание атрибута type, так как text/css и text/javascript являются значениями по умолчанию.
Ссылки на спецификацию HTML5:
<!-- Внешний CSS -->
link(rel="stylesheet", href="css/main.css")
<!-- CSS внутри документа -->
style
/* ... */
<!-- JavaScript -->
script(src="js/main.js")Практичность важнее чистоты
Старайтесь соблюдать стандарты HTML и семантику, но не за счет практичности. Используйте меньшее количество разметки с наименьшим числом тонкостей, когда это возможно.
Порядок атрибутов
Для удобства чтения HTML-атрибуты должны быть указаны именно в этом порядке:
classid,namedata-*src,for,type,hreftitle,altaria-*,role
Классы создают для многократно используемых компонентов верстки, поэтому они идут первыми. Идентификаторы более специфичны и должны использоваться умеренно (например, для закладок на странице), поэтому они следуют вторыми.
a(class="..." id="..." data-modal="toggle" href="#") Какая-то ссылка
input(class="form-control" type="text")
img(src="..." alt="...")Логические атрибуты
Логические атрибуты одни из тех, которые не требуют объявленного значения. XHTML требует от вас задать значение, но в HTML5 нет такого требования.
За подробной информацией обратимся к разделу о логических атрибутах на WhatWG:
Наличие логического атрибута у элемента говорит об истинном его значении, а отсутствие атрибута — о ложном.
Если вы должны указать значение атрибута, но вам это не нужно, следуйте этой рекомендации от WhatWG:
Если атрибут присутствует, его значение должно быть либо пустой строкой или [...] каноническим именем атрибута без начальных или конечных пробелов.
Если коротко, то не указывайте значение логическому атрибуту.
input(type="text" disabled)
input(type="checkbox" value="1" checked)
select
option(value="1" selected) 1Сокращение разметки
Всякий раз, когда это возможно, избегайте лишних родительских элементов. Во многих случаях это требует повторения и рефакторинга, но позволяет создать меньшее количество разметки. Посмотрите на следующий пример:
<!-- Неплохо -->
span(class="avatar")
img(src="...")
<!-- Лучше -->
img(class="avatar" src="...")Разметка, генерируемая с помощью JavaScript
Создание разметки с помощью JavaScript делает ее менее производительной, сложной для поиска и редактирования. По возможности избегайте этого.
Подход к разработке стилей
- Mobile first использующий следующие разрешения:
- mobile (экраны шириной от 0 до 640px), стили пишутся без использования медия выражений
- tablet = 40em (экраны шириной от 640px и больше), стили пишутся в медиа выражении @media (min-width: tablet)
- screen = 64em (экраны шириной от 1024px и больше), стили пишутся в медиа выражении @media (min-width: screen)
- screen_large = 90em (экраны шириной от 1440px и больше), стили пишутся в медиа выражении @media (min-width: screen_large)
.element
...
.element-avatar
...
.element-selected
...
@media (min-width: tablet)
.element
...
.element-avatar
...
.element-selected
...
@media (min-width: screen)
.element
...
.element-avatar
...
.element-selected
...
@media (min-width: screen_large)
.element
...
.element-avatar
...
.element-selected
...Синтаксис
- Используйте мягкие отступы с двумя пробелами — это единственный способ гарантировать, что ваш код будет везде одинаково выглядеть.
- При группировке селекторов помещайте каждый селектор на отдельную строку.
- Фигурные скобки не используются.
- После объявления
:не ставится. - Каждое объявление должно находится на отдельной строке для более точного сообщения об ошибках.
- Для свойств, значения которых разделены запятыми, следует оставлять по одному пробелу после каждой запятой (например,
box-shadow). - Не оставляйте пробелов после запятых внтури значений
rgb(),rgba(),hsl(),hsla(), илиrect(). Это помогает различать различные цветовые значения (запятая без пробела) от нескольких значений одного свойства (запятая с пробелом). - Начальный ноль для значений (например,
0.5вместо.5). - Все 16-ичные значения записывайте строчными буквами (в нижнем регистре), например,
#fff. Строчные буквы гораздо легче различить при просмотре файла, поскольку они, как правило, имеют больше уникальных форм. - Используйте короткие 16-ичные значения везде, где это возможно, например,
#fffвместо#ffffff. - Всегда берите в кавычки значения атрибутов внутри селектора, например,
input[type="text"]. В некоторых случаях это делать необязательно, но это является хорошей практикой для поддержки согласованности. - Опускайте единицы измерения при нулевом значении, например,
margin: 0;вместоmargin: 0px;.
Есть вопросы по перечисленным соглашениям? Ознакомьтесь с разделом о синтаксисе статьи о каскадных таблицах стилей на Википедии.
/* Плохой Stylus */
.selector, .selector-secondary, .selector[type=text] {
padding:15px;
margin:0px 0px 15px;
background-color:rgba(0, 0, 0, 0.5);
box-shadow:0 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}
/* Хороший Stylus */
.selector,
.selector-secondary,
.selector[type="text"]
padding 15px
margin 0 0 15px
background-color rgba(0,0,0,0.5)
box-shadow 0 1px 2px #ccc, inset 0 1px 0 #fffПорядок объявления
Объявления свойств должны быть по алфавиту
.declaration-order
background-color #f5f5f5
border 1px solid #e5e5e5
border-radius 3px
bottom 0
color #333
display block
font normal 13px "Helvetica Neue", sans-serif
height 100px
left 0
float right
line-height 1.5
opacity 1
position absolute
right 0
text-align center
top 0
width 100px
z-index 100Место для media query
Помещайте media queries настолько близко к соответствующим наборам правил, насколько это возможно. Не объединяйте их в отдельную таблицу стилей. Не помещайте их в конце файла. В противном случае это приведет к тому, что media queries будут не замечены в будущем. Вот типичная структура:
.element
...
.element-avatar
...
.element-selected
...
@media (min-width: tablet)
.element
...
.element-avatar
...
.element-selected
...Свойства с префиксами
Используется autoprefixer, необходимости в прописывании префиксов нет.
/* Свойства с префиксами */
.selector
box-shadow: 0 1px 2px rgba(0,0,0,.15)Правила с одиночными объявлениями
В случаях, когда набор правил включает в себя только одно объявление, оно пишется, так же как с несколькими. Любой набор правил с несколькими объявлениями должен быть разделен на отдельные строки.
/* Одиночные объявления */
.span1
width 60px
.span2
width 140px
.span3
width 220px
/* Несколько объявлений, по одному на каждую строчку */
.sprite
display inline-block
width 16px
height 15px
background-image url(../img/sprite.png)
.icon
background-position 0 0
.icon-home
background-position 0 -20px
.icon-account
background-position 0 -40pxСокращенная запись
Старайтесь ограничить использование сокращенных объявлений в тех случаях, когда необходимо явно задать все доступные значения. Наиболее часто злоупотребляют сокращением следующих свойств:
paddingmarginfontbackgroundborderborder-radius
Часто нам не нужно устанавливать все значения сокращенной записи свойства. Например, HTML заголовки устанавливают только отступы сверху и снизу, таким образом, в случае необходимости нужно переопределить только эти два значения. Чрезмерное использование сокращенной записи свойств часто приводит к грязному коду с ненужными переопределения и непреднамеренными побочными эффектами.
На сайте 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Вложенность
Избегайте излишнюю вложенность. Лучше вообще не использовать. То, что вы можете ее использовать, не означает, что вы всегда должны это делать. Применяйте вложенность только если вам нужно сократить область видимости стилей до родительского элемента, а также при наличии нескольких элементов, которые должны быть вложены.
// Без вложенности
.table > thead > tr > th
...
.table > thead > tr > td
...
// С вложенностью
.table > thead > tr
> th
...
> td
...Комментарии
Код написан и поддерживается людьми. Убедитесь, что ваш код является описательным, хорошо прокомментирован и доступным (понятным) для других. Хорошие комментарии к коду передают контекст и цель кода, а не просто повторяют название класса или компонента.
Обязательно пишите законченные предложения для больших комментариев и короткие фразы для общих замечаний.
/* Плохой пример */
/* Modal header */
.modal-header
...
/* Хороший пример */
/* Обертывающий элемент для .modal-title и .modal-close */
.modal-header
...Имена классов
- Используется "классическое именование" БЭМ
- Придерживайтесь коротких и емких имен классов настолько, насколько это возможно.
- Используйте осмысленные имена; используйте структурные или целенаправленные имена вместо презентационных.
- Классы с префиксами должны основываться на ближайшем классе-родителе или на каком то базовом классе.
/* Плохой пример */
.t
...
.red
...
.header
...
/* Хороший пример */
.tweet
...
.important
...
.tweet-header
...Селекторы
- Используйте имена классов вместо имен тегов для оптимальной производительности отображения.
- Избегайте использования нескольких селекторов по атрибуту (например,
[class^="..."]) для часто встречающихся компонентов. Это негативно повлияет на производительность браузера. - Используйте короткие селекторы и старайтесь ограничить количество элементов в каждом селекторе до трех.
- Вкладывайте классы в ближайший родительский класс только в случае необходимости (например, когда не используете классы с префиксами).
Дополнительно к прочтению:
/* Плохой пример */
span
...
.page-container #stream .stream-item .tweet .tweet-header .username
...
.avatar
...
/* Хороший пример */
.avatar
...
.tweet-header .username
...
.tweet .avatar
...Организация кода
- Посмотрите организацию файловой системы в README.md
- Организуйте разделы кода согласно вашим компонентам.
- Разработайте последовательную иерархию для комментариев.
- Отделяйте разделы кода несколькими пустыми строками. Это упростит просмотр кода в крупных файлах.
- Когда вы используете множество CSS-файлов, разбивайте их по компонентам, а не по страницам. Страницы могут быть переработаы и компоненты перемещены с одной страницы на другую.
/*
* Заголовок раздела для компонента
*/
.element
...
/*
* Заголовок раздела для компонента
*
* Иногда возникает необходимость включения дополнительного контекста для всего компонента. Сделайте это в этом месте, если это достаточно важно.
*/
.element
...
/* Контекстный под-компонент или модификатор */
.element_heading
...