Критерии качества вёрстки 2021

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

С тех пор в разработке интерфейсов произошло море изменений: сначала в продакшн пришли флексы, потом подтянулись гриды, умер IE, все переехали из Фотошопа в Фигму, и много чего ещё. Каждое это изменение влияло на наши критерии, и мы постоянно их дорабатывали.

Сейчас пришло время снова обсудить с сообществом обновлённые критерии, чтобы поделиться наши выпускники продолжали радовать индустрию своим уровнем.

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

Что описывают и что не описывают эти критерии

Эти критерии касаются нашего первого уровня вёрстки, то есть задач, связанных с фиксированной вёрсткой без адаптивности и без специфичных требований к вёрстке (например, по натяжке на конкретную CMS).

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

Как устроена система критериев

На курсе ученик верстает макет (вот такого уровня сложности), и на защите в конце курса эту вёрстку по критериям качества проверяет случайный наставник. Защита считается успешной, если зачтены все обязательные критерии.

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

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

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

TEST-01. Кроссбраузерность

  • Необходимо смотреть на размеры и расположение блоков, внешнее сходство с макетом.

  • Необходимо проверить работу анимации, если такая имеется.

  • Допускаются небольшие отличия в отображениях шрифтов.

Вёрстка должна идентично отображаться в последних стабильных версиях браузеров Chrome, Firefox, Safari, если иное не указано в техзадании проекта.

Назначение критерия

Пользователи сайта могут использовать разные браузеры в разных системах, поэтому нужно добиваться единого отображения.

TEST-02. Технологии

Проект должен быть сделан на HTML и CSS без использования сторонних библиотек и фреймворков.

Назначение критерия

Задача курса — научить решать задачи с помощью базовых технологий. Полученная база позволит разобраться, как работают фреймворки или библиотеки.

TEST-03. Размеры страницы

  • У каждой страницы есть минимальная ширина по фрейму.

  • При ширине окна больше минимальной страница центрируется.

  • Горизонтальная прокрутка появляется только при ширине, меньше минимальной.

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

Примеры и назначение критерия

Скриншот экрана на большом разрешении. Только вертикальный скролл.Скриншот экрана на большом разрешении. Только вертикальный скролл.Если на странице убрать лишние элементы, и выставить разрешение артборда (1020px), то горизонтальный скролл пропадает.Если на странице убрать лишние элементы, и выставить разрешение артборда (1020 px), то горизонтальный скролл пропадает.

Зачем нужен критерий

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

У страницы должна быть минимальная ширина, чтобы у пользователей с меньшим разрешением при просмотре страницы оставались работоспособны все элементы сайта.

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

TEST-04. Переполнение

Длина текста

  • Текст должен оставаться в рамках родительского блока при переполнении.

  • Текст не должен обрезаться или вываливаться из родительского блока при переполнении.

  • Текст не должен смещать другие блоки.

  • Родительский блок должен сохранять минимальные размеры при недополнении.

  • Слова, длиннее минимальной ширины, должны переноситься.

Размеры элементов

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

Количество элементов

  • При увеличении количества элементов они должны оставаться в рамках родительского блока.

  • Элементы могут переноситься на следующую строку при уменьшении размера родителя.

  • При минимальном количестве элементов или их отсутствии родительский блок должен сохранять минимальные размеры.

  • Последние блоки в сетках должны выравниваться по направлению текста.

Примеры и назначение критерия

Длина текста

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

image-loader.svg

Родительский блок должен сохранять минимальные размеры при недополнении.

image-loader.svg

Слова длиннее минимальной ширины должны переноситься.

image-loader.svg

Размеры элементов

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

image-loader.svg

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

Количество элементов

При увеличении количества элементов они должны оставаться в рамках родительского блока и последние блоки должны выравниваться по направлению текста.

image-loader.svg

Элементы могут переноситься на следующую строку при уменьшении размера родителя.

image-loader.svg

