Строго соблюдайте предложенные здесь или свои собственные соглашения. Если вы нашли ошибку, будь она большая или маленькая, сразу сообщите об этом. Если у вас есть что дополнить или вы хотите принять участие в разработке этих соглашений, пожалуйста, создайте issue на GitHub.
Каждая строка кода должна казаться написанной только одним человеком, вне зависимости от количества разработчиков.
Установите в вашем редакторе следующие настройки, которые помогут избежать распространенных несогласованностей в коде и грязи:
Подумайте над документированием и применением этих настроек в файле .editorconfig
вашего проекта. Для примера, ознакомьтесь с файлом настроек для Bootstrap. Узнайте больше об EditorConfig.
<!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="https://gitanon.github.io/css/main.css")
body.page
include blocks/header/header.pug
...
include blocks/text/text.pug
script(src="https://gitanon.github.io/js/main.js")
Укажите в начале каждой вашей HTML-страницы этот тип документа. Это заставит браузер работать в режиме соответствия стандартам, что обеспечит единообразное отображение ваших страниц в разных браузерах.
<!DOCTYPE html>
html
head
Из спецификации HTML5:
Для указания языка документа авторам рекомендуется прописывать атрибут языка в корневом элементе html. Это поможет инструментам синтеза речи определить какое произношение использовать, а инструментам перевода - какие правила, и так далее.
Подробнее познакомиться с атрибутом lang
можно в спецификации.
Список кодов различных языков на Sitepoint.
html(lang="en-us")
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")
Согласно спецификации HTML5, при подключении CSS и JavaScript файлов не требуется указание атрибута type
, так как text/css
и text/javascript
являются значениями по умолчанию.
<!-- Внешний CSS -->
link(rel="stylesheet", href="https://gitanon.github.io/css/main.css")
<!-- CSS внутри документа -->
style
/* ... */
<!-- JavaScript -->
script(src="https://gitanon.github.io/js/main.js")
Старайтесь соблюдать стандарты HTML и семантику, но не за счет практичности. Используйте меньшее количество разметки с наименьшим числом тонкостей, когда это возможно.
Для удобства чтения HTML-атрибуты должны быть указаны именно в этом порядке:
class
id
, name
data-*
src
, for
, type
, href
title
, alt
aria-*
, role
Классы создают для многократно используемых компонентов верстки, поэтому они идут первыми. Идентификаторы более специфичны и должны использоваться умеренно (например, для закладок на странице), поэтому они следуют вторыми.
a(class="..." id="..." data-modal="toggle" href="#") Какая-то ссылка
input(class="form-control" type="text")
img(src="https://gitanon.github.io/..." 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="https://gitanon.github.io/...")
<!-- Лучше -->
img(class="avatar" src="https://gitanon.github.io/...")
Создание разметки с помощью JavaScript делает ее менее производительной, сложной для поиска и редактирования. По возможности избегайте этого.
.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
).#fff
. Строчные буквы гораздо легче различить при просмотре файла, поскольку они, как правило, имеют больше уникальных форм.#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 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
Старайтесь ограничить использование сокращенных объявлений в тех случаях, когда необходимо явно задать все доступные значения. Наиболее часто злоупотребляют сокращением следующих свойств:
padding
margin
font
background
border
border-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
...
/*
* Заголовок раздела для компонента
*/
.element
...
/*
* Заголовок раздела для компонента
*
* Иногда возникает необходимость включения дополнительного контекста для всего компонента. Сделайте это в этом месте, если это достаточно важно.
*/
.element
...
/* Контекстный под-компонент или модификатор */
.element_heading
...