
Хабр, привет!
Меня всегда раздражали вопросы на проверку знаний HTML и CSS. На моей памяти я ни разу не встретил человека, который спрашивал что-то интересное. По этой причине у меня появилось несколько статей с вопросами по CSS, которые собрали достаточно много просмотров для меня.
А что касается HTML, то я ничего не написал. Сегодня буду исправляться. Сразу скажу, что это не будут вопросы в стиле: «А какие HTML5-элементы вы знаете?». Мне хочется, чтобы вам было интересно и чтобы вы узнали что-то новое.
По этой причине большинство вопросов связаны с практикой. И абсолютно точно вы не ответите на все. Хотя, может, я ошибаюсь. Вот и проверим, насколько я прав.
Давайте посмотрим, что я вам подготовил.
Корректно ли использовать атрибут inputmode со значением numeric для элемента input, в который будут вводить цифровой код?
<body> <form> <!-- другие элементы --> <label for="code">Цифровой код</label> <input inputmode="numeric" type="text" id="code"> <!-- другие элементы --> </form> </body>
Ответ
Ответ на вопрос начнём с объяснения назначения атрибута inputmode. Он решает только одну задачу, а именно сообщает, какую виртуальную клавиатуру показывать браузерам при вводе данных на мобильных платформах.
Чтобы определиться со значением в нашем случае, нужно проанализировать формат данных, который требуется ввести пользователю. Поскольку цифровой код представляет собой набор цифр, то при его вводе должна отображаться виртуальная клавиатура только с цифрами. Для этого как раз подходит значение numeric.
Правильный ответ: Конечно, да! Значение numeric позволяет более удобно вводить цифровой код.
От какой проблемы спасают атрибуты width и height?
<body> <svg xmlns="http://www.w3.org/svg" width="32" height="32" viewBox="0 0 256 256"> <!-- оставшиеся элементы --> </svg> </body>
Ответ
Для ответа на вопрос нужно вспомнить, как отобразят браузеры элемент svg без атрибутов width и height. А они будут использовать значение атрибута viewBox, чтобы рассчитать размеры.
В нашем примере оно представляет собой набор четырёх чисел, разделённых пробелами. Таким способом значение задаёт прямоугольник, который определяет границы окна отображения элемента svg. Первое значение — это min-x, второе — это min-y, третье — это ширина, а четвёртое — это высота.
В итоге браузеры сделают элемент svg размером 256 пикселей на 256 пикселей, если у него не будет атрибутов width и height. По этой причине иконка может занять очень много пространства на экране, если у нас не загрузятся стили.
Чтобы этого не случилось, нужно объявлять атрибуты width и height. Так браузеры поймут размеры элемента svg сразу и не будут анализировать значение атрибута viewBox.
Правильный ответ: Атрибуты задают размеры элемента svg, чтобы иконка не занимала много пространства в случае, если стили не загрузятся.
Каким атрибутом можно сделать сразу всю группу элементов a неактивными?
Ответ
В HTML есть атрибут inert, который может сделать часть страницы недоступной для браузера. Буквально, пользователь не сможет кликнуть, сфокусироваться, ввести данные и найти через поиск по странице всё, что будет находиться в элементе с объявленным атрибутом.
В нашем примере атрибут inert поможет нам сделать все элементы a неактивными.
Правильный ответ: Атрибутом inert. Для этого его нужно добавить к элементу ul.
Я добавил название скачиваемого файла в качестве значения к атрибуту download. Можно ли так делать?
<body> <a href="b3f7be5pc3b8w24q6g.pdf" download="Заказ №5241836">Скачать детали заказа</a> </body>
Ответ
У атрибута download можно указать значение в виде произвольной строки, которая будет являться рекомендуемым именем файла. Оно подставляется в системное окно при сохранении файла.
В нашем примере будет подставлена строка «Заказ №5241836».
Правильный ответ: Да.
Атрибут lang, объявленный для элемента span, бесполезный. Правда или ложь?
<body> <p> Олимпи́йский комите́т Росси́и (англ. <span lang="en">Russian Olympic Committee</span>) — организация, представляющая страну в международном олимпийском движении </p> </body>
Ответ
Атрибут lang указывает не только основной язык страницы. Его задача — подсказать браузерам, на каком языке написан контент элемента. Эта информация, например, помогает скринридерам корректно озвучивать информацию.
Правильный ответ: Ложь. Атрибут lang поможет скринридерам корректно озвучить информацию на английском языке.
Есть ли разница между двумя фрагментами кода?
<body> <img src="mediastore/nn-banner.webp"> </body>
<body> <img src="mediastore/nn-banner.webp" alt=""> </body>
Ответ
С точки зрения визуального восприятия разницы нет. Если картинка не загрузится, то пользователи в любом случае не увидят альтернативный текст. Но разница заключается в том, как скринридеры проанализируют элемент img.
В первом случае они поймут, что атрибут alt отсутствует. Вместо него они озвучат всё содержимое атрибута src. Во втором случае элемент img не будет обнаружен. Скринридеры никогда его не найдут.
Правильный ответ: Разница есть и заключается в том, что скринридеры по-разному обрабатывают элемент img и озвучивают его.
Атрибут disabled, установленный у элемента fieldset, сделает неактивными все элементы input. Правда или ложь?
<body> <form> <fieldset disabled> <legend>Прозвище Дракса из «Стражей Галактики»?</legend> <label> <input type="radio" name="answer" value="Exterminator"> Уничтожитель </label> <label> <input type="radio" name="answer" value="Destroyer"> Разрушитель </label> <label> <input type="radio" name="answer" value="Accuser"> Обвинитель </label> </fieldset> </form> </body>
Ответ
Элемент fieldset помогает браузерам найти сгруппированные элементы формы. По сути они воспринимают их как отдельные части. Если у элемента fieldset установлен атрибут disabled, то все интерактивные элементы внутри становятся неактивными. Они даже не передадут значения при отправке формы.
Правильный ответ: Правда.
Можно ли на одной странице использовать несколько элементов main?
Ответ
Стандартом допускается использование любого количества элементов main на странице. Единственное, что нужно сделать, это визуально отобразить один, а остальные скрыть, добавив атрибут hidden.
<body> <main> <!-- здесь контент --> </main> <main hidden> <!-- здесь контент --> </main> <main hidden> <!-- здесь контент --> </main> </body>
Правильный ответ: Можно, только визуально должен отображаться один.
Вам нужно использовать в разметке ссылку «Наверх». Какой вариант вы выберите?
<body> <a href="#top" aria-label="Обратно наверх"> <!-- иконка здесь --> </a> <!-- оставшаяся часть кода страницы --> </body>
<body> <!-- оставшаяся часть кода страницы --> <a href="#top" aria-label="Обратно наверх"> <!-- иконка здесь --> </a> </body>
Ответ
Если пользователь будет использовать клавишу Tab для перехода между элементами, то в первом варианте он сразу попадёт на ссылку «Наверх». Хотя он и так находится там. Получается, что он совершил лишнее действие.
Во втором варианте пользователь попадёт на ссылку, только если дойдёт до конца страницы. По этой причине лучше располагать элемент a перед закрывающим элементом body.
Правильный ответ: Вариант №2, потому что в первом пользователь попадёт на ссылку, ещё находясь в верхней части страницы.
Какая ошибка есть в разметке страницы?
<body> <header> <!-- здесь элементы h1 и nav --> </header> <main> <section aria-labelledby="blog-heading"> <h2 id="blog-heading">Мой блог</h2> <article aria-labelledby="heading-1"> <h4><a href="#0" id="heading-1">Мое путешествие в Москву</a></h4> <p>Было классно. Увидел Кремль, Собор, поел в Белом кролике</p> </article> <article aria-labelledby="heading-2"> <h4><a href="#0" id="heading-2">Мое путешествие в Казань</a></h4> <p>Погода была дождливой. Но чак-чак супер</p> </article> </section> <!-- здесь другие элементы section --> </main> </body>
Ответ
Анализируя разметку, можно сказать, что на странице есть заголовок первого уровня в элементе header. Далее у каждого элемента section есть заголовок второго уровня. Но почему-то в элементе article находится заголовок четвёртого уровня, а не третьего. То есть нарушена иерархия заголовков.
Это приводит к тому, что ассистивные технологии неправильно анализируют страницу. Например, в результате этой ошибки пользователям скринридера сложнее понять структуру.
Правильный ответ: Нарушена иерархия заголовков.
Есть ли разница между двумя примерами разметки блока «Хлебные крошки»?
<body> <!-- вариант №1 --> <nav aria-label="Хлебные крошки"> <ul> <li><a href="../">Главная</a></li> <li><a aria-current="page">Новости</a></li> </ul> </nav> </body>
<body> <!-- вариант №2 --> <nav aria-label="Хлебные крошки"> <ol> <li><a href="../">Главная</a></li> <li><a aria-current="page">Новости</a></li> </ol> </nav> </body>
Ответ
Разница заключается в использовании элементов ul и ol. Согласно стандарту первый является неотсортированным списком, а второй, наоборот, отсортированным. Получается, у списка ol дочерние элементы должны быть расположены согласно какой-либо сортировке.
Область «Хлебные крошки» как раз представляет собой список элементов, у которого есть строгий порядок. На примере разметки из вопроса видно, что если поменять местами пункт «Новости» и «Главная», сломается структура навигации.
Правильный ответ: Есть. Поскольку элемент ol представляет собой упорядоченный список, то он лучше подходит для области «Хлебные крошки».
Заключение
Сколько правильных ответов удалось набрать вам? Если их нет совсем, то это совсем не проблема. Мои вопросы не показывают «уровень знаний». Я просто хотел помочь вам узнать про разные аспекты HTML и их практическое применение, а также подсказать, на что стоит обратить своё внимание.
Надеюсь, у меня это получилось. Обязательно поделитесь своими впечатлениями в комментариях.
На этом у меня всё. Спасибо за чтение!
P. S. Помогаю больше узнать про CSS и дружелюбные интерфейсы в своих закрытых ТГ-каналах CSS isn't magic и UX + Dev = a11y. Присоединяйтесь. Как вступить, написано в профиле.
© 2026 ООО «МТ ФИНАНС»
Комментарии (27)