При проверке переполнения в браузере Safari необходимо добавлять текст не через инспектор браузера, а через редактор кода, редактируя страницу HTML. В противном случае текст будет добавляться в одну длинную строчку.

Зачем нужен критерий

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

TEST-05. Шрифты

Следующие текстовые параметры должны соответствовать параметрам из макета:

  • семейство шрифта font-family;

  • насыщенность шрифта font-weight;

  • начертание шрифта font-style;

  • размер шрифта font-size;

  • высота строки line-height;

  • цвет текста color.

Назначение критерия

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

TEST-06. Pixel Perfect

При наполнении контентом, как в макете, элементы каждой страницы соответствуют макету.

Допускаются:

  • различия в 5 пикселей по высоте при расстояниях более 30 пикселей и 2 пикселя по ширине;

  • различия в отображении шрифтов, связанные со сглаживанием на различных платформах.

Примеры и назначение критерия

Пример идеального прохождения ПП.Пример идеального прохождения ПП.Пример не идеального, но допустимого несовпадения элементов.Пример не идеального, но допустимого несовпадения элементов.Вариант несовпадения.Вариант несовпадения.Вариант, когда накопились несоответствия по предыдущим блокам. Смещение макета в PixelPerfect исправляет эту проблему.Вариант, когда накопились несоответствия по предыдущим блокам. Смещение макета в PixelPerfect исправляет эту проблему.

Рекомендуем проверять с помощью инструмента PerfectPixel (работает в Chrome, Firefox).

Зачем нужен критерий

Заказчик может не принять работу, если вёрстка будет отличаться от согласованному макета. Поэтому веб-разработчик должен не просто сверстать сайт по образцу, а сделать это близко к согласованному макету.

Чтобы сайт как можно точнее совпадал с утвержденным дизайном, веб-разработчики придерживаются концепции Pixel Perfect. Это способ вёрстки строго по макету, при котором размеры и интервалы из макета соблюдаются с точностью до нескольких пикселей.

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

TEST-07. Стайлгайд

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

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

Для элементов форм, кнопок и ссылок: hover, focus, active.

Для элементов форм: disabled.

Назначение критерия

При проверке этого пункта следует оценивать наличие эффектов и их соответствие стайлгайду.

TEST-08. Взаимодействие

При взаимодействии с элементами (наведение, нажатие) ни сам элемент, ни окружающие его блоки не меняют своего положения, если такое поведение не предусмотрено макетом.

Примеры

Правильно

Неправильно

Неправильно

Неправильно

PROJ-01. Кодгайд

Код должен быть написан с соблюдением требований кодгайда Академии.

Примеры и назначение критерия

Правильно. Код написан в одном стиле.

Новости

Галерея

