6 лет назад мы обсуждали с сообществом критерии качества вёрстки, которые мы используем в обучении, чтобы наши выпускники радовали рынок своими умениями и подходом к работе.
С тех пор в разработке интерфейсов произошло море изменений: сначала в продакшн пришли флексы, потом подтянулись гриды, умер IE, все переехали из Фотошопа в Фигму, и много чего ещё. Каждое это изменение влияло на наши критерии, и мы постоянно их дорабатывали.
Сейчас пришло время снова обсудить с сообществом обновлённые критерии, чтобы наши выпускники продолжали радовать индустрию своим уровнем.
Ниже представлена обновлённая система критериев, которую мы планируем внедрить на осенних запусках курсов. Мы публикуем её сейчас, чтобы собрать обратную связь от сообщества и внести изменения в критерии.
Что описывают и что не описывают эти критерии
Эти критерии касаются нашего первого уровня вёрстки, то есть задач, связанных с фиксированной вёрсткой без адаптивности и без специфичных требований к вёрстке (например, по натяжке на конкретную CMS).
Критерии для задач, связанных с адаптивностью, автоматизацией, натяжкой на CMS или вёрсткой под React, мы тоже планируем обсудить с сообществом, когда подготовим их.
Как устроена система критериев
На курсе ученик верстает макет (вот такого уровня сложности), и на защите в конце курса эту вёрстку по критериям качества проверяет случайный наставник. Защита считается успешной, если зачтены все обязательные критерии.
Помимо обязательных есть и дополнительные критерии, их выполнение для успешной защиты не нужно, но они позволяют более точно оценить качество работы и показать ученику как улучшить свой код. Дополнительные критерии в нашей системе помечены звёздочкой.
Для удобства обсуждения критерии разбиты на категории, некоторые критерии относятся к процессу приёмки проекта, некоторые к качеству кода.
Также для многих критериев мы попытались написать обоснование, зачем нужен критерий, и почему он именно такой. И будем рады, если в результате обсуждений появятся новые обоснования или дополнятся текущие.
TEST-01. Кроссбраузерность
Необходимо смотреть на размеры и расположение блоков, внешнее сходство с макетом.
Необходимо проверить работу анимации, если такая имеется.
Допускаются небольшие отличия в отображениях шрифтов.
Вёрстка должна идентично отображаться в последних стабильных версиях браузеров Chrome, Firefox, Safari, если иное не указано в техзадании проекта.
Назначение критерия
Пользователи сайта могут использовать разные браузеры в разных системах, поэтому нужно добиваться единого отображения.
TEST-02. Технологии
Проект должен быть сделан на HTML и CSS без использования сторонних библиотек и фреймворков.
Назначение критерия
Задача курса — научить решать задачи с помощью базовых технологий. Полученная база позволит разобраться, как работают фреймворки или библиотеки.
TEST-03. Размеры страницы
У каждой страницы есть минимальная ширина по фрейму.
При ширине окна больше минимальной страница центрируется.
Горизонтальная прокрутка появляется только при ширине, меньше минимальной.
Допускаются расхождения по горизонтали, не превышающие ширину полосы вертикальной прокрутки.
Примеры и назначение критерия
Зачем нужен критерий
В качестве ориентира для ширины страницы используется фрейм, потому что мы считаем Figma преобладающим форматом макетов и поэтому пользуемся терминами этого графического редактора. В учебных макетах мы учли минимальную ширину, но в реальной разработке минимальная ширина страницы может отличаться от размера фрейма.
У страницы должна быть минимальная ширина, чтобы у пользователей с меньшим разрешением при просмотре страницы оставались работоспособны все элементы сайта.
Контент страницы должен быть отцентрирован, чтобы у пользователей с большим разрешением при просмотре страницы контент находился перед глазами — в центре страницы.
TEST-04. Переполнение
Длина текста
Текст должен оставаться в рамках родительского блока при переполнении.
Текст не должен обрезаться или вываливаться из родительского блока при переполнении.
Текст не должен смещать другие блоки.
Родительский блок должен сохранять минимальные размеры при недополнении.
Слова, длиннее минимальной ширины, должны переноситься.
Размеры элементов
Контент больше ширины родителя не должен выходить за его пределы, ломать сетку или смещать другие блоки.
Количество элементов
При увеличении количества элементов они должны оставаться в рамках родительского блока.
Элементы могут переноситься на следующую строку при уменьшении размера родителя.
При минимальном количестве элементов или их отсутствии родительский блок должен сохранять минимальные размеры.
Последние блоки в сетках должны выравниваться по направлению текста.
Примеры и назначение критерия
Длина текста
Текст должен оставаться в рамках родительского блока при переполнении и не должен вываливаться или обрезаться из родительского блока.
Родительский блок должен сохранять минимальные размеры при недополнении.
Слова длиннее минимальной ширины должны переноситься.
Размеры элементов
Контент больше ширины родителя не должен выходить за его пределы, ломать сетку или смещать другие блоки.
Контент больше ширины родителя не должен выходить за его пределы, ломать сетку или смещать другие блоки.
Количество элементов
При увеличении количества элементов они должны оставаться в рамках родительского блока и последние блоки должны выравниваться по направлению текста.
Элементы могут переноситься на следующую строку при уменьшении размера родителя.
При проверке переполнения в браузере Safari необходимо добавлять текст не через инспектор браузера, а через редактор кода, редактируя страницу HTML. В противном случае текст будет добавляться в одну длинную строчку.
Зачем нужен критерий
Верстальщик должен предусматривать ситуации, в которых контент может меняться, и подготавливать вёрстку к изменениям контента.
TEST-05. Шрифты
Следующие текстовые параметры должны соответствовать параметрам из макета:
семейство шрифта
font-family
;насыщенность шрифта
font-weight
;начертание шрифта
font-style
;размер шрифта
font-size
;высота строки
line-height
;цвет текста
color
.
Назначение критерия
При проверке этого пункта следует ориентироваться именно на параметры, указанные в макете. Из-за особенностей отображения шрифтов на разных платформах, определение этого критерия на глаз может привести к ошибке. Помимо этого, стоит допускать разное межбуквенное расстояние в макете и в финальной вёрстке. Считать разное межбуквенное расстояние ошибкой стоит только в том случае, если оно явно указано в макете.
TEST-06. Pixel Perfect
При наполнении контентом, как в макете, элементы каждой страницы соответствуют макету.
Допускаются:
различия в 5 пикселей по высоте при расстояниях более 30 пикселей и 2 пикселя по ширине;
различия в отображении шрифтов, связанные со сглаживанием на различных платформах.
Примеры и назначение критерия
Рекомендуем проверять с помощью инструмента PerfectPixel (работает в Chrome, Firefox).
Зачем нужен критерий
Заказчик может не принять работу, если вёрстка будет отличаться от согласованному макета. Поэтому веб-разработчик должен не просто сверстать сайт по образцу, а сделать это близко к согласованному макету.
Чтобы сайт как можно точнее совпадал с утвержденным дизайном, веб-разработчики придерживаются концепции Pixel Perfect. Это способ вёрстки строго по макету, при котором размеры и интервалы из макета соблюдаются с точностью до нескольких пикселей.
Допустимые различия нужны для компенсации несоответствий макету, связанных с отличиями отображения элементов в разных графических редакторах, браузерах и операционных системах.
TEST-07. Стайлгайд
Все состояния элементов должны соответствовать стайлгайду, предусмотренному в макете. Стайлгайд — это часть дизайна проекта, он имеет наивысший приоритет. При наличии стайлгайда верстальщик должен ему следовать.
Если в стайлгайде не предусмотрены состояния элемента, то их нужно реализовать на своё усмотрение.
Для элементов форм, кнопок и ссылок:hover
, focus
, active
.
Для элементов форм: disabled
.
Назначение критерия
При проверке этого пункта следует оценивать наличие эффектов и их соответствие стайлгайду.
TEST-08. Взаимодействие
При взаимодействии с элементами (наведение, нажатие) ни сам элемент, ни окружающие его блоки не меняют своего положения, если такое поведение не предусмотрено макетом.
Примеры
Правильно
Неправильно
Неправильно
Неправильно
PROJ-01. Кодгайд
Код должен быть написан с соблюдением требований кодгайда Академии.
Примеры и назначение критерия
Правильно. Код написан в одном стиле.
<section class="news">
<h2 class="news-title">Новости</h2>
</section>
<section class="news">
<h2 class="news-title">Галерея</h2>
</section>
.news {
color: #000000;
}
.news-title {
color: #ff0000;
background-color: #ffffff;
}
Неправильно. Одинаковые элементы разметки имеют разные отступы и переносы.
<section class="news-title">
<h2 class="news-title">
Новости
</h2>
</section>
<section class="news-title"><h2 class="news-title">Галерея</h2></section>
Неправильно. Один и тот же цвет написан в разных нотациях.
.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 {
/* стили */
}
Правильно. Значения атрибутов состоят из английских слов.
<label for="name"></label>
<input class="field" id="name" type="text">
Зачем нужен критерий
Английский язык — это общепринятая договорённость в среде разработчиков. Единый подход именования позволяет быстрее знакомиться с кодовой базой.
PROJ-03. Название папок и файлов
Файлы и папки должны быть записаны строчными буквами без пробелов между словами.
Примеры и назначение критерия
Правильно. Названия файлов и папок написаны строчными.
barbershop/
styles/
styles.css
images/
logo.svg
hammer.jpg
sun.png
Неправильно. Названия папок содержат прописные буквы.
barbershop/
Styles/
Styles.css
SCripts/
MySctips.js
IMAGES/
imagine image.jpg
В качестве разделителей должны использоваться только дефисы -
или подчёркивания _
. Выберите только один стиль — -
или _
. Разделители должны использоваться последовательно.
Правильно. Многосоставные названия разделяются дефисами.
barbershop/
images/
logo-full.svg
twitter-logo.jpg
header-bottom-border.png
Неправильно. Многосоставные названия содержат разные разделители.
barbershop/
images/
logotip.svg
link__active-before.png
header-border_bottom.jpg
Зачем нужен критерий. Перечисленные требования продиктованы кодстайлом Академии. В других командах и проектах требования могут отличаться. Критерий говорит о том, что важно соблюдать кодстайл команды, в которой вы работаете. Кроме того, в некоторых системах названия папок и файлов регистрозависимые, и единообразное именование защитит вас от возможных проблем, связанных с регистром.
PROJ-04*. Закомментированный код
В проекте не должно быть закоментированных фрагментов кода без осмысленного текстового пояснения.
Примеры и назначение критерия
Правильно. Комментарий описывает механику взаимодействия с элементом. Таким образом передаются знания от одного разработчика другому.
<!-- Чтобы попап отображался необходимо добавить класс popup-active -->
<div class="popup popup-active">
<div class="popup__overlay"></div>
</div>
Правильно. Комментарий скрывает часть разметки, но при этом имеет пояснение, в каком случае эту часть нужно восстановить.
<div class="popup popup-active">
<div class="popup__overlay"></div>
<!-- Если в попапе есть карта, то добавить див и в него вложить карту
<div class="popup-map"></div>
-->
</div>
Правильн
Правильно. Комментарии поясняют структуру разметки, позволяя быстрее навигировать по файлу.
<!-- Header -->
<header class="header"></header>
<!-- Список пунктов -->
<ul>
<li>Пункт</li>
<li>Пункт</li>
</ul>
<!-- Price -->
<section class="price"></section>
<!-- Footer -->
<footer class="footer"></footer>
/* Header */
.header {
…
}
/* Footer */
.footer {
…
}
Неправильно. Код закомментирован и не имеет описания.
<!--
<div class="popup">
<div class="popup__overlay"></div>
<!–Разметка попапа–>
</div>
-->
Неправильно. Код закомментирован и имеет неосмысленное описание: комментарий не помогает понять, почему код закомментирован.
<!--TODO: Не забыть удалить
<div class="popup">
<div class="popup__overlay"></div>
<!–Разметка попапа–>
</div>
-->
Зачем нужен критерий. Большое количество закомментированного кода засоряет разметку, усложняет понимание и дальнейшую поддержку кода. Если фрагмент кода по какой-то причине должен быть закомментирован, то хорошие поясняющие комментарии помогут быстрее ознакомиться с его функциональностью.
PROJ-05. Неиспользуемые файлы
В проекте не должно быть неиспользуемых файлов:
Файлы, не подключённые на страницы.
Подключённые файлы, которые ничего не делают.
Файлы svg-изображений, которые заинлайнены в разметку, могут остаться в папке проекта.
Примеры и назначение критерия
Правильно. Файл slider.css
находится в папке проекта и подключен в разметке.
barbershop/
styles/
styles.css
slider.css
<head>
<link rel="stylesheet" href="styles/styles.css">
<link rel="stylesheet" href="styles/slider.css">
</head>
Неправильно. Файл slider.css
находится на файловой системе, но не подключен в проекте.
barbershop/
styles/
styles.css
slider.css // не подключён
<head>
<link rel="stylesheet" href="styles/styles.css">
</head>
Неправильно. Файл slider.css
подключен, но не влияет на стилизацию страницы.
barbershop/
styles/
styles.css
slider.css // подключен, но пустой
<head>
<link rel="stylesheet" href="styles/styles.css">
<link rel="stylesheet" href="styles/slider.css">
</head>
Зачем нужен критерий. Неиспользуемые файлы засоряют файловую структуру и усложняют поддержку сайта.
HTML-01. Ориентиры
На странице, при их наличии, должны быть обозначены структурные ориентиры:
<header>
для вводной части, повторяющейся на других страницах;<main>
для основного содержимого, не повторяющегося на других страницах;<nav>
для важных навигационных элементов по сайту;<aside>
для дополнительного содержимого;<footer>
для закрывающей, дополнительной информации о странице.
Ориентиры могут быть обёрнуты или вложены в другие теги, использоваться для стилизации или просто служить смысловыми обёртками.
Примеры и назначение критерия
Правильно. На странице используются структурные ориентиры. Тега <aside>
нет в структуре, так как такой элемент не предусмотрен дизайном проекта.
<body>
<header>
Лого
<nav>
Меню
</nav>
</header>
<main>
Страница
</main>
<footer>
Контакты
</footer>
</body>
Неправильно. На странице используется <div>
вместо структурных ориентиров.
<body>
<div>
Лого
<div>
Меню
</div>
</div>
<div>
Страница
</div>
<div>
Контакты
</div>
</body>
Зачем нужен критерий. Ориентиры — это элементы, группирующие контент, которые позволяют быстро перемещаться между группами, что важно при навигации по сайту с помощью скринридера.
HTML-02. Заголовки
На странице должен быть
<h1>
, который описывает содержимое страницы.Уровни заголовков должны идти последовательно от большего к меньшему без пропусков.
Исключения, касающиеся наличия одного <h1>
на странице или изменения сквозной структуры заголовков, возможны для тега <article>
, так как внутри него может находиться свой собственный <h1>
и собственная структура заголовков.
Примеры и назначение критерия
Правильно. На странице есть <h1>
, описывающий её содержимое. Заголовки применяются последовательно — от большего к меньшему, без пропусков.
<h1>Каталог</h1>
<section>
<h2>Товары</h2>
<article>
<h3>Товар</h3>
</article>
</section>
<section>
<h2>Доставка</h2>
</section>
Неправильно. На странице нет <h1>. Последовательность заголовков неупорядоченная.
<section>
<h5>Товары</h5>
<article>
<h1>Товар</h1>
</article>
</section>
<section>
<h3>Доставка</h3>
</section>
Правильно. На странице есть <h1>
, описывающий её содержимое, и несколько <article>
с собственными <h1>
. Иерархия заголовков при этом остаётся упорядоченной.
<h1>Каталог</h1>
<section>
<h2>Товары</h2>
<article>
<h3>Товар</h3>
</article>
</section>
<article>
<h1>Барбершоп сегодня закрыт.</h1>
</article>
<article>
<h1>Скидки на новые причёски.</h1>
</article>
Зачем нужен критерий. Иерархия заголовков важна, так как она определяет структуру контента, которую потом могут использовать сторонние программы, например, поисковые роботы или скринридер. Исключения, касающиеся использования <article>
допустимы, но лучше всё равно следовать общим правилам — один <h1>
и уровни заголовков без пропусков.
HTML-03. Кнопки и ссылки
Ссылки <a href>
должны использоваться для перехода между страницами, а кнопки <button>
должны использоваться только для действий на странице.
У ссылок должен быть атрибут
href
. Ссылки, которые ведут на самих себя, могут быть без атрибута.Для ссылок, адрес которых неизвестен, можно использовать атрибут
href
с решёткойhref="#"
.Адреса почты и телефоны должны быть размечены ссылками с соответствующими схемами внутри
href
.У кнопок должен быть явно указан тип действия в атрибуте
type
.
Примеры и назначение критерия
Правильно. Для элементов, предназначенных для перехода между страницами, использован тег <a>.
<!-- Страница catalog.html -->
<nav>
<ul>
<li><a href="#">Главная</a></li>
<li><a>Каталог</a> <!-- в ссылке на каталог не указан href, так как она ведёт на саму себя --></li>
<li><a href="#">Вопросы</a></li>
</ul>
</nav>
Неправильно. Для элементов, предназначенных для перехода между страницами, использован тег <button
>.
<nav>
<ul>
<li><button type="button">Главная</button></li>
<li><button type="button">Каталог</button></li>
<li><button type="button">Вопросы</button></li>
</ul>
</nav>
Правильно. Для почты и телефона использованы схемы mailto:
и tel:
.
<a href="mailto:email@example.com">email@example.com</a>
<a href="tel:+79876543210">+7 987 654-32-10</a>
Неправильно. Для почты и телефона не использован тег <a>
c схемами mailto:
и tel:
.
<span>email@example.com</span>
<p>+7 987 654-32-10</p>
Правильно. Для элемента действия использован тег <button>
.
<button type="button">Закрыть</button>
Зачем нужен критерий. Правильно размеченные ссылки и кнопки улучшают пользовательский опыт и помогают избегать ошибок в работе веб-страниц. Подробнее о том, чем отличаются ссылки и кнопки и какие проблемы могут возникнуть, если использовать неподходящий тег, можно почитать в блоге.
HTML-04. Работоспособные формы
Формы должны быть работоспособными и отправлять данные всех полей.
Поля формы должны находиться внутри тега
<form>
.У формы должен быть указан атрибут
action
.У обязательных полей должен быть атрибут
required
.
Для тестирования формы можно использовать адрес https://echo.htmlacademy.ru.
Примеры и назначение критерия
Правильно. Форма имеет атрибут action
. Все поля формы обёрнуты в тег <form>
.
<form action="https://echo.htmlacademy.ru">
<label>
Логин
<input type="text" name="user" required>
</label>
<label>
Пароль
<input type="password" name="password" required>
</label>
<button type="submit">Отправить</button>
</form>
<form action="https://echo.htmlacademy.ru">
<label>
Поиск
<input type="search" name="search" required>
</label>
<button type="submit">Найти</button>
</form>
Неправильно. У формы не указан атрибут action
.
<form>
<label>
Логин
<input type="text" name="login" required>
</label>
<label>
Пароль
<input type="text" name="password" required>
</label>
<button type="button">Отправить</button>
</form>
Неправильно. Форма поиска не обёрнута в тег <form>
.
<label>
Поиск
<input type="search" name="search" required>
</label>
<button type="submit">Найти</button>
Неправильно. У полей с обязательным заполнением нет атрибута required
.
<form action="https://echo.htmlacademy.ru">
<label>
Логин *
<input type="text" name="user"
</label>
<label>
Пароль *
<input type="password" name="password">
</label>
<button type="submit">Отправить</button>
</form>
Неправильно. У разных полей формы одинаковое значения для атрибута <name>
. В этом случае отправятся данные только одного поля.
<form action="https://echo.htmlacademy.ru">
<label>
Пароль
<input type="password" name="password" required>
</label>
<label>
Повторите пароль
<input type="password" name="password" required>
</label>
<button type="submit">Отправить</button>
</form>
Неправильно. Не указано значение у атрибута name
или отсутствует атрибут name
.
<form action="https://echo.htmlacademy.ru">
<label>
Пароль
<input type="password" name="" required>
</label>
<label>
Повторите пароль
<input type="password" required>
</label>
<button type="submit">Отправить</button>
</form>
Зачем нужен критерий. Формы — это критическая функциональность сайта, поэтому важно, чтобы они были работоспособны и отправляли введённые пользователем данные.
HTML-05. Подписи полей форм
Подписи полей форм должны быть привязаны к своим полям.
Примеры и назначение критерия
Правильно. Описание привязано к полю с помощью оборачивающего <label>.
<label>
Имя
<input type="text" name="text">
</label>
<label>
<input type="text" name="text">
Имя
</label>
Правильно. Описание привязано к полю с помощью атрибута for
у <label>
и id
у <input>
.
<label for="name">Имя</label>
<input type="text" id="name" name="text">
Неправильно. Описание никак не связано с полем формы.
Имя
<input type="text" name="name">
Неправильно. Поле имеет два описания.
<label for="email">Email</label>
<label>
<input id="email" type="email" name="email">
</label>
Зачем нужен критерий. Подписи полей форм отображаются в дереве доступности, что позволяет скринридерам правильно понимать и передавать смысл поля.
HTML-06. Лишние элементы
В разметке не должно быть лишних обёрток и элементов, которые используются для оформления и могут быть заменены на псевдоэлементы.
Примеры и назначение критерия
Правильно. Не используется лишняя обёртка, а для декоративного элемента нет дополнительного блока в разметке.
<div class="features clearfix">
<div class="features-item">
<h2>Быстро</h2>
<p>Мы делаем свою работу быстро!</p>
</div>
…
</div>
Правильно. Допускается использование тега <span>
для стилизации кастомных чекбоксов.
<label class="login-checkbox">
<input type="checkbox" name="remember" class="visually-hidden">
<span class="checkbox-indicator"></span>
Запомните меня
</label>
Неправильно. Используется лишняя обёртка, которую можно сократить, а для декоративного элемента использован тег <span>
, который можно заменить на псевдоэлемент.
<div class="features">
<div class="clearfix">
<div class="features-item">
<h2>Быстро</h2>
<span class="triangle"></span>
<p>Мы делаем свою работу быстро!</p>
</div>
</div>
...
</div>
Если в вёрстке осознанно и единообразно разделяются сеточные и смысловые блоки, это ошибкой не является.
Зачем нужен критерий. Лишние элементы не несут в себе функциональности, поэтому их нужно удалять для упрощения поддержки и переиспользования кода.
HTML-07. Валидация HTML
Разметка должна проходить валидацию в валидаторе W3C без ошибок (
error
).В проверке могут быть предупреждения (
warning
).
Назначение критерия
Главная задача валидатора — проверить, что код соответствует стандартам и спецификациям языка. Код, который не проходит валидацию, может быть неправильно отработан в браузере.
HTML-08. Фавиконки
К каждой странице должны быть подключены иконки с помощью <link rel="icon">
с указанием размера иконки.
В корне проекта должен быть файл
favicon.ico
, но подключать его к странице необязательно.Фавиконки должны быть в размере 32×32 и в формате PNG.
Примеры и назначение критерия
Правильно. Подключена favicon.ico
из корня проекта, а также иконка размером 32×32 в формате PNG
.
<head>
<link rel="icon" href="favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="images/favicon-32.png">
</head>
Правильно. Подключена только иконка размером 32×32 в формате PNG
. favicon.ico не подключён к странице, но лежит в корне проекта.
<head>
<link rel="icon" type="image/png" sizes="32x32" href="images/favicon-32.png">
</head>
Неправильно. Подключена только favicon.ico без варианта иконки размером 32×32 в формате PNG.
<head>
<link rel="icon" href="favicon.ico">
</head>
Также ошибкой будет отсутствие favicon.ico в корне проекта.
Зачем нужен критерий. Фавиконки важны, так как они улучшают пользовательский опыт: помогают определить, какой сайт открыт на вкладке, или быстро найти нужный сайт в избранном.
CSS-01. Подключение стилей
Все стилевые файлы должны быть подключены с помощью тега
<link rel="stylesheet">
.Собственные стили проекта должны быть подключены одним файлом в
<head>
.Сторонние стили должны быть подключены в
<head>
отдельными файлами.Сторонние стили должны быть подключены до собственных стилей проекта.
В разметке не должно быть инлайновых стилей в атрибуте
style=""
или в теге<style>
.В разметке допускаются стили для демонстрации поведения JS.
Примеры и назначение критерия
Правильно. Все собственные стили подключены в одном файле в <head>.
<head>
<link rel="stylesheet" href="styles/styles.css">
</head>
Неправильно. Стили разбиты на несколько файлов.
<head>
<link rel="stylesheet" href="styles/header.css">
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/footer.css">
</head>
Правильно. Сторонние стили подключены отдельно от собственных стилей.
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap">
<link rel="stylesheet" href="styles/styles.css">
</head>
Неправильно. Сторонние стили добавлены к собственным стилям.
<!-- Файл index.html -->
<head>
<link rel="stylesheet" href="styles/styles.css">
</head>
/* Файл styles/styles.css */
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap");
Правильно. Сторонние стили подключены до собственных стилей.
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap">
<link rel="stylesheet" href="styles/normalize.css">
<link rel="stylesheet" href="styles/styles.css">
</head>
Неправильно. Собственные стили подключены до сторонних стилей.
<head>
<link rel="stylesheet" href="styles/styles.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap">
<link rel="stylesheet" href="styles/normalize.css">
</head>
Неправильно. Стили используются в разметке.
<html>
<head></head>
<body>
<h1>Барбершоп «Бородинский»</h1>
<style>
.features {
…
}
</style>
<section class="features">
…
</section>
</body>
</html>
<section class="features" style="background-image: url('images/hammer.jpg');">
…
</section>
Зачем нужен критерий. Правильно подключённые стили гарантируют, что сайт будет выглядеть так, как этого требует макет.
CSS-02. Глобальный селектор
Глобальные селекторы запрещены, кроме исключений, приведённых ниже.
Глобальный селектор — это селектор по типу элемента или универсальный селектор. Например:
* {}
body {}
img {}
:root {}
Исключения:
Универсальный селектор, используемый для изменения боксовой модели одновременно элементов и псевдоэлементов.
Нормализация тега
<img>
.Уникальные теги документа:
<html>
и<body>
.:root
, в котором использованы только кастомные свойства.
Примеры и назначение критерия
Правильно. Используется универсальный селектор одновременно с псевдоэлементами для изменения боксовой модели.
*,
*::before,
*::after {
box-sizing: border-box;
}
Неправильно. Использован универсальный селектор без псевдоэлементов и не для изменения боксовой модели.
* {
margin: 0;
padding: 0;
}
Правильно. Для нормализации тега <img>
использованы свойства max-width
и object-fit
.
img {
max-width: 100%;
object-fit: contain;
}
Неправильно. Для нормализации тега <img>
использовано свойство display
.
img {
max-width: 100%;
display: block;
}
Правильно. Использован уникальный тег <body>
.
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
, но использовать этот атрибут для связывания <label>
и элементов форм не считается ошибкой.
Селекторы по идентификатору обладают большей специфичностью по сравнению с классом и добавляют непредсказуемости в код. Например, чтобы переопределить #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
, а дальше в любых селекторах прописывать только особенности начертания. На тех элементах, у которых по умолчанию есть тестовые стили, например <i>
или <b>
, начертание шрифта применится автоматически. Это позволяет легко менять шрифт и отслеживать все варианты его использования.
Тип семейства необходимо указывать, чтобы в случае отсутствия основного шрифта изменения внешнего вида шрифтов на странице были минимальны.
IMG-01. Контентная и декоративная графика
Контентная графика должна вставляться в разметке.
Декоративная графика должна вставляться в стилях.
Декоративная SVG-графика может использоваться в разметке, если её внешний вид нужно менять стилями.
О том, как различать декоративную и контентную графику, можно почитать в блоге.
Примеры и назначение критерия
Правильно. Контентная графика использована в разметке.
<img src="images/hammer.jpg" width="640" height="320" alt="Мороженное сорта Хаммер со вкусом дубовой коры">
Неправильно. Контентная графика использована в стилях.
<div class="product">
…
</div>
.product {
background-image: url("images/hammer.jpg");
}
Правильно. Декоративная графика использована в стилях.
<button class="button-icon">
<span class="visually-hidden">Перейти в Facebook.</span>
</button>
.button-icon {
background-image: url("images/icons/icon.svg");
}
Правильно. Декоративная изменяемая графика использована в разметке.
<body>
<svg class="icon" width="11" height="10" viewBox="0 0 11 10" xmlns="http://www.w3.org/2000/svg">
<path d="M11 0L0 0L5.5 10L11 0Z" />
</svg>
</body>
.icon:hover {
fill: #ff0000;
}
Неправильно. Декоративная графика использована в разметке.
<img src="images/line.png" width="16" height="16" alt="">
Зачем нужен критерий
Контентная графика должна быть в разметке, так как она содержит в себе важную смысловую информацию и поэтому должна быть доступна пользователю даже в том случае, если стили по какой-то причине не загрузятся.
Декоративная графика должна быть в стилях, так как она не несёт смысловой нагрузки и её отсутствие в случае незагрузки стилевого файла не приведёт к потере важной информации. Использовать декоративную графику в разметке нежелательно, так как лишние элементы в разметке усложняют поддержку кода.
IMG-02. Форматы графики
Выбран подходящий формат изображений. Например:
JPEG для фотографий;
SVG для векторных изображений;
PNG для всех прочих.
Назначение критерия
Зачем нужен критерий. Использование подходящих форматов изображений важно для того, чтобы изображения отображались без погрешностей и имели оптимальный размер при загрузке.
IMG-03. Размеры графики в разметке
Для всех изображений, размеченных при помощи <img>
и <svg>
, размеры должны быть заданы с помощью атрибутов width
и height
.
Примеры и назначение критерия
Правильно
<img src="images/flower.jpg" width="390" height="250" alt="Нежные цветки сакуры на фоне голубого неба.">
<svg width="11" height="10" viewBox="0 0 11 10" xmlns="http://www.w3.org/2000/svg">
<path d="M11 0L0 0L5.5 10L11 0Z" />
</svg>
Зачем нужен критерий
Задавать размеры растровых изображений в разметке необходимо, чтобы не было скачков интерфейса при их загрузке, а векторных — чтобы изображение не увеличивалось бесконтрольно, если у него не заданы внутренние размеры.
Задавать размеры изображений в разметке необходимо для перестраховки. В этом случае вёрстка сайта не сломается, если изображение будет заменено на более большое или маленькое.
CONT-01. Текстовые переносы
Текст не должен переноситься с помощью двойного <br>
.
Примеры и назначение критерия
Правильно. Перенос для соответствия макету сделан с помощью одного тега <br>
.
<h1>Шампунь для <br>
мужчин Brews Daily</h1>
Неправильно. Перенос для соответствия макету сделан с помощью двух тегов <br>
.
<p>Заимствование, как бы это ни казалось парадоксальным, непрерывно.</p>
<br>
<br>
<p>Представленный лексико-семантический анализ является психолингвистическим в своей основе.</p>
Зачем нужен критерий. Использовать тег <br>
для создания отступов между блоками — это плохая практика, потому что такой код неудобно изменять и поддерживать.
ALLY-01. Описание графики
Контентная графика должна иметь описание.
Чтобы описание элемента попало в дерево доступности, нужно использовать один из способов:
добавить изображению
alt
;добавить скрытый текст с помощью
visually-hidden
;добавить атрибут
aria-label
.
Предпочтительно увеличивать доступность в первую очередь с помощью HTML и только потом — aria
-ролей.
Подпись в конце описания должна иметь точку. Точка нужна для интонационной паузы при чтении скринридером.
Примеры и назначение критерия
Контентная растровая графика
Теги <img>
должны иметь заполненный атрибут alt
с описанием изображения.
Исключение: если рядом с изображением есть сущность в которой уже описано содержимое картинки, то alt
можно оставлять пустым.
Правильно. У тега <img>
атрибут alt
содержит описание изображения.
<img src="images/hammer.jpg" width="640" height="320" alt="Винтажный молоток с рукояткой из массива дуба.">
Правильно. В карточке товара есть заголовок, описывающий товар. В этом случае alt
можно оставить пустым, иначе скринридер при чтении карточки повторит два раза название товара.
<li class="product-card">
<img src="images/shampoo.jpg" width="220" height="200" alt="">
<h3>Шампунь для мужчин Brews Daily</h3>
</li>
Неправильно. У тега <img>
не заполнен атрибут alt
.
<img src="images/hammer.jpg" width="640" height="320" alt>
Неправильно. В качестве значения атрибута alt
использован пробел.
<img src="images/hammer.jpg" width="640" height="320" alt=" "> <!--alt с пробелом-->
Контентная векторная графика
Контентная векторная графика в разметке должна иметь атрибут role="img"
и описание изображения в атрибуте aria-label
.
Правильно. Контентная векторная графика имеет role="img"
и aria-label
.
<svg
class="logo"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 140 18"
width="367"
height="152"
role="img"
aria-label="Барбершоп «Бородинский»">
<path d="M78.55 0h-2.8v15.78h2.8V0zM91.02z"/>
</svg>
Неправильно. У контентной векторной графики отсутствует role="img"
и aria-label
.
<svg class="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 18" width="367" height="152">
<path d="M78.55 0h-2.8v15.78h2.8V0zM91.02z"/>
</svg>
Зачем нужен критерий. Атрибут alt
даёт альтернативное описание изображения для скринридеров и поисковиков. Правильное описание картинки добавляет смысл и ценность появления этой картинки для пользователя.
ALLY-02. Подписи интерактивных элементов
Интерактивные элементы должны быть подписаны. Подпись должна быть связана с элементом и отображаться в дереве доступности.
Предпочтительно реализовывать подпись с помощью HTML: тегом с классом visually-hidden
или атрибутом alt
у изображений, и только потом — aria
-атрибутами.
Подпись в конце описания должна иметь точку. Точка нужна для интонационной паузы при чтении скринридером.
Примеры и назначение критерия
Правильно. У ссылки есть описание, так как у изображения заполнен атрибут alt.
<a href="/">
<img src="images/logo.svg" width="64" height="32" alt="Барбершоп «Бородинский».">
</a>
Неправильно. У ссылки нет описания, так как у изображения не заполнен атрибут alt
.
<a href="/">
<img src="images/logo.svg" width="64" height="32" alt="">
</a>
Неправильно. У ссылки нет описания, так как внутри неё нет текстового содержимого.
<a href="https://twitter.com/htmlacademy_ru"></a>
Правильно. Описание у кнопки с иконкой реализовано при помощи текста, скрытого классом visually-hidden
.
<button class="fb-icon" type="button">
<span class="visually-hidden">Закрыть окно.</span>
</button>
.fb-icon {
content: url("images/fb.png");
}
Неправильно. Кнопка с иконкой не имеет описания.
<button class="fb-icon" type="button"></button>
.fb-icon {
content: url("images/fb.png");
}
Зачем нужен критерий. Текстовое описание интерактивных элементов поможет пользователям понять, что именно произойдёт в результате взаимодействия, в случае если они не видят элементы интерфейса. Это описание будет озвучено скринридером.
ALLY-03. Видимое состояние элементов
Все интерактивные элементы должны иметь видимое состояние фокуса.
Элементы должны иметь стандартный браузерный фокус, если это состояние не описано в дизайне.
Примеры и назначение критерия
Правильно. Интерактивный элемент имеет стандартный браузерный фокус.
<button class="button" type="button">Закрыть</button>
Неправильно. Вместо кнопки использован <div>
, стилизованный под кнопку, но не имеющий встроенной интерактивности.
<div class="button">Закрыть</div>
.button {
display: inline-block;
border: none;
height: 50px;
background-color: #eeeeee;
}
Правильно. Стандартный браузерный фокус заменён на фокус, описанный в макете.
<button class="button" type="button">Закрыть</button>
.button {
outline: none;
box-shadow: 0 0 1px rgba(255, 255, 0, 0.7);
}
Неправильно. Стандартная обводка отключена без замены на альтернативное состояние.
<button class="button" type="button">Закрыть</button>
.button {
outline: none;
}
* {
outline: none;
}
При проверке нужно убедиться, что в коде либо нет outline: none, либо взамен назначена подходящая замена.
Зачем нужен критерий. Видимое состояние интерактивных элементов позволяет передвигаться по ним с клавиатуры клавишей Tab и видеть каждый текущий элемент в активном состоянии.
ALLY-04. Области интерактивных элементов
Область интерактивных элементов должна включать тексты, иконки и другие связанные части. Она не должна накладываться на окружающие элементы.
Область клика у интерактивных элементов может быть больше, чем их контент, но область клика не должна накладываться на окружающие элементы.
Область клика можно определить из макета. Если в макете область клика не определена, то можно сделать её на своё усмотрение, руководствуюсь примерами ниже.
Примеры и назначение критерия
Область взаимодействия включает иконку и текст
Область вокруг текста в навигации чувствительна к клику, а не только сам текст.
Интерактивные элементы с иконкой имеют расширенную область клика.
В пагинации цифры имеют расширенную область клика, а не по цифре.
Кнопка закрытия модального окна имеет расширенную область клика, а не равную размерам иконки.
В карточке товара кликабельным является не только название товара, но и изображение товара, а не только его название.
Зачем нужен критерий. Правильные области важны для ускорения взаимодействия с интерактивными элементами интерфейса: чем меньше область клика, тем больше времени пользователь потратит на то, чтобы попасть в эту область.
ALLY-05. Фоновый цвет у фоновых картинок
Для блока, у которого есть текст с фоновым изображением, должен быть указан фоновый цвет, который соответствует преобладающему цвету изображения. Преобладающий цвет фоновой картинки должен быть контрастным.
Примеры и назначение критерия
Правильно. Указан цвет фона перед основным изображением.
body {
background: #000000 url("../img/background-body.jpg") no-repeat center top;
}
Результат: картинка не загрузилась, но при этом цвет фона остался тёмным.
Неправильно. Указано только основное изображение.
body {
background: url("../img/background-body.jpg") no-repeat center top;
}
Результат: картинка не загрузилась, а цвет фона стал белым.
Для блока с картой также следует указывать фоновый цвет.
Чтобы этот критерий был засчитан, необходимо не просто указать цвет фона, но и подобрать цвет, который преобладает в самом изображении.
Зачем нужен критерий. Такой метод используется для перестраховки. В этом случае, если фоновое изображение не загрузится, на заднем фоне останется преобладающий цвет.
ALLY-06*. Порядок фокуса
Порядок фокуса на интерактивных элементах не должен изменяться стилями.
Примеры и назначение критерия
Правильно
<nav class="menu">
<ul>
<li><a class="menu-item menu-item-current" href="#">Кроет</a></li>
<li><a class="menu-item" href="#">Буря</a></li
<li><a class="menu-item" href="#">Мглою</a></li>
<li><a class="menu-item" href="#">Небо</a></li>
</ul>
</nav>
.menu {
display: flex;
}
• Кроет
• Буря
• Мглою
• Небо
Неправильно
<nav class="menu">
<ul>
<li><a class="menu-item menu-item-current" href="#">Кроет</a></li>
<li><a class="menu-item" href="#">Буря</a></li
<li><a class="menu-item" href="#">Мглою</a></li>
<li><a class="menu-item" href="#">Небо</a></li>
</ul>
</nav>
.menu {
display: flex;
flex-direction: row-reverse;
}
• Небо
• Мглою
• Кроет
• Буря
Зачем нужен критерий. Переход между элементами на странице должен быть очевиден и предсказуем для пользователей, передвигающихся по сайту с клавиатуры.
Комментарии (22)
GoodProject
18.08.2021 14:33HTML Academy респект, спс за статью.
Первые курсы, которые вели: Першин, Симоненко и Макеев - лучшее что было в верстке. :)AlexPershin Автор
27.08.2021 11:56Спасибо, мы всегда рядом с процессом разработки курсов, хотя лекции уже и не читаем
Zman
20.08.2021 23:31+1Спасибо за статью.
Расскажите, пожалуйста, почему для нормализации тега
<img>
неправильно использовать свойствоdisplay: block;
AlexPershin Автор
27.08.2021 11:55Потому что картинки ведут себя как блочно-строчные по умолчанию (тут надо копать откуда это берётся: из спеки или из общепринятых браузерных стилей по умолчанию), и изменение типа бокса у картинок на блочный кардинально поменяет их поведение.
А та нормализация, которая допускается в критерии, она про перестраховку, чтобы картинка за пределы своего контейнера не вылезала (даже если кто-то вставил картинку, которая намного шире контейнера).
boltrukevich
27.08.2021 11:48Благодарю за этот труд, и за то, что собрали это в такой материал полезны! Теперь есть куда ссылаться : )
Spaceoddity
01.09.2021 05:44HTML-02. Заголовки
На странице должен быть <h1>, который описывает содержимое страницы.
Присутствие на странице заголовка не является обязательным требованием в вебе. Необходимость в заголовке определяется типом и содержимым страницы.
HTML-03. Кнопки и ссылки
Ссылки <a href> должны использоваться для перехода между страницами, а кнопки <button> должны использоваться только для действий на странице.
Очень размыто в нынешних реалиях. Вызов модального окна должен осуществляться кнопкой или ссылкой? Программная навигация? Отображение компонентов в SPA?
CSS-02. Глобальный селектор
Неправильно. Использован универсальный селектор без псевдоэлементов и не для изменения боксовой модели.
Что? Откуда это взято? Лично я всегда сбрасываю стили таким образом. Даже если я начну лепить простыни для reset.css, то html5 позволяет использовать кастомные элементы. И их эти простыни уже не зацепят. А универсальный селектор потому и называется универсальным, что его назначение - установить css-свойства для всех элементов страницы.
CSS-04. ID в селекторах
В селекторах не должно быть #id.
Селекторы по идентификатору обладают большей специфичностью по сравнению с классом и добавляют непредсказуемости в код. Например, чтобы переопределить #id, потребуется несколько селекторов по классу или !important. Это делает код неконтролируемым и сложно читаемым.
Это не критерий. Это просто общепринятая практика. Сами печетесь о корректном каскаде, и сами же игнорируете дополнительные инструменты управления "специфичностью". "Неконтроллируемость" вносят вовсе не идентификаторы или !important, а "говнокод". Ну и никаким количеством "селекторов по классу" вы идентификатор не "перебьёте". Именно в этом и есть его основное назначение. И если пользоваться этим с умом - всё будет контролируемо и читаемо.
CSS-05. Использование !important
То же самое что и с идентификаторами. Вам дали инструмент - вы его игнорируете и даже запрещаете, руководствуясь только общепринятой практикой.
CONT-01. Текстовые переносы
Текст не должен переноситься с помощью двойного <br>.
Удивили. Думал будет "нельзя использовать <br> для управления переносом".
Потому что картинки ведут себя как блочно-строчные по умолчанию (тут надо копать откуда это берётся: из спеки или из общепринятых браузерных стилей по умолчанию), и изменение типа бокса у картинок на блочный кардинально поменяет их поведение. А та нормализация, которая допускается в критерии, она про перестраховку, чтобы картинка за пределы своего контейнера не вылезала (даже если кто-то вставил картинку, которая намного шире контейнера).
Вы написали такой талмуд с критериями, но даже не удосужились открыть спецификацию? Т.е. вы не в курсе как HTML5 трактует разделение элементов на строчные и блочные? Если мне нужно чтобы все картинки на странице были представленные через блочную модель, почему я не могу использовать img{display:block;}? Да, я именно хочу кардинально поменять их поведение. В чём проблема? Ситуация несколько специфичная, но настолько уж. Точно так же далеко не всегда нужно object-fit:contain. Легко может понадобиться и object-fit:cover. В чём тут разница - не объясните?
AlexPershin Автор
03.09.2021 17:34Мы писали критерии применительно к следующей задаче: "Вёрстка страницы без адаптивности с нуля в условиях полного контроля разметки верстальщиком". То есть это те условия, в которых можно делать "идеальную вёрстку", и они ближе к вёрстке интерфейсов в продуктовых компаниях.
Зачем понимать, как делать "идеальную вёрстку" и как писать "идеальный код"? Чтобы в подходящих условиях делать максимально качественные интерфейсы, а при наличии специфических требований и задач отступать от идеального решения.
С учётом этого и постараюсь ответить на все вопросы.Присутствие на странице заголовка не является обязательным требованием в вебе. Необходимость в заголовке определяется типом и содержимым страницы.
Думаю, типовой случай страницы в вебе - это информационная страница, документ. И с точки зрения доступности наличие главного заголовка - это очень хорошо. Можете описать специфические задачи, в которых заголовок не нужен? Мы включим их как исключения, или используем в критериях, которые будут касаться этих спецзадач.
Очень размыто в нынешних реалиях. Вызов модального окна должен осуществляться кнопкой или ссылкой? Программная навигация? Отображение компонентов в SPA?
Возможно, формулировка и размыта. Вопрос в другом: считаете ли вы, что хороший верстальщик должен уметь разбираться в том, когда ставить ссылку, а когда кнопку? Если да, то критерий нужен.
Общее правило по выбору кнопки/ссылки у нас получилось сформулировать так, что единственное условие для выбора – это возможность потенциального перехода куда-то по щелку или невозможность перехода куда-то. Конечно, иногда данных с макета недостаточно для принятия решения, и в этом случае надо обращаться к тз или к заказчику.
И сам по себе критерий не может дать чёткий ответ на ваши вопросы, но он говорит о том, что во всех этих ситуациях тег должен быть подобран правильно в зависимости от поставленной задачи и бизнес-логики.
Что? Откуда это взято? Лично я всегда сбрасываю стили таким образом. Даже если я начну лепить простыни для reset.css, то html5 позволяет использовать кастомные элементы. И их эти простыни уже не зацепят.
Основной посыл этого критерия - чтобы не использовали где попало селекторы по тегам. Например, не сбрасывали бы отступы у всех списков с помощью `ul {...}`. Вы в своих специфичных задачах можете использовать глобальные селекторы, если понимаете плюсы-минусы.
А универсальный селектор потому и называется универсальным, что его назначение - установить css-свойства для всех элементов страницы.
Да, такая возможность в CSS присутствует. Но это ведь не означает, что её нужно использовать неаккуратно и напропалую?
Это не критерий. Это просто общепринятая практика. Сами печетесь о корректном каскаде, и сами же игнорируете дополнительные инструменты управления "специфичностью". "Неконтроллируемость" вносят вовсе не идентификаторы или !important, а "говнокод". Ну и никаким количеством "селекторов по классу" вы идентификатор не "перебьёте". Именно в этом и есть его основное назначение. И если пользоваться этим с умом - всё будет контролируемо и читаемо.
Многие критерии и являются просто повторением общепринятых практик. Конкретно этот критерий запрещает ученикам использовать один из инструментов и больше задумываться о том, чтобы не было говнокода.
То же самое что и с идентификаторами. Вам дали инструмент - вы его игнорируете и даже запрещаете, руководствуясь только общепринятой практикой.
А можете подсказать специфичные задачи, где этот инструмент идеально подходит? Мы эти примеры используем в критериях, а также учтём эти применры при обучении этим специфичным задачам.
Удивили. Думал будет "нельзя использовать <br> для управления переносом".
Как раз и хотели запретить распространённую у новичков ошибку и при этом оставить возможность использовать одиночные переносы там, где это нужно.
Вы написали такой талмуд с критериями, но даже не удосужились открыть спецификацию? Т.е. вы не в курсе как HTML5 трактует разделение элементов на строчные и блочные?
К сожалению (а вообще к счастью), HTML5 уже никак не трактует разделение на блочные и строчные (как когда то было в предыдущей версии). В HTML5 ввели категории элементов: фразовые, потоковые и так далее. А названия типов боксов (а не элементов) остались только в CSS. Мне лично это изменение нравится очень сильно, так как отражает важный принцип: разделение содержания и оформления.
Если мне нужно чтобы все картинки на странице были представленные через блочную модель, почему я не могу использовать img{display:block;}? Да, я именно хочу кардинально поменять их поведение. В чём проблема? Ситуация несколько специфичная, но настолько уж. Точно так же далеко не всегда нужно object-fit:contain. Легко может понадобиться и object-fit:cover. В чём тут разница - не объясните?
Всё правильно, вы сами написали, что ситуация специфичная. И если вам для специфичной задачи нужно для всех картинок задать блочные боксы, то это ок. Наша же задача была в этом примере показать один из распространенных способов нормализации картинок, когда можно и глобальный селектор по тегу использовать. И чаще всего для нормализации картинок задают `max-width: 100%`. `object-fit` тоже, думаю, допустим для нормализации
dasdasdasda
10.09.2021 16:33Начертания шрифтов, подключенных с помощью
@font-face
, должны меняться с помощьюfont-weight
иfont-style
и не должны меняться с помощью подключения отдельного семейства шрифтов.но ведь дизайнер нарисовал начертание, а если я начертание буду менять с помощью font-weight, то оно будет отличаться от того которое нарисовал дизайнер и будет отличаться еще и в разных браузерах
nikolayshabalin
14.09.2021 13:11Немного не понял про что вы.
Критерий защищает от следующей ситуации@font-face { font-family: "OpenSans"; src: url("fonts/opensans.woff2"); font-display: swap; } @font-face { font-family: "OpenSans-Bold"; src: url("fonts/opensans-bold.woff2"); font-display: swap; } body { font-family: "OpenSans", sans-serif; } h1 { font-family: "OpenSans-Bold", sans-serif; }
Мы же просим использовать шрифты
@font-face { font-family: "OpenSans"; src: url("fonts/opensans.woff2"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: OpenSans; src: url("fonts/opensans-bold.woff2"); font-weight: 700; font-style: normal; font-display: swap; } body { font-family: "OpenSans", sans-serif; } h1 { font-weight: 700; }
То есть все начертания дизайнера учитываются в обоих подходах, но мы просим использовать подход, когда начертание используется общее для всего сайта и нужные по месту с помощью
font-style
иfont-weight
.dasdasdasda
14.09.2021 13:28Неправильно. Начертание семейства изменяется именем шрифта, а не свойствами
font-weight
иfont-style
.Если я буду начертание менять свойством
font-weight
то браузер будет решать как отрисовать начертание (например 400 или 700), а если я буду менять начертание именем шрифта font-family: "OpenSans Bold", то будет подключаться то начертание которое нарисовал дизайнер и которое лежит в файле "fonts/opensans-bold.woff2".nikolayshabalin
14.09.2021 13:35В случае с
@font-face { font-family: "OpenSans"; src: url("fonts/opensans.woff2"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: OpenSans; src: url("fonts/opensans-bold.woff2"); font-weight: 700; font-style: normal; font-display: swap; } body { font-family: "OpenSans", sans-serif; } h1 { font-weight: 700; }
У
<h1>
будет отображёнOpenSans
из файлаopensans-bold.woff2
, то есть то что и планировал дизайнер
nikolayshabalin
14.09.2021 13:40Посмотрите как Google Fonts генерит стилевой файл с подключением шрифтов
ровно таким же способом
sympler
20.09.2021 16:25Для тега form атрибут action давно стал необязательным. Зачем его обязательно указывать?
mrBarabas
Очень много чего правильно, но вот есть моменты нужные только при обучении и очень будут мешать для верстки для продакшена, в частности, нет пункта про картинки, а именно про отзывчивость + в форматах нет современных, в подключении стилей в эпоху хттп2 подключение разными файлами считать за ошибку, нет ни слова про критические стили и вместо этого запрет на подключение стилей через тег. Ну и есть доля непонятной отсебятины - про стили для тегов (на самом деле от них не уйти при наличии пользовательского ввода - комменты на сайте, статьи в админке через редактор и т.д.), от некоторых можно легко уйти, от других - сложно, а если пользоваться вашими требованиями, то получится верстка для страницы, которую нужно будет дорабатывать для продакшена и работодатели не сильно будут рады, если верстальщик им такую верстку «принесёт» как готовую. Но за отсутствие фреймворков плюсик).
AlexPershin Автор
Давайте по порядку
Всё верно, так как на этом курсе нет задач по адаптивной графике, то этот критерий мы не используем, но он есть там, где учатся решать задачи, связанные с адаптивом.
мы от части форматов сознательно отказались, так как фигма из коробки не умеет их отдавать, поэтому нужны какие-то дополнительные инструменты. как вы у себя получаете эти форматы?
для решаемой задачи (вёрстка с нуля сайта из 2-3 страниц) это скорее ошибка, да даже и в более сложных проектах сборщики всё равно склеивают стили в один файл
а разве это не инструмент оптимизации, который нужен на достаточно крупных проектах, а на маленьких нет? то есть это достаточно специфическая вещь?
в блоке "о чём эти критерии" как раз описывается, что мы не охватываем этой системой, в частности мы не охватываем специфичные задачи вёрстки под какие-либо цмс. тут скорее вёрстка в условиях продуктовой компании, когда всю разметку контролирует верстальщик и в которую очень аккуратно подставляются пользовательские данные
какой вид продакшна вы имеете в виду? продакшн в заказной разработке, когда верстают для клиента, который потом будет натягивать вёрстку на какую-то цмс или продакшн в продуктовой разработке, когда с нуля пилится интерфейс продукта?
popovsergey
Figma, кстати, из коробки умеет в
.webp
, но мы планировали форматы во второй уровень уносить.popovsergey
а нет, пардон, я перепутал с SVG, но вообще есть довольно простой плагин, который умееет это делать легко https://www.figma.com/community/plugin/789009980664807964/TinyImage-Compressor
nikolayshabalin
Да, этот момент мы рассматриваем в рамках професии и расскарываем на HTML 2 уровня.
С
webp
студенты учаться работать, а сavif
знакомятся и если захотят, то могут добавить в итоговой проект.webp
формат про оптимизацию, а не про эстетику (например у JPG и PNG тут есть отличия в виде прозрачноти). Любой JPG или PNG будет выглядеть также какwebp
. Оптимизация как раз тема для следующего уровня HTML-курса.vanxant
pagespeed / lighthouse де-факто обязателен для всех проектов, которые чуть больше админки локалхоста. И там это критическое требование.
AlexPershin Автор
Насколько я понимаю, вопросы был именно про critical css
Что касается pagespeed / lighthouse — при разработке критериев мы учитывали и требования этих инструментов, и тот объём задач, который делает студент на этом курсе. Здесь он верстает сайт из двух страниц, поэтому продвинутые техники оптимизации пока не даём. Но базовые вещи требуем, например, про подбор правильного формата для картинок и оптимизацию графики.