TAZAQ
16.06.2026 09:25Можно ли на одной странице использовать несколько элементов main?
Ну технически, ответ “можно” без всяких но

Aggle
16.06.2026 09:25Семь правильных. С учётом того, что html-ем я последний раз занимался уже не помню сколько лет назад, — наверное неплохо (ручки-то помнят!).
Спасибо за толковую статью!

gabirx
16.06.2026 09:25забавно, занимаюсь рендерингом html, и понятия не имею как оно отрабатывать должно. надо смотреть спецификации, которые постоянно обновляются

ermouth
16.06.2026 09:25Атрибут
langпоможет скринридерам корректно озвучитьНу и hyphens:auto без него не работает. Вообще кстати загадка, отчего автопереносы не стали в вёрстке массовым явлением – на мобилах даже короткие тексты с переносами куда приятнее выглядят.
TooBigBigs
Классно, спасибо! Примерно половину ответил правильно.
Это при том, что в разработке я придерживаюсь примерно такой последовательности :
сначала используй возможности HTML
не получается - попробуй CSS
не получается - попробуй северный уровень (PHP)
не получается (точно не получается? Подумай ещё!) - только тогда JS
С недоумением и расстройством наблюдаю, как большинство начинают с последнего или в лучшем случае предпоследнего и мучаются, мучаются, мучаются… Потом прихожу я, удаляю 80% кода и офигеваю с того, как они умудрились пропустить первое мимо своих мозгов.
Akuma
Начинают с последнего потому, что знают что через голый html/css многое не получить. Любой шаг влево-вправо и всё
TooBigBigs
И да, и нет. Чаще не знают, как много можно получить. Не думают, что может и не надо делать шаги влево-вправо.
Недавно я удалил несколько КБ. кода и пару sql-запросов, заменив всё на 2 строчки CSS! Хитрые строчки, их написал ЧатЖПТ, а я просто предположил, что так, наверное, должно быть, можно.
До этого кодер самоотверженно работал несколько дней, создавая минное поле из багов, решая эту второстепенную задачу на PHP. То есть, получается, не проверив возможность низкоуровневой реализации подходами 1-2, убился на 3-м и запоганил кусочек проекта.
Akuma
А можно подробнее что там было?
Не представляю что вы там такое заменяли на полностью клиентскую часть
TooBigBigs
Очень просто : подсчет числа объектов в выборке SQL-объектов. По неведомой причине выбранный CRUD-фреймворк не давал такой элементарной возможности в рамках своего API.
Кодер грустно писал параллельнный SQL-запрос с нуля руками, а там куча условий и ещё пара динамических галочек на JS.
Я: подсчитал число TR внутри TABLE через CSS, вывел после последнего TR.
Понятно, что решение не содержит числа на сервере, но и задача ставилась “Сделать подсчет числа объектов на всякий случай”. Её в ТЗ и требованиях не было, скорее второстепенный функционал для собственного же удобства.
Итого: 15 минутное решение закрыло задачу VS несколько дней работы и усложнение поддержки в 2 раза.
randomsimplenumber
Backend'ера посадили вместо верстальщика. И какого результата ожидали увидеть?
Wesha
«Когда у вас в руках молоток, все предметы начинают казаться подозрительно похожими на гвозди» ©
randomsimplenumber
Вот именно. Прелесть в том что коллектив несколько дней любовался как чувак своим молотком пытается штукатурить.
TooBigBigs
Я не умею разделять задачи на бэкенд и верстку. Это приводит к тому, что кодер делает кривую-косую кнопку, а на предъявы отвечает, что он не дизайнер.
Верстальщик верстает так, что его код невозможно загнать в цикл, а на предъявы отвечает, что он не кодер.
Дизайнер рисует так, что сверстать это через циклы действительно сложно, а на предъявы отвечает, что он не верстальщик, не кодер, и вообще он так видит.
И все они не понимают, что делают в целом.
В какой-то момент я принял решение гнать их всех в шею и оставить одного более-менее вменяемого “кодера”. Теперь могу добавить, что и его стоило бы тогда же выгнать, вполне успешно заменяем ЧатЖПТ.
randomsimplenumber
Не хватает архитектора. Дожен же хоть кто то понимать как оно работает.
TooBigBigs
Архитектор - это я.
Только вот кончилось всё тем, что мне на порядок проще самому сделать всё: от анализа бизнес-задач и дизайна интерфейса до финального разворачивания проекта на сервере и настройки DNS-зон доменов.
Реально проще, чем пытаться делегировать, поскольку на простых задачах моя продуктивность ~= 1/2 продуктивности всех троих, на средних - x2, а на сложных - примерно x10.
Такая вот странная заковыка вышла - полный fullstack, я один до 30 раз эффективнее “обычных” разработчиков и заменяю продакшн целиком.
Впрочем, радоваться особо нечему, ибо ни счастья, ни автоматического изменения дохода это автоматически не дает. Со счастьем скорее даже наоборот.
randomsimplenumber
Так может не ваша продуктивность х10, а ихняя х/10.
TooBigBigs
Раньше тоже так думал, но это не бьется с теорией вероятности. Поскольку описанный паттерн постоянно повторяется в любых областях, которыми я всерьез интересуюсь, получается одно из двух:
либо я сам стабильно окружаю себя идиотами, причем практически безошибочно только ими
либо просто я талантливее середняка примерно в 10 раз (я бы предпочел слово “въедливее”, ведь как мне кажется 90% моего таланта состоит в умении очень сильно и настойчиво фокусироваться на задаче)
На самом деле быть талантливее среднего в 10 раз не такая уж и уникальная особенность.
Долларовых миллионеров - 1% населения (1 человека знаю лично, иногда переписываемся). Геев и лесбиянок - 5-7% населения (знаю человек пять-семь) Быть мировым чемпионом в каком-то виде спорта - ничтожная, но и то я знаю одного, который меня вспомнит если что.
На этом фоне я бы не удивился, если б знал 2-3 “неожиданно талантливых” людей, и, стало быть, вполне возможно что это и есть я сам.
gerbert_MX
я постепенно пришел к JS (я не фронт-енд, просто балуюсь) потому что получается максимум результата (динамического) при минимуме сторонних приседаний. JS работает ожидаемо, тот же css может тебя подвести на разных браузерах, а JS с canvas один, един и неделим
я понимаю что в плане поддержки теми же слабовидящими или с выключенным js такие поделия не катят, но я делаю для себя или узкого круга лиц и меня функционал устраивает
особенно хорошо сейчас с неронками - WPA что будет работать без интернета (то есть "установить" можно с локалхоста) с нужным тебе функционалом, причем нейроки умеют работать с бразуером, а значит нужно просто нарезать задачу и то как его проверять что бы на выходе получить уже готовое или практически готовое
maxshopen
Как то php не вписывается в последовательность. Можно пример что вы имели ввиду?
TooBigBigs
Если что-то можно решить путем отдельного запроса к серверу (PHP или нет - не важно), и на нём обработать логику, то лучше так и сделать.
Пример: юзер загрузил мышкой фотки к уже имеющимся. Надо приделать к новым фоткам кнопки. Не надо городить никакого кода - просто принудительно обновим страницу, кнопки сами приделаются по F5.
alexnozer
Здравый подход, побольше бы разработчиков ему следовало. Однако по поводу п.2 сделаю оговорку. Фанатичное использование CSS только ради того, чтобы не писать JS может привести к хакам.
Одно дело подсчёт элементов (в комментариях ниже писали). CSS-счётчики и вывод в
content. Это нормально. Другое дело всякие «меню» на чекбоксах и «вкладки» на радио-кнопках с:checked. Вот так лучше не делать, потому что это портит UX, доступность и это хак.andreymal
Почему портит?
alexnozer
Потому что семантика, свойства, состояния и поведение не соответствуют требованиям виджета и ожиданиям пользователей. Поясню на примере чекбокса и кнопки раскрытия меню.
Чекбокс — это элемент формы, который предназначен для выбора одной или нескольких опций. У него есть устоявшийся аффорданс (внешний вид, который намекает на назначение элемента, подпись и квадрат с пустотой или галочкой внутри). Пользователи видит это и понимают, что можно нажать, галочка появится/исчезнет, опция будет выбрана/не выбрана, это не приведёт ни к каким лишним действиям и где-то рядом будет форма с кнопкой отправки.
Пользователи мыши ожидают, что нажатие по тексту также меняет состояние чекбокса. Пользователи клавиатуры ожидают, что на элемент можно сфокусироваться и появится рамка фокуса, а нажатие пробела переключит состояние. Пользователи программ чтения с экрана слышат подпись, роль и состояние элемента и из этого понимают, что это чекбокс и что с ним можно делать. Пользователи программ голосового управления ожидают, что голосовая команда «отметь такой-то флажок» сработает. И так далее, таковы ожидания.
Кнопка меню работает иначе и там другие ожидания. Использование чекбокса для меню не соответствует ожиданиям:
Если чекбокс скрыт (часто при реализации меню его скрывают и оставляют
<label>), то пользователи клавиатуры и программ чтения с экрана не смогут сфокусироваться и активировать его;Если чекбокс скрыт визуально, но доступен для клавиатуры, это приводит либо к тому, что пользователи не видят, где находится фокус, либо состояние фокуса не соответствует тому, что отображается. Обе ситуации запутывают;
Пользователи программ чтения с экрана слышат про чекбокс и не понимают, что происходит. Почему тут чекбокс? Это какая-то форма? Как чекбокс связан с меню? Что нужно сделать?
Пользователи программ голосового управления могут озвучивать команду и не получать никакой обратной связи, ничего не произойдёт;
При открытии меню, пользователи программ чтения с экрана услышат «отмечено» вместо «развёрнуто»;
При открытии с помощью клавиатуры фокус не будет помещён на первый интерактивный элемент внутри меню, нажатие Esc не приведёт к закрытию меню и возврату фокуса на элемент, табуляция внутри меню не будет зациклена;
И так далее...
Чекбокс просто не соответствует тому, как должно себя вести меню.
andreymal
Для меня как минимум неочевидно, являются ли перечисленные проблемы принципиально нерешаемыми. Но предположу, что они действительно нерешаемые — как мне быть, если я хочу, чтобы мой сайт был работоспособен без JS?
alexnozer
Отчасти решаемые, отчасти нет. Можно заставить чекбокс быть кнопкой меню, обвешав его с ног до головы ARIA-атрибутами и JS-ом, который будет делать всё то, что чекбокс не делает, а кнопка меню должна.
Что касается работоспособности без JS, то есть как минимум три стратегии:
Прогрессивное улучшение. Без JS меню просто всегда отображается и не скрывается. С JS скрыто и переключается честно, с помощью кнопки со всеми нужными состояниями.
nojs+<noscript>. Наbodyвисит классnojsи удаляется скриптом при загрузке страницы. Соответственно, если скрипт отработал, значит JS есть и класса не будет. Если нет, класс останется и от него в CSS можно скрыть элементы, которые зависят от JS. А<noscript>отображает содержимое только когда JS нет. В него помещается упрощённый резервный вариант, который работает без JS.Ссылки и формы. Любое действие — это переход на другую страницу или отправка формы с обработкой на сервере. Меню может быть отдельной лёгкой страницей с набором ссылок, а кнопка раскрытия меню — ссылка на эту страницу. Вот статья об этом. С View Transition очень даже неплохо получается.
В современных браузерах кое какие элементы UI можно реализовать средствами HTML/CSS и это работает без JS:
<details>+<summary>, Popover API, Invoker Commands,<dialog>, Scroll Snap. Это честные способы реализовать что-то, например меню через Popover API, вместо хаков на чекбоксах.