.news { color: #000000; } .news-title { color: #ff0000; background-color: #ffffff; }

Неправильно. Одинаковые элементы разметки имеют разные отступы и переносы.

Новости

Галерея

Неправильно. Один и тот же цвет написан в разных нотациях.

.news {
  color: red;
}

.news-title {
  color: rgb(255, 0, 0);
  background-color: #ffffff;

Зачем нужен критерий

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

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

PROJ-02. Именование

Названия папок, файлов, атрибутов, классов должны состоять из английских слов.

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

Примеры и назначение критерия

Именование папок и файлов

Правильно. Названия папок и файлов состоят из английских слов.

barbershop/
  styles/
    styles.css
  images/
    logo.svg
    hammer.jpg
    sun.png

Неправильно. Названия папок и файлов написаны транслитом или не словами.

proekt/
  stili/
    stili.css
  SCripts/
    MySctips.js
  i/
    logotip.svg
    098sd9f8sd0f8.png
    imagine image.jpg

Именование классов

Правильно. Названия классов состоят из английских слов.

.header-logo {
  …
}

.footer-social {
  …
}

Неправильно. Названия классов написаны транслитом.

.shapka {
  /* стили */
}

.podval {
  /* стили */
}

.glavniy-logotip {
  /* стили */
}

Правильно. Значения атрибутов состоят из английских слов.



Зачем нужен критерий

Английский язык — это общепринятая договорённость в среде разработчиков. Единый подход именования позволяет быстрее знакомиться с кодовой базой.

PROJ-04*. Закомментированный код

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

Примеры и назначение критерия

Правильно. Комментарий описывает механику взаимодействия с элементом. Таким образом передаются знания от одного разработчика другому.


Правильно. Комментарий скрывает часть разметки, но при этом имеет пояснение, в каком случае эту часть нужно восстановить.


Правильн

Правильно. Комментарии поясняют структуру разметки, позволяя быстрее навигировать по файлу.


  • Пункт
  • Пункт
/* Header */ .header { … } /* Footer */ .footer { … }

Неправильно. Код закомментирован и не имеет описания.

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

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

PROJ-05. Неиспользуемые файлы

В проекте не должно быть неиспользуемых файлов:

  • Файлы, не подключённые на страницы.

  • Подключённые файлы, которые ничего не делают.

Файлы svg-изображений, которые заинлайнены в разметку, могут остаться в папке проекта.

Примеры и назначение критерия

Правильно. Файл slider.css находится в папке проекта и подключен в разметке.

barbershop/
  styles/
    styles.css
    slider.css


  
    

Неправильно. Файл slider.css находится на файловой системе, но не подключен в проекте.

barbershop/
  styles/
    styles.css
    slider.css // не подключён


  

Неправильно. Файл slider.css подключен, но не влияет на стилизацию страницы.

barbershop/
  styles/
    styles.css
    slider.css // подключен, но пустой


  
  

Зачем нужен критерий. Неиспользуемые файлы засоряют файловую структуру и усложняют поддержку сайта.

HTML-01. Ориентиры

На странице, при их наличии, должны быть обозначены структурные ориентиры:

  • для вводной части, повторяющейся на других страницах;

  • для основного содержимого, не повторяющегося на других страницах;

  • для закрывающей, дополнительной информации о странице.

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

Примеры и назначение критерия

Правильно. На странице используются структурные ориентиры. Тега

HTML-04. Работоспособные формы

  • Формы должны быть работоспособными и отправлять данные всех полей.

  • Поля формы должны находиться внутри тега

    .

  • У формы должен быть указан атрибут action.

  • У обязательных полей должен быть атрибут required.

Для тестирования формы можно использовать адрес https://echo.htmlacademy.ru.

Примеры и назначение критерия

Правильно. Форма имеет атрибут action. Все поля формы обёрнуты в тег .


  
  
  


Неправильно. У формы не указан атрибут action.

Неправильно. Форма поиска не обёрнута в тег

.


Неправильно. У полей с обязательным заполнением нет атрибута required.


  

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

Неправильно. Не указано значение у атрибута name или отсутствует атрибут name.

Зачем нужен критерий. Формы — это критическая функциональность сайта, поэтому важно, чтобы они были работоспособны и отправляли введённые пользователем данные.

HTML-05. Подписи полей форм

Подписи полей форм должны быть привязаны к своим полям.

Примеры и назначение критерия

Правильно. Описание привязано к полю с помощью оборачивающего



Правильно. Описание привязано к полю с помощью атрибута for у  и id у .



Неправильно. Описание никак не связано с полем формы.

Имя

Неправильно. Поле имеет два описания.


Зачем нужен критерий. Подписи полей форм отображаются в дереве доступности, что позволяет скринридерам правильно понимать и передавать смысл поля.

HTML-06. Лишние элементы

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

Примеры и назначение критерия

Правильно. Не используется лишняя обёртка, а для декоративного элемента нет дополнительного блока в разметке.

Быстро

Мы делаем свою работу быстро!

Правильно. Допускается использование тега для стилизации кастомных чекбоксов.

Неправильно. Используется лишняя обёртка, которую можно сократить, а для декоративного элемента использован тег , который можно заменить на псевдоэлемент.

Быстро

Мы делаем свою работу быстро!

...

Если в вёрстке осознанно и единообразно разделяются сеточные и смысловые блоки, это ошибкой не является.

Зачем нужен критерий. Лишние элементы не несут в себе функциональности, поэтому их нужно удалять для упрощения поддержки и переиспользования кода.

HTML-07. Валидация HTML

  • Разметка должна проходить валидацию в валидаторе W3C без ошибок (error).

  • В проверке могут быть предупреждения (warning).

Назначение критерия

Главная задача валидатора — проверить, что код соответствует стандартам и спецификациям языка. Код, который не проходит валидацию, может быть неправильно отработан в браузере.

HTML-08. Фавиконки

К каждой странице должны быть подключены иконки с помощью с указанием размера иконки.

  • В корне проекта должен быть файл favicon.ico, но подключать его к странице необязательно.

  • Фавиконки должны быть в размере 32×32 и в формате PNG.

Примеры и назначение критерия

Правильно. Подключена favicon.ico из корня проекта, а также иконка размером 32×32 в формате PNG.


  
  

Правильно. Подключена только иконка размером 32×32 в формате PNG. favicon.ico не подключён к странице, но лежит в корне проекта.


  

Неправильно. Подключена только favicon.ico без варианта иконки размером 32×32 в формате PNG.


  

Также ошибкой будет отсутствие favicon.ico в корне проекта.

Зачем нужен критерий. Фавиконки важны, так как они улучшают пользовательский опыт: помогают определить, какой сайт открыт на вкладке, или быстро найти нужный сайт в избранном.

CSS-01. Подключение стилей

  • Все стилевые файлы должны быть подключены с помощью тега .

  • Собственные стили проекта должны быть подключены одним файлом в .

  • Сторонние стили должны быть подключены в  отдельными файлами.

  • Сторонние стили должны быть подключены до собственных стилей проекта.

  • В разметке не должно быть инлайновых стилей в атрибуте style="" или в теге

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

CSS-02. Глобальный селектор

Глобальные селекторы запрещены, кроме исключений, приведённых ниже.

Глобальный селектор — это селектор по типу элемента или универсальный селектор. Например:

* {}
body {}
img {}
:root {}

Исключения:

  • Универсальный селектор, используемый для изменения боксовой модели одновременно элементов и псевдоэлементов.

  • Нормализация тега .

  • Уникальные теги документа: и .

  • :root, в котором использованы только кастомные свойства.

Примеры и назначение критерия

Правильно. Используется универсальный селектор одновременно с псевдоэлементами для изменения боксовой модели.

*,
*::before,
*::after {
  box-sizing: border-box;
}

Неправильно. Использован универсальный селектор без псевдоэлементов и не для изменения боксовой модели.

* {
  margin: 0;
  padding: 0;
}

Правильно. Для нормализации тега использованы свойства max-width и object-fit.

img {
  max-width: 100%;
  object-fit: contain;
}

Неправильно. Для нормализации тега использовано свойство display.

img {
  max-width: 100%;
  display: block;
}

Правильно. Использован уникальный тег .

body {
  margin: 0;
}

Неправильно. Использованы селекторы по типу.

ul { 
  list-style: none;
}

p { 
  margin: 0;
}

Правильно. Селектор по типу вложен внутрь селектора по классу.

.content h1 {
  font-size: 30px;
}

.content p {
  font-size: 20px;
}

Правильно. Внутри :root использованы только кастомные свойства.

:root {
  --basic-extra-dark: #242424;
  --basic-dark: #595959;
  --basic-light: #e7e7e7;
  --basic-extra-light: #f6f6f6;
}

Неправильно. :root использован не для кастомных свойств.

:root {
  font-size: 20px;
}

Зачем нужен критерий

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

Глобальные селекторы применяют стили ко всем элементам на странице, поэтому их использование может делать вёрстку менее контролируемой, а поведение элементов — непредсказуемым.

CSS-04. ID в селекторах

В селекторах не должно быть #id.

Примеры и назначение критерия

Неправильно. Используется селектор по идентификатору.

#header {
  background-color: #000000;
}

Зачем нужен критерий

Критерий рассматривает именно запрет на стилизацию через id, но использовать этот атрибут для связывания и элементов форм не считается ошибкой.

Селекторы по идентификатору обладают большей специфичностью по сравнению с классом и добавляют непредсказуемости в код. Например, чтобы переопределить #id, потребуется несколько селекторов по классу или !important. Это делает код неконтролируемым и сложно читаемым.

CSS-05. Использование! important

Ключевое слово !important не должно использоваться для борьбы со специфичностью.

Примеры и назначение критерия

Неправильно. Использован ! important.

.content h1 {
  font-size: 17px !important;
}

Зачем нужен критерий. Модификатор !important даёт CSS-правилу наивысшую специфичность и нарушает этим каскад стилей. Это добавляет непредсказуемости в код, усложняет его поддержку и отладку. Существуют специфические задачи, в которых использование !important может быть целесообразно, но в рамках курса таких задач нет, поэтому он запрещён.

CSS-06. Использование шрифтов

  • Начертания шрифтов, подключенных с помощью @font-face, должны меняться с помощью font-weight и font-style и не должны меняться с помощью подключения отдельного семейства шрифтов.

  • При указании шрифт должен дополняться общим семейством: serif, sans-serif, monospace и другие.

Примеры и назначение критерия

Правильно. Указано типовое семейство для шрифта sans-serif, а начертание изменяется с помощью font-weight.

@font-face {
 font-family: "PT Sans";
 src: url("/fonts/pt-sans.woff2") format("woff2");
 font-weight: 400;
 font-style: normal;
 font-display: swap;
}

@font-face {
 font-family: "Futura";
 src: url("/fonts/futura-bold.woff2") format("woff2");
 font-weight: 700;
 font-style: normal;
 font-display: swap;
}

.page {
  font-family: "PT Sans", sans-serif;
}

.content h2 {
  font-family: "Futura", sans-serif;
  font-weight: 700;
}

Неправильно. Начертание семейства изменяется именем шрифта, а не свойствами font-weight и font-style.

@font-face {
 font-family: "Futura Regular";
 src: url("/fonts/futura-regular.woff2") format("woff2");
 font-weight: 400;
 font-style: normal;
 font-display: swap;
}

@font-face {
 font-family: "Futura Bold";
 src: url("/fonts/futura-bold.woff2") format("woff2");
 font-weight: 700;
 font-style: normal;
 font-display: swap;
}

.content {
  font-family: "Futura Regular", sans-serif;
}

.content h2 {
  font-family: "Futura Bold", sans-serif;
}

Неправильно. У шрифта не указано общее семейство serif, sans-serif или monospace.

@font-face {
 font-family: "PT Sans";
 src: url("/fonts/pt-sans.woff2") format("woff2");
 font-weight: 400;
 font-style: normal;
 font-display: swap;
}

@font-face {
 font-family: "Futura";
 src: url("/fonts/futura.woff2") format("woff2");
 font-weight: 400;
 font-style: normal;
 font-display: swap;
}

.content {
  font-family: "PT Sans";
}

.content h2 {
  font-family: "Futura";
}

Зачем нужен критерий

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

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

IMG-01. Контентная и декоративная графика

  • Контентная графика должна вставляться в разметке.

  • Декоративная графика должна вставляться в стилях.

  • Декоративная SVG-графика может использоваться в разметке, если её внешний вид нужно менять стилями.

О том, как различать декоративную и контентную графику, можно почитать в блоге.

Примеры и назначение критерия