| layout | ../../layouts/Layout.astro |
|---|---|
| title | HTML |
| description | Семантика HTML, формы, accessibility, SEO, metadata, SVG, media и устройство браузерного документа |
| category | Frontend |
| kind | questions |
| order | 30 |
Что такое HTML и какую задачу он решает?
|
Короткий ответ HTML описывает структуру и смысл документа: заголовки, текст, навигацию, формы, ссылки и изображения. Браузер разбирает разметку и строит DOM, который используют CSS, JavaScript, поисковые роботы и assistive technologies. Полный ответ HTML, HyperText Markup Language, — язык разметки, который описывает структуру и семантику документа. Он не задает бизнес-логику приложения и не отвечает за визуальный layout: обычно HTML описывает, что это за контент, CSS — как он выглядит, а JavaScript — как меняется и реагирует на события. Например: <article>
<h2>Корзина</h2>
<p>В корзине 3 товара</p>
<button type="button">Оформить заказ</button>
</article>Здесь браузер получает не просто набор строк. После parsing он создает DOM-узлы с типами и отношениями: HTML важен сразу нескольким потребителям:
Поэтому визуально одинаковые варианты не всегда эквивалентны: <div class="button">Купить</div>
<button type="button">Купить</button>Оба можно стилизовать одинаково, но второй вариант уже имеет keyboard behavior, focusability, button semantics и ожидаемое поведение формы. Еще один важный момент: HTML source и DOM — не одно и то же. Parser может исправить часть невалидной вложенности, добавить служебные узлы, а JavaScript позже меняет DOM динамически. На интервью полезно связать HTML не только с тегами: HTML — это контракт структуры и семантики страницы, из которого браузер строит DOM и accessibility model; корректная разметка уменьшает объем CSS/JS, который приходится имитировать вручную. |
Что такое HTML attribute?
|
Короткий ответ Attribute задает дополнительную информацию, состояние или настройку HTML element: Полный ответ HTML attribute — часть start tag, которая уточняет свойства элемента или его поведение. <a
href="/profile"
class="link"
lang="en"
>
Profile
</a>Здесь:
Attributes удобно разделять на несколько групп. Global attributes доступны у большинства HTML elements: Element-specific attributes определены для конкретных элементов: Boolean attributes работают по факту присутствия, а не по строковому значению: <button disabled>Save</button>Для boolean attribute запись Важно отличать HTML attribute от DOM property. Initial markup задает attributes, а browser создает DOM object с
properties. Для некоторых значений они отражают друг друга, но не всегда являются одной сущностью. Например, текущее
<input value="initial" />input.value = 'current';В framework-разработке эта разница особенно заметна при property binding и attribute binding. Attributes также не являются безопасным хранилищем. Любые значения в DOM видны клиенту, поэтому в На интервью хороший ответ включает три идеи: attribute находится в markup, может влиять на semantics/native behavior, а после parsing важно различать attribute и соответствующее DOM property. |
Что такое semantic HTML?
|
Короткий ответ Semantic HTML использует элементы по их назначению: Полный ответ Semantic HTML означает, что элемент выбирают прежде всего по смыслу и поведению, а не по его default-стилям. Например: <nav aria-label="Основная навигация">
<a href="/catalog">Каталог</a>
</nav>
<main>
<h1>Каталог</h1>
<button type="button">Добавить товар</button>
</main>
Accessibility Screen reader может быстро перемещаться по landmarks и headings, а native controls получают ожидаемый keyboard behavior без ручной реализации. Поддерживаемость Разметка Прогрессивное поведение браузера Native элементы уже умеют focus, form submission, link navigation, context menu, open in new tab и другие platform features. SEO и machine-readable structure Семантика помогает crawler понять hierarchy и назначение частей документа, хотя сама по себе не является гарантией ranking. Типичная ошибка — использовать семантический элемент только из-за названия. Например, Еще одна ошибка — считать framework component семантикой сам по себе: <app-action>Save</app-action>Custom Angular component не превращается автоматически в accessible button. Внутри него все равно нужно выбрать правильный native element и обеспечить contract компонента. ARIA также не должна быть первым способом исправления markup. Правило «No ARIA is better than bad ARIA» практически означает: сначала ищем native element, а роль и состояния добавляем вручную только когда platform primitive недостаточно. На интервью можно сформулировать так: semantic HTML переносит часть поведения и смысла из пользовательского JavaScript в стандартизированные browser primitives, поэтому интерфейс обычно получается доступнее, проще и устойчивее. |
Что такое document outline?
|
Короткий ответ Это логическая структура документа, прежде всего иерархия Полный ответ Под document outline на практике понимают логическую иерархию содержимого страницы: какой heading главный, какие разделы вложены друг в друга и где находятся основные landmarks. Например: <h1>Настройки аккаунта</h1>
<section>
<h2>Безопасность</h2>
<section>
<h3>Двухфакторная аутентификация</h3>
</section>
</section>
<section>
<h2>Уведомления</h2>
</section>Здесь уровни headings отражают информационную вложенность, а не размер шрифта. Визуальный размер всегда можно изменить CSS. Исторически спецификация HTML предлагала outline algorithm, в котором Практические правила:
Для SPA важна еще и динамика: после route change document title, main heading и focus должны оставаться согласованными, иначе визуально новая страница появилась, а пользователь screen reader продолжает находиться в старом контексте. На интервью сильный ответ: outline — это не магия sectioning tags, а явно спроектированная hierarchy headings и landmarks, которая отражает структуру контента и помогает навигации. |
Что такое doctype и зачем он нужен?
|
Короткий ответ
Полный ответ Современный HTML-документ обычно начинается так: <!doctype html>
<html lang="ru">
<!-- ... -->
</html>
Исторически сайты зависели от несовместимого поведения старых браузеров. Чтобы новые браузеры могли одновременно поддерживать старые страницы и стандартизированное поведение, появились режимы:
Без корректного doctype браузер может перейти в quirks mode. Тогда различия затрагивают, например, вычисление layout и часть CSS behavior. Такая проблема особенно неприятна тем, что HTML и CSS визуально выглядят корректно, но страница ведет себя иначе из-за document mode. Проверить режим можно через: document.compatMode;В standards mode обычно будет Старые doctypes были длинными, потому что ссылались на DTD. В современном HTML достаточно короткого На интервью полезно подчеркнуть: doctype нужен не для загрузки спецификации и не является HTML-тегом; его практическая роль — не дать браузеру случайно включить legacy quirks rendering. |
Что такое custom elements?
|
Короткий ответ Custom Elements API позволяет регистрировать собственные HTML elements с именем через дефис и lifecycle callbacks. Это часть Web Components; Shadow DOM, templates и slots — отдельные возможности и не включаются автоматически. Полный ответ Custom Elements — browser API для регистрации собственных элементов, которые участвуют в DOM как настоящие elements. Имя autonomous custom element должно содержать дефис, чтобы не конфликтовать с будущими built-in HTML tags. class UserBadge extends HTMLElement {
connectedCallback() {
this.textContent ||= 'Guest';
}
}
customElements.define('user-badge', UserBadge);После регистрации markup можно использовать так: <user-badge></user-badge>Основные lifecycle callbacks включают:
Важно: Custom Elements API не означает Shadow DOM автоматически. Компонент может остаться в обычном light DOM. Если
нужна style/DOM encapsulation, автор отдельно создает shadow root. Аналогично Есть несколько архитектурных trade-offs. Плюсы
Ограничения
Если В Angular custom elements могут быть interoperability boundary, но внутри одного Angular-приложения обычный Angular component часто проще: у него уже есть DI, templates, signals/inputs и framework lifecycle. На интервью полезно разделить понятия: Custom Elements — регистрация нового DOM element; Web Components — более широкий набор browser primitives, куда также относятся Shadow DOM и templates. |
Чем tag отличается от HTML element?
|
Короткий ответ Tag — синтаксическая часть HTML source, например Полный ответ Термины часто используют как синонимы в разговоре, но технически они относятся к разным уровням. Tag — токен в текстовой HTML-разметке: <p></p>
Element — логическая сущность, которую описывает markup и из которой после parsing появляется DOM element: <p class="lead">
Hello
<strong>world</strong>
</p>У Не у всех элементов структура одинаковая. Void elements не могут иметь child nodes в HTML и не используют end tag: <img
src="avatar.png"
alt="User avatar"
/>
<input name="email" />
<br />Слеш перед Есть также элементы, у которых end tag в source может быть опущен по правилам parser, например часть Разница полезна при отладке parser behavior: source содержит tags, а DOM DevTools показывает уже построенные nodes. Невалидная последовательность tags может быть исправлена parser-ом, поэтому получившееся element tree не всегда буквально повторяет source. На интервью достаточно сказать: tag — это синтаксис разметки, element — объект структуры документа, который этот синтаксис описывает. |
Чем block element отличается от inline element?
|
Короткий ответ
Полный ответ Термины «block element» и «inline element» исторически удобны, но в современном frontend важно не смешивать HTML semantics и CSS formatting behavior. User agent stylesheet обычно задает, например: p {
display: block;
}
span {
display: inline;
}Block-level box обычно участвует в block formatting context и занимает строку в своем normal flow, а inline box участвует в line formatting вместе с текстом. Но CSS может изменить это: span.badge {
display: inline-block;
}
nav.horizontal {
display: flex;
}
Есть и более сложные значения: Отдельный edge case — содержательная модель HTML. Нельзя рассуждать так: «если CSS сделал Практический пример: для текста внутри paragraph можно использовать На интервью сильный ответ: block/inline — это главным образом CSS formatting, semantic category HTML живет отдельно; default display можно изменить, semantics от этого не меняются. |
Зачем команде договариваться об HTML principles?
|
Короткий ответ HTML principles фиксируют повторяемые решения: native semantics, keyboard accessibility, heading/form structure, правила для links/buttons и допустимое применение ARIA. Это уменьшает количество случайных решений в каждом PR и делает интерфейс стабильнее для пользователей, тестов и поддержки. Полный ответ В большой codebase HTML редко ломается одной очевидной ошибкой. Чаще качество постепенно деградирует через сотни
локально «нормальных» решений: clickable Поэтому team principles полезны как общие invariants разметки. Например, команда может договориться:
Лучшие правила подкрепляются tooling. Например, часть ошибок находят template lint rules, axe/component tests и browser accessibility checks. Но lint не определит, правильно ли названо действие или логично ли устроена hierarchy, поэтому review остается нужен. Для component library principles особенно важны: одна ошибка в primitive размножается на десятки экранов. Если design
system Не стоит превращать guidelines в каталог запретов на сотни страниц. Сильная policy короткая, объясняет почему правило существует и дает escape hatch для реальных edge cases. На интервью можно привести пример: команда запрещает clickable |
Чем section, article, main, aside и nav отличаются друг от друга?
|
Короткий ответ
Полный ответ Эти элементы помогают описать роль области документа, но не являются взаимозаменяемыми «семантическими div».
Главное уникальное содержимое текущего document. Обычно пользователь ожидает один активный <main>
<h1>Заказы</h1>
<!-- основной контент страницы -->
</main>
Крупный блок навигационных links: главное меню, навигация раздела, breadcrumbs. Не каждый набор из двух ссылок обязан
быть <nav aria-label="Основная навигация">...</nav>
<nav aria-label="Навигация по документации">...</nav>
Самостоятельная единица контента, которую в принципе можно использовать или распространять отдельно: пост, новость, комментарий, карточка публикации.
Тематическая часть документа. Обычно у нее есть heading. Если container нужен только для layout/styling и у него нет
отдельной темы,
Контент, связанный с окружающим материалом, но вторичный по отношению к основному потоку: related links, sidebar, дополнительная справка. Элементы могут вкладываться друг в друга. Например,
Главная ошибка — выбирать element по визуальному положению. Sidebar не всегда На интервью полезно объяснять через вопрос «может ли этот кусок существовать самостоятельно и какую роль он играет в структуре документа?», а не перечислять определения наизусть. |
Когда использовать button, а когда a?
|
Короткий ответ
Полный ответ Практическое правило простое: если после активации меняется location/resource — ссылка; если выполняется команда в текущем UI — кнопка. Навигация: <a href="/settings/security">Настройки безопасности</a>Действие: <button type="button">Открыть фильтры</button>Submit формы: <button type="submit">Сохранить</button>Почему это важно не только для accessibility. Link дает browser navigation contract Пользователь может скопировать URL, открыть link в новой вкладке, использовать context menu, browser history и обычные
link shortcuts. Button дает action contract Он focusable, активируется ожидаемыми keyboard keys, поддерживает Clickable Есть случаи, где UI выглядит как button, но semantics остаются link: например CTA «Открыть отчет» ведет на И наоборот, «Назад» внутри wizard может быть button, если он меняет локальный step без navigation URL. Но если product использует реальную browser history/route, link или navigation API может быть правильнее. У На интервью сильная формула: |
Когда команда может использовать HTML preprocessor или template engine?
|
Короткий ответ HTML preprocessor или template engine полезны, когда разметка генерируется сервером, CMS, static site generator или design system tooling. В Angular основным слоем обычно остаются Angular templates, но frontend-разработчик должен понимать, откуда приходит HTML, какие fragments может вставлять backend и какие ограничения это создает для структуры, styles и hydration. Полный ответ HTML preprocessor или template engine полезны, когда разметка генерируется сервером, CMS, static site generator или design system tooling. В Angular основным слоем обычно остаются Angular templates, но frontend-разработчик должен понимать, откуда приходит HTML, какие fragments может вставлять backend и какие ограничения это создает для структуры, styles и hydration. |
Как backend или CMS может влиять на frontend markup?
|
Короткий ответ Backend или CMS могут добавлять wrappers, ids, classes, служебные attributes и готовые HTML-фрагменты. Эти соглашения нужно учитывать, чтобы не сломать CSS, accessibility, analytics и автотесты. Хороший ответ включает мысль, что такие контракты лучше документировать, а не выяснять по случайным DOM-структурам в production. Полный ответ Backend или CMS могут добавлять wrappers, ids, classes, служебные attributes и готовые HTML-фрагменты. Эти соглашения нужно учитывать, чтобы не сломать CSS, accessibility, analytics и автотесты. Хороший ответ включает мысль, что такие контракты лучше документировать, а не выяснять по случайным DOM-структурам в production. |
Как договориться о комментариях в HTML?
|
Короткий ответ HTML-комментарии стоит оставлять только для неочевидной структуры, интеграционного ограничения или временного workaround. Они не должны пересказывать obvious markup. В Angular чаще лучше помогают понятные имена компонентов, inputs и template blocks, а большой комментарий в template может быть сигналом, что код стоит упростить. Полный ответ HTML-комментарии стоит оставлять только для неочевидной структуры, интеграционного ограничения или временного workaround. Они не должны пересказывать obvious markup. В Angular чаще лучше помогают понятные имена компонентов, inputs и template blocks, а большой комментарий в template может быть сигналом, что код стоит упростить. |
Что делает атрибут lang?
|
Короткий ответ lang задает язык документа или фрагмента. Он помогает screen reader выбрать произношение, браузеру — проверку орфографии и переносы, а поисковым системам — интерпретировать содержимое. Полный ответ
|
Для чего нужны data-* attributes?
|
Короткий ответ Они хранят небольшие пользовательские данные прямо на element и доступны через dataset. Их используют для связи разметки с поведением или тестами, но не как замену application state и не для секретных данных. Полный ответ Они хранят небольшие пользовательские данные прямо на element и доступны через |
Из каких частей состоит HTML5 как open web platform?
|
Короткий ответ HTML5 в широком смысле часто называют набором Web Platform API: semantic HTML, forms, media, canvas, SVG, storage, offline capabilities, history, drag and drop и messaging. На интервью важно не смешивать сам язык разметки с браузерными API вокруг него. Для Angular-разработчика это база, на которую опираются компоненты, forms, routing и интеграции с browser APIs. Полный ответ HTML5 в широком смысле часто называют набором Web Platform API: semantic HTML, forms, media, canvas, SVG, storage, offline capabilities, history, drag and drop и messaging. На интервью важно не смешивать сам язык разметки с браузерными API вокруг него. Для Angular-разработчика это база, на которую опираются компоненты, forms, routing и интеграции с browser APIs. |
Чем cookie отличается от sessionStorage и localStorage?
|
Короткий ответ Cookie может автоматически отправляться с HTTP-запросами и иметь флаги HttpOnly, Secure, SameSite. localStorage и sessionStorage доступны JavaScript, привязаны к origin и не отправляются автоматически; sessionStorage живет в рамках вкладки, localStorage сохраняется дольше. Секретные tokens опасно хранить в Web Storage из-за XSS. Полный ответ Cookie может автоматически отправляться с HTTP-запросами и иметь флаги |
Чем script, script async и script defer отличаются?
|
Короткий ответ Обычный script блокирует HTML parsing до загрузки и выполнения. async загружается параллельно и выполняется сразу после загрузки, поэтому порядок между async scripts не гарантирован. defer загружается параллельно, выполняется после parsing в порядке объявления и обычно лучше подходит для application bundle. Полный ответ Обычный |
Почему clickable div — плохая практика?
|
Короткий ответ div не получает focus, keyboard activation, role и accessible name интерактивного элемента автоматически. Их ручная имитация сложна и хрупка. Для действий следует использовать button, для переходов — a. Полный ответ
|
Что происходит после получения HTML-документа?
|
Короткий ответ Браузер начинает streaming parse HTML еще до полной загрузки документа: tokenizer и tree construction строят DOM, preload scanner заранее обнаруживает ресурсы, параллельно загружаются CSS, JavaScript, изображения и fonts. Для первого render браузеру нужны DOM и CSSOM, после чего идут style calculation, layout, paint и compositing. Полный ответ Получение HTML не означает, что браузер сначала скачивает весь файл, а потом начинает работать. Обычно обработка идет потоково: новые байты приходят по сети и постепенно проходят decoding, tokenization и tree construction. Упрощенная последовательность выглядит так:
Это не строго последовательный waterfall. Сеть, parsing и часть resource loading перекрываются по времени. Например,
preload scanner может найти JavaScript способен менять эту картину. Классический parser-blocking script: <script src="app.js"></script>может остановить HTML parser до загрузки и выполнения script, потому что JavaScript потенциально меняет документ через
DOM APIs или CSS обычно не блокирует сам HTML parsing, но может задерживать render: браузеру нужен CSSOM, чтобы корректно посчитать styles. Кроме того, script, который зависит от computed styles, тоже может косвенно ждать stylesheet. Практический performance-вопрос поэтому звучит не «сколько весит HTML», а что находится на Critical Rendering Path:
В SSR/Angular сценарии server-rendered HTML может дать пользователю содержимое раньше bundle, но затем framework еще должен bootstrap/hydrate приложение. Поэтому «HTML уже пришел» и «страница полностью интерактивна» — разные milestones. На интервью полезно не перечислять весь browser engine: HTML парсится потоково в DOM, ресурсы обнаруживаются и загружаются параллельно, а первый render зависит от critical resources, CSSOM, layout и paint. |
Что такое progressive enhancement?
|
Короткий ответ Progressive enhancement начинает с базового доступного HTML и основного пользовательского сценария, а затем добавляет CSS, JavaScript и новые browser APIs как улучшения. Если enhancement недоступен или сломался, ключевой content и действие по возможности остаются рабочими. Полный ответ Progressive enhancement — стратегия проектирования от устойчивой базы к дополнительным возможностям, а не список fallback для старых браузеров. Простой пример — поиск: <form
action="/search"
method="get"
>
<label for="query">Поиск</label>
<input
id="query"
name="q"
/>
<button type="submit">Найти</button>
</form>Без JavaScript form уже имеет понятную семантику и может отправить запрос. JavaScript затем может добавить autocomplete, debounce, client-side validation или обновление результатов без full-page navigation. Подход полезен по нескольким причинам. Resilience Bundle может не загрузиться из-за сети, CSP, CDN incident или runtime error. Если весь основной сценарий существует только после JavaScript bootstrap, пользователь получает пустой или мертвый интерфейс. Accessibility Native HTML primitives уже содержат semantics, keyboard behavior и form behavior. Enhancement поверх них обычно надежнее, чем custom widget с нуля. Performance Server-rendered или prerendered content может стать доступным до загрузки большого client bundle. Browser diversity Новый API можно включать через feature detection, не запрещая весь продукт пользователю, у которого нет одной advanced capability. Например: if ('share' in navigator) {
showNativeShareButton();
}При этом progressive enhancement не означает «приложение обязано полностью работать без JavaScript». Для сложного редактора или IDE это может быть неразумно. Нужно определить minimum viable experience: что является core content и какие действия должны переживать отсутствие конкретной enhancement. Для Angular SSR это особенно полезная модель: SSR HTML дает ранний meaningful state, hydration добавляет client-side interactivity, а отдельные advanced APIs подключаются только там, где доступны. На интервью сильная формулировка: progressive enhancement проектирует надежный baseline и делает сложность additive; отказ одного слоя не должен без необходимости уничтожать весь пользовательский сценарий. |
Чем progressive enhancement отличается от graceful degradation?
|
Короткий ответ Progressive enhancement проектирует продукт снизу вверх: сначала рабочий baseline, затем улучшения. Graceful degradation обычно начинается с полнофункционального experience и определяет, как он упростится при отсутствии части возможностей. Оба подхода стремятся сохранить полезный сценарий, но точка проектирования разная. Полный ответ Оба термина описывают устойчивость интерфейса при разных возможностях среды, но направление мышления отличается. Progressive enhancement: Сначала проектируется минимальный надежный слой, а каждый следующий делает experience лучше. Graceful degradation: Сначала существует богатый вариант, затем команда определяет приемлемое поведение для менее способной среды. Например, редактор изображений может использовать WebGL как основной renderer. Полностью воспроизводить его без JavaScript бессмысленно, но graceful degradation может дать preview, download original или понятное сообщение о неподдерживаемой функции вместо crash. А обычная форма регистрации естественно подходит progressive enhancement: native form работает сама, а JavaScript добавляет password strength meter и inline validation. Разница не означает, что один подход всегда «правильный», а второй устарел. Выбор зависит от продукта:
Главная ошибка — называть graceful degradation ситуацию, когда unsupported browser просто получает белый экран. Degraded experience все еще должен быть преднамеренным и полезным. На интервью можно ответить через направление: progressive enhancement добавляет capability к baseline, graceful degradation снимает capability с full experience, стараясь сохранить core value. |
Чем browser support отличается от browser optimization?
|
Короткий ответ Browser support — обещание, что в указанном окружении работает определенный набор пользовательских сценариев. Browser optimization — дополнительная работа над скоростью, UX или использованием platform features для приоритетных окружений. Поддерживать браузер не значит давать ему pixel-identical experience. Полный ответ Полезно разделять contract корректности и уровень оптимизации. Browser support отвечает на вопрос:
Например, support matrix может гарантировать login, поиск, оформление заявки и доступ к документам в последних двух major versions Chrome, Edge, Firefox и Safari. Browser optimization отвечает на другой вопрос:
Например, приложение поддерживает Safari и Chrome, но для Chromium использует дополнительную производительную feature только после feature detection. Safari получает тот же core scenario другим путем. Поддержка не обязана означать:
Она должна описывать observable user outcome. Иначе QA получает бесконечную задачу «все должно быть одинаково везде». Optimization также нельзя использовать как оправдание функциональной поломки. Если браузер заявлен supported, critical flow должен работать даже без отдельных performance enhancements. Практически полезно фиксировать:
На интервью сильный ответ: support — это product contract на работоспособность, optimization — приоритизация качества и performance поверх этого contract. |
Как определить, какие браузеры поддерживать?
|
Короткий ответ Support matrix определяют по реальной аналитике аудитории, business/regulatory requirements, корпоративным ограничениям, capabilities продукта и стоимости QA/разработки. Ее нужно версионировать и регулярно пересматривать, а не выбирать по личным предпочтениям команды. Полный ответ Фраза «поддерживаем современные браузеры» почти бесполезна: она не определяет версии, устройства и критерий работоспособности. Нужна явная support policy. Решение обычно собирают из нескольких источников. Product analytics Какой процент active users использует конкретные browser/version/device combinations? Для B2B особенно важно смотреть не на глобальную статистику, а на собственных клиентов. Business requirements Один enterprise customer со старым managed browser может быть важнее 0.2% общей аудитории. Regulatory и accessibility requirements Государственные или финансовые продукты могут иметь дополнительные требования к environments и assistive technologies. Required Web APIs Если ключевая функция зависит от WebAuthn, camera, WebGL или другой capability, нужно проверить поддержку и качество реализации, а не только browser version. Cost of support Каждый дополнительный environment увеличивает test matrix, polyfills, workarounds и incident surface. Support имеет цену, поэтому legacy browser не должен сохраняться «навсегда по привычке». После решения policy связывают с tooling: Browserslist/targets, transpilation, polyfills, CI/e2e matrix и QA devices. Но Browserslist сам по себе не является продуктовой policy: он описывает технические targets, а не полный набор user scenarios. Полезно заранее определить критерий удаления browser version: например, usage ниже порога несколько месяцев и отсутствие contractual клиентов. Изменение support лучше анонсировать, а не обнаруживать после случайного dependency upgrade. На интервью хорошо показать product thinking: browser matrix — результат данных, обязательств и стоимости, после чего она превращается в конкретные build/test targets. |
Что такое graded browser support?
|
Короткий ответ Graded browser support делит environments на уровни с разными гарантиями: например, full support, functional support и unsupported/limited fallback. Это делает ожидания проверяемыми и не заставляет команду обещать одинаковый experience для всех браузеров. Полный ответ Идея graded support — заменить бинарное «работает / не работает» несколькими уровнями service contract. Пример:
Такой подход полезен, когда аудитория гетерогенна. Например, основной B2C трафик тестируется глубоко на актуальных mobile Safari/Chrome, а редкий corporate browser сохраняет critical business flow без всех animation/performance guarantees. Tier должен описывать не название браузера, а что именно команда проверяет. Иначе «Tier B» превращается в красивую метку без смысла. Нужно также избегать вечного накопления tiers. Если environment почти не используется, поддержка должна иметь owner и review date. Graded support хорошо сочетается с progressive enhancement: lower tier может получить baseline, а richer capabilities включаются в более сильных environments. На интервью полезно сказать: graded support управляет стоимостью compatibility через разные явные SLA опыта, а не через случайный набор browser hacks. |
Когда компоненту нужна отдельная browser support policy?
|
Короткий ответ Отдельная policy нужна, когда capability компонента уже общей матрицы приложения: camera, clipboard, WebGL, file system, advanced drag-and-drop, heavy graphics или другой API с неодинаковой поддержкой. Тогда документируют feature detection, fallback и environments, где гарантируется полный сценарий. Полный ответ Product-level support matrix не всегда достаточно. Страница может быть поддержана в Safari, но конкретный 3D editor, camera scanner или advanced clipboard flow иметь более узкие технические требования. Отдельная component/feature policy оправдана, если есть хотя бы одно из условий:
Например, общий продукт поддерживает iOS Safari, но bulk file editor требует File System Access API. Вместо ложного
«Safari unsupported» можно оставить приложение supported и дать editor другой flow: обычный Правильная реализация обычно использует feature detection, а не user-agent sniffing: if ('showOpenFilePicker' in window) {
// enhanced flow
} else {
// fallback
}UA detection иногда нужен для известных engine bugs, но как основная capability model он хрупок. Policy должна отвечать:
На интервью сильная мысль: support матрица продукта описывает доступность продукта, а отдельная feature policy — более узкий contract конкретной capability, не понижая без необходимости весь browser до unsupported. |
Почему HTML-парсер не падает на невалидной разметке?
|
Короткий ответ HTML parser intentionally error-tolerant: спецификация задает deterministic tokenization, tree construction и error recovery для множества невалидных случаев. Браузер строит исправленный DOM вместо того, чтобы прекращать отображение страницы, поэтому DOM может отличаться от исходного source. Полный ответ HTML исторически должен был отображать огромный объем несовершенной разметки в интернете. Если бы одна ошибка закрытия tag останавливала документ как строгий XML parser, web был бы значительно менее совместим. Поэтому HTML parsing specification описывает не только valid syntax, но и точные recovery rules. Например: <p>One</p>
<p>Two</p>При встрече второго Другой известный пример — таблицы: browser может добавить Это важно для разработки по нескольким причинам. DOM может не повторять source DevTools Elements показывает построенное tree, а View Source — исходный response. Невалидность не означает predictability «Браузер все исправит» — плохая стратегия. Recovery rules сложны, а разные контексты ( Framework hydration чувствительна к структуре Если server markup невалиден и parser перестроил DOM, client framework может получить hydration mismatch. Security/sanitization Нельзя проектировать sanitizer исходя из наивной строковой модели tags; parser behavior и DOM contexts имеют значение. Поэтому validator/linter все еще полезен, хотя browser page визуально «работает». На интервью стоит сказать: HTML forgiving не потому, что ошибок нет, а потому что error recovery стандартизирован; браузер продолжает parsing и строит определенный DOM, который иногда отличается от написанного source. |
Чем DOM отличается от HTML source?
|
Короткий ответ HTML source — исходный текст документа. DOM — текущее объектное дерево после parsing/error recovery и последующих изменений JavaScript. Поэтому View Source и DevTools Elements могут показывать разную структуру и значения. Полный ответ HTML source и DOM относятся к разным этапам жизни страницы. HTML source — текст, полученный по сети или записанный в документ: <ul id="list"></ul>DOM — объектная модель, созданная parser и доступная через JavaScript: const list = document.querySelector('#list');
list.append(document.createElement('li'));После этого DOM содержит DOM может отличаться от source еще до JavaScript из-за parser recovery:
После запуска приложения различие становится еще сильнее: Angular/React добавляют и удаляют nodes, меняют attributes, рендерят portals/overlays и обновляют text. Практическое следствие для debugging:
Это особенно важно при SSR/hydration. Если ошибка существует уже в server HTML, нужно смотреть response/source. Если она появляется после bootstrap, нужен current DOM и framework lifecycle. DOM также не равен accessibility tree: accessibility model строится на основе DOM, semantics, styles и ARIA, но может скрывать часть nodes или представлять их другими roles. На интервью полезная формула: source — serialization на входе parser, DOM — live runtime model после parser и JavaScript. |
Что такое preload, prefetch и preconnect?
|
Короткий ответ
Полный ответ Resource hints решают разные части latency, поэтому их нельзя считать тремя вариантами одного и того же.
<link
rel="preload"
href="/fonts/inter.woff2"
as="font"
type="font/woff2"
crossorigin
/>Browser начинает fetch раньше обычного discovery. Типичные кандидаты: critical font, hero/LCP image или ресурс, который browser иначе обнаружит слишком поздно. Но preload не должен превращаться в список всех assets страницы.
<link
rel="prefetch"
href="/next-page.js"
/>Обычно имеет более низкий priority и полезен для вероятной следующей navigation. Browser может игнорировать hint в зависимости от network/policy.
<link
rel="preconnect"
href="https://cdn.example.com"
crossorigin
/>Он заранее выполняет DNS/TCP/TLS connection setup, но не загружает конкретный файл. Это полезно для действительно критичного third-party origin. Preconnect ко всем возможным доменам тратит sockets и ресурсы. Есть также Hints — подсказки browser scheduler, а не абсолютные команды. Их эффективность нужно проверять через waterfall, Performance panel и реальные Web Vitals. То, что ускоряет desktop broadband, может ухудшить constrained mobile network. На интервью сильный ответ: preload двигает fetch текущего critical resource раньше, prefetch готовит вероятное будущее, preconnect сокращает connection latency; каждый hint имеет opportunity cost. |
Как работает HTML form?
|
Короткий ответ
Полный ответ HTML form — не просто контейнер для Простейший пример: <form
action="/search"
method="get"
>
<label for="query">Поиск</label>
<input
id="query"
name="q"
required
/>
<button type="submit">Найти</button>
</form>Native submit можно запустить кнопкой
В набор данных обычно попадают controls с JavaScript может перехватить flow: form.addEventListener('submit', (event) => {
event.preventDefault();
const data = new FormData(form);
// отправить через fetch или обработать локально
});Но даже SPA выигрывает от настоящего Важно различать Backend всегда должен повторно валидировать и авторизовывать данные. DOM, hidden fields и client validation контролирует пользователь. На интервью полезная формула: form — это встроенный protocol браузера для группировки controls, validation и submit; JavaScript может расширить или перехватить этот flow, но не обязан реализовывать его с нуля. |
Что делают action и method у формы?
|
Короткий ответ
Полный ответ
<form
action="/orders"
method="post"
>
<input name="comment" />
<button type="submit">Создать</button>
</form>Если GET сериализует данные в query string: POST помещает form payload в request body. Его формат задает <form
action="/avatar"
method="post"
enctype="multipart/form-data"
>
<input
type="file"
name="avatar"
/>
<button type="submit">Загрузить</button>
</form>У submit buttons есть полезный override contract: <button type="submit">Сохранить</button>
<button
type="submit"
formaction="/preview"
formmethod="post"
>
Preview
</button>Это позволяет одной форме иметь несколько осмысленных submit actions без ручного click-handler для каждой кнопки. У HTML form не умеет напрямую отправлять И главное: method не является security boundary. POST не скрывает данные от сети без HTTPS и не заменяет authentication, authorization или CSRF protection. На интервью достаточно связать |
Чем GET form отличается от POST form?
|
Короткий ответ GET подходит для безопасных операций вроде поиска и фильтров: параметры становятся частью URL, который можно сохранить, скопировать и повторить. POST отправляет данные в body и обычно используется для изменений состояния. Ни POST, ни GET не заменяют HTTPS, validation и authorization. Полный ответ Разница важнее, чем просто «query string против body»: выбор должен отражать семантику операции. GET используют для чтения и поиска, которые не должны менять значимое server state: <form
action="/catalog"
method="get"
>
<input name="query" />
<button type="submit">Искать</button>
</form>Получается URL вроде: Плюсы GET для такого сценария:
POST обычно выбирают для создания сущности, команды или передачи большого payload: <form
action="/orders"
method="post"
>
...
</form>Но есть важные ограничения. POST не означает «секретно». Body виден client tools, server logs/proxies могут его записывать, а транспорт защищает HTTPS. GET не должен менять состояние. Prefetcher, crawler или пользователь, повторив URL, не должен случайно удалить запись или провести платеж. POST не гарантирует idempotency. Double submit может создать два заказа, поэтому критические операции часто требуют idempotency key или server-side deduplication. Метод не заменяет security. И GET, и POST требуют server validation, authentication/authorization; state-changing requests дополнительно проектируют с учетом CSRF. На интервью сильный ответ: GET моделирует безопасное чтение и делает параметры частью адреса ресурса, POST моделирует submission/command; security определяется не тем, где лежат параметры. |
Почему специализированные типы input полезнее text?
|
Короткий ответ
Полный ответ
<input
type="email"
name="email"
autocomplete="email"
/>
<input
type="date"
name="birthday"
/>
<input
type="number"
name="count"
min="1"
max="10"
/>Преимущества специализированных типов:
Но <input
name="otp"
inputmode="numeric"
autocomplete="one-time-code"
/>
Date/time controls также могут визуально различаться между браузерами и OS. Если product требует custom picker, native input semantics и validation все равно стоит учитывать. Client type validation нельзя считать security: request можно отправить напрямую, не используя форму. На интервью полезно сказать: specialized type переносит часть UX и validation в platform, но type должен отражать семантику данных, а не заменять domain validation. |
Что такое label и как связать его с control?
|
Короткий ответ
Полный ответ Form field должен иметь понятное accessible name, и для большинства обычных inputs лучший primitive — настоящий
Явная связь: <label for="email">Email</label>
<input
id="email"
name="email"
type="email"
/>
Возможна implicit association: <label>
Email
<input
name="email"
type="email"
/>
</label>Явная связь часто удобнее в component layout, потому что label и input могут находиться в разных wrappers. Label — не место для длинной инструкции. Дополнительную подсказку обычно выводят отдельно и связывают через
<label for="password">Пароль</label>
<input
id="password"
aria-describedby="password-hint"
/>
<p id="password-hint">Минимум 12 символов</p>
В component library важно проверить, что генерируемые На интервью: label дает не просто текст рядом с input, а программно определимую связь между названием и control. |
Почему placeholder не должен заменять label?
|
Короткий ответ Placeholder — временная подсказка внутри поля: он исчезает при вводе, может иметь слабый contrast и не является надежной заменой постоянному accessible name. Его используют для примера значения, а назначение control задают label. Полный ответ UI вида <input placeholder="Email" />выглядит компактно, но теряет важную информацию сразу после того, как пользователь начал вводить значение. Проблемы placeholder-as-label:
Правильнее: <label for="phone">Телефон</label>
<input
id="phone"
name="phone"
placeholder="+372 5555 5555"
/>Здесь label отвечает что это, placeholder — пример формата. Floating label pattern допустим, если подпись действительно остается видимой и программно связанной с control после ввода, а не просто является placeholder с CSS-анимацией. Если пример или инструкция важны для успешного ввода, их лучше не прятать в placeholder вообще: постоянный hint рядом с полем устойчивее. На интервью хороший ответ связывает placeholder не только с accessibility, но и с memory load: пользователю не нужно помнить назначение уже заполненного поля. |
Для чего нужен name у form control?
|
Короткий ответ
Полный ответ
<label for="email">Email</label>
<input
id="email"
name="email"
value="user@example.com"
/>При submit получится примерно: Если убрать Некоторые controls имеют дополнительные правила:
Это полезно и без network submit: const data = new FormData(form);
console.log(data.get('email'));Не стоит использовать На интервью формула: |
Что такое native validation?
|
Короткий ответ Constraint Validation API позволяет браузеру проверять Полный ответ HTML controls умеют участвовать во встроенной constraint validation. <input
type="email"
name="email"
required
maxlength="120"
/>Browser вычисляет Основные состояния доступны через JavaScript API: input.checkValidity();
input.reportValidity();
input.setCustomValidity('Такой email уже используется');
Validation можно отключить у всей формы через CSS получает useful pseudo-classes вроде Native messages и UI зависят от browser/locale, поэтому design system иногда показывает собственные сообщения, но это не обязывает выбрасывать platform validity model. Самое важное ограничение: пользователь может удалить attributes в DevTools или отправить request напрямую. Server validation проверяет domain rules, consistency и authorization независимо от client. На интервью сильная мысль: native validation дает бесплатный baseline и API для UX, но доверенной остается только server-side проверка. |
Для чего нужен autocomplete?
|
Короткий ответ
Полный ответ Browser не должен угадывать назначение каждого поля только по placeholder или CSS. <input
name="email"
autocomplete="email"
/>
<input
type="password"
name="password"
autocomplete="current-password"
/>Для регистрации: <input
name="username"
autocomplete="username"
/>
<input
type="password"
name="password"
autocomplete="new-password"
/>Для адресов tokens можно уточнять контекстом Плюсы:
Не стоит ставить неверный token ради желаемого UI: autofill может подставить чувствительные данные не в то поле. На интервью: autocomplete — semantic contract с browser autofill, а не просто on/off switch. |
Как сделать accessible error message для поля?
|
Короткий ответ Ошибка должна быть конкретной, видимой и программно связанной с control, например через Полный ответ Плохая ошибка сообщает только «неверное значение» или меняет цвет border. Хорошая отвечает что не так и как исправить. <label for="email">Email</label>
<input
id="email"
name="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<p id="email-error">Введите адрес в формате name@example.com</p>Здесь сообщение:
Если у поля одновременно hint и error, После submit длинной формы полезен error summary с links к проблемным fields. Обычно focus переводят в summary или
первый invalid control один раз после неуспешной отправки, а не скачут focus-ом на каждом Для динамического появления ошибки live region используют осторожно. Если каждое нажатие клавиши вызывает assertive announcement, screen reader experience становится шумным. Часто достаточно связи через description и сообщения после blur/submit.
На интервью полезно перечислить три слоя: визуальное сообщение + programmatic relation + разумное focus/announcement behavior. |
Почему disabled field не отправляется вместе с формой?
|
Короткий ответ
Полный ответ <input
name="plan"
value="pro"
disabled
/>Визуально значение есть в DOM, но native submission не отправит Это часто удивляет при форме редактирования: разработчик disables поле, чтобы запретить изменение, а backend перестает получать значение. Если значение должно быть отправлено, нужно выбрать подходящую модель:
<input
value="PRO"
readonly
/>
<input
type="hidden"
name="planId"
value="42"
/>Hidden field не становится защищенным: его легко изменить через DevTools/request. Например, цену или роль нельзя доверять только потому, что input скрыт или disabled.
На интервью сильный ответ: disabled означает не только внешний вид, а исключение control из interaction и submission model. |
Чем disabled отличается от readonly?
|
Короткий ответ
Полный ответ Оба состояния могут визуально означать «нельзя менять», но contract у них разный. <input
name="id"
value="A-42"
readonly
/>
<input
name="internal"
value="secret"
disabled
/>
У checkbox, radio, select или button нет эквивалентного native Еще один UX trade-off: disabled control часто имеет низкий contrast и не позволяет пользователю скопировать значение. Readonly поле может быть лучше, если данные полезно выделить/copy. Ни На интервью: disabled убирает control из формы как активный участник; readonly сохраняет его как отправляемое значение, но запрещает редактирование. |
Для чего нужны fieldset и legend?
|
Короткий ответ
Полный ответ Представим группу: <fieldset>
<legend>Способ доставки</legend>
<label>
<input
type="radio"
name="delivery"
value="courier"
/>
Курьер
</label>
<label>
<input
type="radio"
name="delivery"
value="pickup"
/>
Самовывоз
</label>
</fieldset>Каждый radio имеет свой label, но
Есть и behavior: <fieldset disabled>
<legend>Дополнительные настройки</legend>
...
</fieldset>При этом спецификация имеет special case для descendants первого Не каждый визуальный card должен становиться fieldset. Если внутри нет логически связанной группы form controls, обычный container корректнее. В design system важно не потерять На интервью: label называет конкретный control, legend — вопрос/назначение группы controls. |
Как группировать radio buttons?
|
Короткий ответ Radio buttons одного выбора получают одинаковый Полный ответ Правильная native группа: <fieldset>
<legend>Тема</legend>
<input
id="theme-light"
type="radio"
name="theme"
value="light"
checked
/>
<label for="theme-light">Светлая</label>
<input
id="theme-dark"
type="radio"
name="theme"
value="dark"
/>
<label for="theme-dark">Темная</label>
</fieldset>Главное правило — одинаковый
Если выбор обязателен, Native radios также имеют ожидаемое keyboard behavior: Tab входит в группу, arrow keys меняют selection согласно
browser/platform conventions. При custom styling лучше визуально скрывать native input корректным способом, а не
заменять его набором Если options можно выбирать несколько одновременно, это уже checkbox group, а не radios. На интервью сильная формулировка: |
Что такое accessibility и WCAG?
|
Короткий ответ Accessibility, или a11y, — проектирование интерфейса так, чтобы им могли пользоваться люди с разными возможностями, устройствами и способами ввода. WCAG 2.2 — актуальная рекомендация W3C: success criteria организованы вокруг принципов perceivable, operable, understandable и robust и имеют уровни A, AA и AAA. Полный ответ Accessibility — это не отдельная «поддержка screen reader», а качество продукта для пользователей с разными зрительными, слуховыми, моторными, когнитивными особенностями и временными ограничениями. Сюда же попадают keyboard-only users, zoom, high contrast, speech input и другие способы взаимодействия. WCAG 2.2 группирует требования по четырем принципам POUR:
Уровни conformance:
Важно: WCAG — не чеклист HTML attributes. Один и тот же success criterion может выполняться разными техническими способами, а часть критериев требует human evaluation. Практический workflow: команда выбирает target, обычно WCAG 2.2 AA, превращает его в design/development rules, автоматические проверки и ручные сценарии, а не пытается «проверить WCAG» одной кнопкой Lighthouse. На интервью сильный ответ: accessibility — свойство пользовательского сценария, WCAG — проверяемая модель требований, а не конкретная библиотека или набор ARIA attributes. |
Что такое keyboard navigation и visible focus?
|
Короткий ответ Ключевые действия должны выполняться без мыши в логичном focus order. Текущий focus обязан быть заметен; нельзя удалять outline без равноценной замены. Native controls уже дают ожидаемые Tab/Shift+Tab и activation semantics, а composite widgets дополнительно используют arrow keys по своему паттерну. Полный ответ Keyboard accessibility начинается с того, что пользователь может дойти до интерактивного элемента, понять где находится и выполнить действие. Для обычной страницы Tab перемещает focus по focusable controls, Shift+Tab — назад. Порядок обычно должен следовать DOM
и визуальной логике. Положительные <button type="button">Сохранить</button>
<a href="/help">Помощь</a>Native controls сразу получают keyboard semantics. Visible focus — отдельное требование. CSS вида :focus {
outline: none;
}без альтернативы делает интерфейс практически неуправляемым. Современный вариант часто строят на Нужно проверять не только наличие кольца, но и что оно:
У сложных widgets Tab обычно входит в компонент один раз, а внутреннее перемещение выполняется arrow keys согласно выбранному WAI-ARIA pattern. На интервью: keyboard support — это focus order + видимый focus + ожидаемая activation/navigation model, а не просто
|
Что такое focus management и focus trap?
|
Короткий ответ Focus management осмысленно перемещает DOM focus после значимых UI-переходов и возвращает его туда, откуда пользователь продолжит работу. Focus trap нужен для настоящего modal dialog, чтобы Tab не уходил в inert content; для обычных panels и dropdown без модальности trap часто вреден. Полный ответ Focus сообщает пользователю keyboard/screen reader, где сейчас находится точка взаимодействия. При динамическом UI браузер не всегда может сам выбрать правильное место, поэтому приложению иногда нужен focus management. Типичные случаи:
Focus trap означает, что Tab/Shift+Tab циклически остаются внутри modal context. Это корректно для modal dialog, потому что content снаружи должен быть недоступен для взаимодействия. Но trap вокруг sidebar, dropdown или обычного card создает keyboard trap — пользователь не может продолжить navigation. Для modal dialog важны четыре части:
На интервью полезная формула: focus management следует за изменением пользовательского контекста; focus trap допустим только там, где UI действительно modal. |
Что такое screen reader?
|
Короткий ответ Screen reader озвучивает и позволяет исследовать accessibility tree: headings, landmarks, links, controls, names, states и descriptions. Он не просто «читает DOM сверху вниз», поэтому визуально правильная страница может быть неудобной, если semantics или focus model неверны. Полный ответ Screen reader — assistive technology, которая предоставляет интерфейс через речь и/или Braille. Пользователь может читать текст последовательно, но часто работает намного быстрее через semantic navigation: прыгает по headings, landmarks, links, form controls, tables и другим категориям. Screen reader взаимодействует не напрямую с HTML source, а с accessibility tree, который browser строит из:
Например: <button aria-expanded="false">Фильтры</button>может быть объявлен как button с именем «Фильтры» и состоянием collapsed. Это объясняет, почему проверка Elements panel недостаточна. Element может присутствовать в DOM, но быть скрытым из accessibility tree; наоборот, роль и имя могут отличаться от того, что визуально кажется очевидным. Реальные screen readers также различаются по OS/browser combinations: VoiceOver + Safari, NVDA/JAWS + Chrome/Firefox и т.д. Поэтому для critical flows полезно иметь поддерживаемую test matrix, а не проверять случайную комбинацию один раз. Не нужно пытаться «озвучить все вручную» ARIA. Хорошая semantic разметка дает screen reader структурированную модель, в которой пользователь сам выбирает способ navigation. На интервью: screen reader — клиент accessibility API, а качество опыта определяется semantics, name/state, focus и keyboard behavior вместе. |
Что такое ARIA и когда ее использовать?
|
Короткий ответ ARIA описывает roles, states и relationships для accessibility tree, когда native HTML недостаточно. Она не добавляет keyboard behavior, focus management или визуальное состояние автоматически. Правило: сначала native HTML, затем минимально необходимая ARIA для custom/dynamic widget. Полный ответ WAI-ARIA позволяет уточнять accessibility semantics через Например custom disclosure может сообщать состояние: <button
type="button"
aria-expanded="false"
aria-controls="filters"
>
Фильтры
</button>
<div
id="filters"
hidden
>
...
</div>Но ARIA не реализует behavior. Если написать: <div role="button">Save</div>browser не добавит автоматически Tab focus, Space/Enter handling, disabled semantics и form behavior настоящего
Поэтому приоритет обычно такой:
ARIA особенно нужна для custom composite widgets: tabs, tree, grid, combobox, menu. Но тогда разработчик берет на себя и keyboard interaction model из соответствующего pattern. Опасный anti-pattern — «улучшать» native element конфликтующей role. Например, превращать кнопку в link через role вместо выбора настоящего элемента. ARIA values должны синхронно отражать runtime state: На интервью: ARIA меняет accessibility contract, а не behavior; использовать ее нужно минимально и только поверх правильно спроектированного interaction. |
Как ARIA и screen reader связаны с accessibility?
|
Короткий ответ Browser преобразует HTML и ARIA в accessibility tree, который screen reader получает через platform accessibility API. ARIA может уточнить role/name/state/relationship, но accessibility требует также keyboard behavior, focus, visual affordances и понятный content. Полный ответ Полезно представить цепочку: ARIA влияет прежде всего на слой semantics. Например: <button aria-pressed="true">Bold</button>сообщает, что button является toggle control и сейчас pressed. Но screen reader experience ломается, если visual state говорит одно, а Еще один пример: Не все users assistive technology используют speech. Accessibility tree также потребляют другие технологии и browser automation. Поэтому корректная semantics полезна шире одной программы. Главная ошибка — считать, что добавление На интервью: ARIA — входные данные для accessibility tree, screen reader — один из потребителей этого tree, а полноценная accessibility включает semantics + interaction + perception. |
Как сделать страницу доступнее без JavaScript?
|
Короткий ответ Начать с semantic HTML и native behavior: landmarks/headings, links, buttons, forms с labels, fieldset/legend, alt text, language и нормальная document order. JavaScript должен улучшать baseline, а не заменять базовые navigation/form semantics без необходимости. Полный ответ Большой объем accessibility можно получить до первого JavaScript handler. Пример базовой страницы: <header>...</header>
<nav aria-label="Основная навигация">...</nav>
<main>
<h1>Профиль</h1>
<form
action="/profile"
method="post"
>
<label for="name">Имя</label>
<input
id="name"
name="name"
required
/>
<button type="submit">Сохранить</button>
</form>
</main>Здесь уже есть:
Другие platform primitives: JavaScript затем может добавить client validation, SPA navigation, autocomplete или transitions, но progressive enhancement снижает количество custom behavior, которое команда обязана воспроизводить и тестировать. Это не означает, что любое SPA обязано полностью работать без JS. Важно другое: не выбрасывать бесплатные browser semantics только потому, что приложение использует framework. Для Angular component нужно смотреть конечный rendered DOM: На интервью хороший ответ: самый дешевый слой accessibility — правильные native primitives и document structure; JS нужен для behavior, которого platform действительно не дает. |
Зачем команде accessibility checklist?
|
Короткий ответ Checklist превращает accessibility из памяти отдельных разработчиков в повторяемый delivery process: semantics, keyboard/focus, labels/names, color/contrast, dynamic announcements, responsive zoom и testing проверяются до merge. Но checklist дополняет, а не заменяет WCAG и usability review. Полный ответ Accessibility деградирует не только из-за сложных bugs. Чаще это накопление мелочей: убрали focus ring, добавили icon-only button без name, забыли label, сделали custom dropdown без arrows. Checklist полезен как definition of done для типовых изменений. Пример минимального review набора:
Для component library checklist должен быть глубже: один bug в Button/Dialog/Select размножается по всему продукту. Поэтому primitives имеет смысл тестировать и с screen reader/browser combinations. Checklist не должен быть сотней пунктов для любого typo PR. Его можно делать risk-based: простая текстовая правка проходит маленький набор, новый modal/combobox — полный interaction review. Лучше связывать пункты с owners/tooling: что проверяет lint, что component tests, что reviewer, что QA/manual audit. На интервью: checklist стандартизирует повторяемые ошибки и переносит accessibility в обычный engineering workflow, а не в аудит перед релизом. |
Какие accessibility tools стоит использовать во frontend workflow?
|
Короткий ответ Комбинировать static/template lint, axe или аналогичные automated rules, browser Accessibility tree/DevTools, Lighthouse как сигнал, component/e2e tests и ручные keyboard/screen-reader проверки. Ни один инструмент не покрывает accessibility целиком. Полный ответ Tooling лучше строить слоями. На этапе кода Template lint rules ловят очевидные проблемы: missing labels, invalid attributes, event patterns. В Angular часть правил можно проверять через Angular ESLint template rules. В component/e2e tests axe-core и похожие engines проверяют детерминированные rules: invalid ARIA, часть name/role проблем, contrast в некоторых состояниях, landmarks и т.д. Их удобно запускать на ключевых screens/states. В browser DevTools Accessibility pane показывает computed role, name, description, states и tree — это часто быстрее, чем угадывать, почему screen reader объявляет control странно. Lighthouse Полезен как smoke signal, но score 100 не означает WCAG conformance. Ручная проверка
Важно тестировать states, а не только initial page: validation error, loading, expanded popup, disabled state, route change. В CI не стоит блокировать релиз тысячами legacy violations без стратегии. Часто вводят baseline и правило «не добавлять новые violations», параллельно сокращая debt. На интервью: automation дает быстрый deterministic coverage, DevTools помогает debugging, а manual interaction проверяет смысл и behavior, которые машина не понимает. |
Почему accessibility нельзя полностью проверить автоматическими тестами?
|
Короткий ответ Автоматизация хорошо ловит формальные нарушения, но не может надежно оценить смысл alternative text, логичность focus order, понятность labels/errors, правильный widget pattern и реальный end-to-end опыт. WCAG требует сочетания machine-checkable и human-evaluated проверок. Полный ответ Автотест видит структуру и вычислимые properties. Например, он может определить:
Но он не знает смысла интерфейса. <img
src="chart.png"
alt="image"
/>Формально Аналогично tool не всегда способен решить:
Snapshot DOM test тоже недостаточен: behavior проявляется во времени и последовательности действий. Лучший подход — pyramid:
Автоматизация особенно ценна не как «сертификатор accessibility», а как защита от возврата уже известных classes bugs. На интервью: автотест отвечает на формальные вопросы, человек — на семантику и usability; conformance нельзя вывести из одного accessibility score. |
Что такое accessible name и как кнопка его получает?
|
Короткий ответ Accessible name — программно определимое имя control в accessibility tree. Для обычной button лучший источник — видимый
текст; имя также может вычисляться через Полный ответ Role сообщает что это, а accessible name — как этот конкретный control называется. <button type="button">Удалить файл</button>Browser вычисляет role Icon-only вариант: <button
type="button"
aria-label="Закрыть"
>
<svg aria-hidden="true">...</svg>
</button>
Если на странице уже есть visible heading/label, часто лучше <h2 id="dialog-title">Удалить проект?</h2>
<div
role="dialog"
aria-labelledby="dialog-title"
>
...
</div>Accessible Name and Description Computation имеет precedence rules: добавление <button aria-label="Отправить">Сохранить</button>Screen reader услышит «Отправить», а sighted user увидит «Сохранить» — это конфликт. Имена должны быть устойчивыми и различимыми. Пять кнопок «Еще» могут технически иметь name, но пользователю сложно понять, какая относится к конкретной карточке. На интервью: accessible name — computed semantic label control; сначала используем visible/native labeling,
|
Чем aria-label, aria-labelledby и aria-describedby отличаются?
|
Короткий ответ
Полный ответ Эти attributes участвуют в разных частях accessibility contract.
<button aria-label="Закрыть">×</button>Полезен, когда нет подходящего visible text. Минус: строка скрыта от sighted users и ее легко забыть локализовать/обновить.
<h2 id="title">Настройки профиля</h2>
<section aria-labelledby="title">...</section>Плюс — visible и accessible label используют один source of truth. Можно ссылаться на несколько ids.
<label for="password">Пароль</label>
<input
id="password"
aria-describedby="password-hint"
/>
<p id="password-hint">Минимум 12 символов</p>Здесь name — «Пароль», description — инструкция. Нельзя заменять name description-ом: control все равно должен иметь имя. И не нужно добавлять Для сложного dialog длинный content не стоит целиком подключать через На интервью: label/labelledby создают identity, describedby добавляет context. |
Для чего нужен aria-hidden?
|
Короткий ответ
Полный ответ Типичный пример — decorative icon рядом с текстом: <button type="button">
<svg aria-hidden="true">...</svg>
Скачать
</button>Если SVG не несет отдельного смысла, screen reader не должен объявлять его дополнительно.
Опасный случай: <div aria-hidden="true">
<button>Удалить</button>
</div>Button может оставаться keyboard-focusable, но отсутствовать в accessibility tree. Пользователь screen reader получает focus на «невидимом» semantic объекте. Поэтому перед применением нужно ответить: content действительно декоративный/дублирующий, или мы пытаемся починить структуру скрытием? Для modal background лучше использовать native dialog/inert behavior, а не вручную раскидывать На интервью: aria-hidden управляет accessibility exposure, а не DOM/visual visibility; focusable descendants под ним — серьезный anti-pattern. |
Что такое live region и role="alert"?
|
Короткий ответ Live region сообщает assistive technologies о динамическом content без перевода focus. Полный ответ SPA постоянно меняет DOM, но screen reader не должен озвучивать каждое изменение автоматически. Live regions позволяют пометить значимый asynchronous update. Для спокойного status: <div role="status">Файл сохранен</div>
Для срочной ошибки: <div role="alert">Соединение потеряно</div>
Другие настройки: Частые ошибки:
Если пользователь сам переводится focus к error summary, live region может быть не нужна. На интервью: live region сообщает важное изменение без focus move; |
Как сделать доступное modal dialog?
|
Короткий ответ Modal dialog должен иметь accessible name, modal semantics, корректный initial focus, Tab/Shift+Tab внутри dialog,
Escape/явную кнопку закрытия и разумный возврат focus после закрытия. Native Полный ответ Доступный modal — это не База на native element: <dialog aria-labelledby="confirm-title">
<h2 id="confirm-title">Удалить проект?</h2>
<p>Действие нельзя отменить.</p>
<button type="button">Отмена</button>
<button type="button">Удалить</button>
</dialog>При Accessible name Обычно через visible title + Initial focus Не всегда первый button. Для длинного semantic content WAI-ARIA APG рекомендует иногда focus статический
heading/paragraph с Keyboard loop Tab и Shift+Tab не должны уходить в background. Escape обычно закрывает dialog, также нужна видимая close/cancel action. Return focus После закрытия — trigger или следующий логичный control, если trigger исчез. Nested/async states Loading и error внутри dialog не должны случайно красть focus.
На интервью: modal accessibility — semantics + inert background + focus lifecycle + keyboard close, а не только role dialog. |
Как сделать доступные dropdown и tabs?
|
Короткий ответ Сначала определить настоящий widget pattern: disclosure, menu button, listbox и combobox выглядят похоже, но имеют
разную semantics/keyboard model. Tabs используют Полный ответ Слово «dropdown» слишком неоднозначно. До кода нужно понять задачу.
Если поставить Для menu button trigger обычно сообщает Tabs имеют отдельный pattern: <div
role="tablist"
aria-label="Настройки"
>
<button
role="tab"
aria-selected="true"
aria-controls="panel-general"
>
Общие
</button>
<button
role="tab"
aria-selected="false"
aria-controls="panel-security"
>
Безопасность
</button>
</div>
<div
role="tabpanel"
id="panel-general"
>
...
</div>Обычно Tab входит в tablist один раз, Left/Right arrows перемещают active/focused tab, а Для combobox keyboard и focus model еще сложнее: DOM focus часто остается на input, а active option задается через
На интервью: сначала выбираем interaction pattern, затем реализуем весь его keyboard/focus/ARIA contract; одинаковый popup визуально не означает одинаковую роль. |
Как сделать доступную icon button?
|
Короткий ответ Использовать настоящий Полный ответ Icon button часто выглядит минималистично, но semantic contract должен быть таким же полным, как у обычной кнопки. <button
type="button"
aria-label="Закрыть"
>
<svg
aria-hidden="true"
viewBox="0 0 24 24"
>
...
</svg>
</button>Почему не Если icon имеет visible text рядом: <button type="button">
<svg aria-hidden="true">...</svg>
Скачать
</button>дополнительный Для toggle icon button состояние следует сообщить явно: <button aria-pressed="true">...</button>и синхронизировать со visual state. WCAG 2.2 также делает важным target size для pointer interactions; product/design system должен не превращать 16×16 glyph в фактическую 16×16 hit area. Icon-only controls особенно требуют различимых names: ряд buttons с name «Еще» мало помогает. Можно дать контекст, например «Действия для отчета Q2». На интервью: SVG — decoration, button — interaction owner; name/state/focus должны принадлежать control, а не картинке внутри него. |
Почему цвет не должен быть единственным способом передачи информации?
|
Короткий ответ Цвет может быть неразличим при color-vision deficiency, low contrast, monochrome/high-contrast mode или плохом дисплее. Error, selection и status нужно дублировать независимым сигналом: текстом, icon/shape, underline, pattern или semantics, сохраняя достаточный contrast. Полный ответ Плохой пример — форма, где invalid input отличается только красной рамкой: Пользователь может не различить red/green, не видеть border из-за forced colors или вообще не видеть экран. Лучше одновременно дать:
То же относится к charts. Легенда «красный = revenue, зеленый = expenses» без labels/patterns требует различать цвет. В графике полезны direct labels, markers, line styles. Links внутри текста тоже не должны отличаться от surrounding text только оттенком, если contrast distinction недостаточен; underline или другой non-color cue часто проще. Важно различать два требования:
Можно выполнить одно и нарушить другое. Design tokens помогают централизовать contrast, но semantic redundancy остается задачей component design. На интервью: цвет — дополнительный channel, а critical meaning должен переживать ситуацию, где этот channel недоступен. |
Для чего нужен атрибут lang?
|
Короткий ответ
Полный ответ Базовая разметка: <html lang="ru"></html>Если внутри появляется другой язык: <p>
Документ называется
<span lang="en">Web Content Accessibility Guidelines</span>
.
</p>Для screen reader это важно: speech engine может сменить voice/pronunciation model и не пытаться читать English по русским фонетическим правилам.
Не нужно размечать каждый англицизм отдельным В SPA route change обычно сохраняет На интервью: lang — semantic metadata для правильной интерпретации текста browser/AT, особенно pronunciation; основной язык — на root, исключения — на fragments. |
Для чего нужны семантические HTML-теги?
|
Короткий ответ Semantic HTML передает назначение content через platform primitives: Полный ответ Semantic element выбирают по назначению, а не по default CSS. <nav aria-label="Основная навигация">...</nav>
<main>
<h1>Отчеты</h1>
<button type="button">Создать отчет</button>
</main>Из этой разметки browser уже может построить:
Эквивалент на Semantics полезна не только screen reader:
Но semantic tag не является магией. Custom Angular component тоже не создает native semantics автоматически. Важен rendered primitive внутри design-system component. На интервью: semantic HTML — первый accessibility layer: он дает корректный role/behavior из platform, а ARIA должна дополнять, а не переписывать его. |
Зачем нужен meta name="viewport"?
|
Короткий ответ
Полный ответ Mobile browser исторически мог рендерить desktop-oriented страницы в virtual viewport шириной около desktop layout, а затем масштабировать результат, чтобы он помещался на маленький экран. Для responsive layout это приводит к тому, что media queries видят не ту ширину, которую ожидает разработчик. Типичная настройка: <meta
name="viewport"
content="width=device-width, initial-scale=1"
/>Здесь:
После этого обычный responsive CSS работает предсказуемее: @media (width <= 48rem) {
.layout {
grid-template-columns: 1fr;
}
}Важно не путать viewport meta с полноценной mobile optimization. Он не исправляет сам по себе:
Также не стоит без серьезной причины запрещать zoom настройками вроде Есть дополнительные viewport directives, например Для SEO сам meta viewport не является «магическим ranking tag». Его ценность в корректном mobile experience и responsive rendering. Search systems оценивают страницу шире, чем наличие одной строки metadata. На интервью: viewport meta задает browser модель layout viewport для mobile; после этого responsive design все равно реализуется HTML/CSS и проверяется на реальных размерах и zoom. |
Что такое favicon?
|
Короткий ответ Favicon — иконка сайта, которую browser и другие clients используют во вкладках, bookmarks, history и search UI.
Основной вариант подключают через Полный ответ Favicon — не одна обязательная картинка определенного формата, а site icon, которую разные clients могут использовать в разных surfaces. Базовый вариант: <link
rel="icon"
href="/favicon.svg"
type="image/svg+xml"
/>Можно дополнительно предоставить raster fallback или platform-specific icons: <link
rel="icon"
href="/favicon-32.png"
sizes="32x32"
type="image/png"
/>
<link
rel="apple-touch-icon"
href="/apple-touch-icon.png"
/>Практические требования зависят от consumer. Browser tab, mobile home screen и search result могут выбирать разные resources. Поэтому favicon pipeline обычно включает несколько размеров/formats, но не нужно генерировать десятки файлов без понятной матрицы поддержки. Для Google Search favicon задается через Favicon не заменяет brand metadata и не гарантирует показ в search result: consumer сам решает, где и какую icon отобразить. Еще одна практическая ошибка — отдавать icon через URL, который требует auth/cookies. В public site favicon должен быть доступен без пользовательской session. На интервью: favicon — ресурс идентификации сайта, подключаемый через |
Что такое canonical URL?
|
Короткий ответ
Полный ответ Один и тот же content часто доступен по нескольким URL: Если это фактически одна страница, можно указать representative URL: <link
rel="canonical"
href="https://example.com/products/42"
/>Canonicalization нужна не только для «штрафа за duplicate content». Она помогает:
Но Для Google redirects и Практические правила:
Для JavaScript sites лучше отдать canonical уже в HTML source и не менять его на другое значение после bootstrap. Multiple conflicting canonical tags делают поведение менее предсказуемым. Если контент реально перемещен и старый URL больше не нужен, обычно лучше server redirect, а не canonical как имитация redirect. На интервью: canonical — hint о representative duplicate URL, который должен быть согласован с redirects, links и sitemap; он не меняет navigation и не гарантирует выбор поисковой системы. |
Для чего нужны title и meta description?
|
Короткий ответ
Полный ответ
<title>Angular signals: руководство и примеры | Example</title>
<meta
name="description"
content="Разбираем Angular signals, computed и effect на практических примерах."
/>
Browser показывает его во вкладке/history, а search engine использует как один из источников title link. Хороший title:
Важно: Google не обязан показывать Meta description <meta
name="description"
content="Практическое руководство по Angular signals с примерами state, computed values и effects."
/>Это краткое описание candidate для snippet, но не фиксированный текст результата. Google primarily формирует snippet из page content и использует meta description, когда она лучше описывает страницу для запроса. Поэтому бессмысленно проектировать description как жесткий pixel-perfect search UI. Лучше делать ее:
Для больших catalogs допустима качественная programmatic generation из page-specific data. В SPA title/description должны меняться вместе с route content. Предпочтительно, чтобы public indexable route имел корректную metadata уже при server/static rendering, а не зависел только от late client effect. На интервью: title и description влияют на представление страницы и понимание результата, но search engine сам формирует финальный title link/snippet; задача frontend — дать точные и согласованные signals. |
Какие HTML-теги важны для поисковых систем?
|
Короткий ответ Нет одного «SEO-тега». Поисковику важны доступный в DOM content, Полный ответ SEO начинается не с коллекции специальных meta tags, а с crawlable и понятного документа. Ключевые primitives:
Headings ( <h1>Angular forms</h1>
<h2>Reactive forms</h2>Links с настоящим <a href="/angular/forms">Angular forms</a>
Structured data обычно задают JSON-LD внутри Semantic elements ( Также важно, где находится content. Google рекомендует держать индексируемый text в DOM; декоративный CSS На интервью: SEO-friendly HTML — это прежде всего semantic, discoverable DOM с корректными links/content/metadata, а не набор магических tags. |
Какие SEO-практики важны для frontend-разработчика?
|
Короткий ответ Frontend отвечает за crawlable URLs и links, содержательный initial/rendered HTML, корректные title/metadata/canonical, indexing directives, semantic content, structured data и performance. Все это нужно проверять на уровне реального URL и rendered DOM, а не только component code. Полный ответ У frontend-разработчика SEO — это часть architecture и delivery, а не финальная установка meta description перед release. Практический checklist можно разделить по слоям. 1. URL и navigation
2. Crawling и indexing
3. Rendered content Google умеет выполнять JavaScript, но rendering имеет ограничения, а другие crawlers/social bots могут JS не исполнять. Public content лучше проектировать так, чтобы critical text, links и metadata были доступны через SSR, prerender/static rendering или другой надежный rendering strategy. 4. Metadata
5. Content semantics
6. Performance и UX Core Web Vitals — не единственный фактор SEO, но slow layout, huge JS и delayed LCP одновременно ухудшают real user experience и могут влиять на search performance. Оптимизацию нужно проверять по field/lab data, а не «потому что SEO любит SSR». 7. Structured data Добавляют только schemas, реально соответствующие видимому content, и валидируют их. Fake reviews/metadata — не shortcut. 8. Verification Проверяют Network response, rendered DOM, URL Inspection/Search Console, structured data validators и реальные pages после deploy. На интервью сильный ответ: frontend SEO — обеспечить crawler тот же надежный product contract: URL → HTTP → render → content → links → metadata, а затем измерять реальный результат. |
Как правильно использовать заголовки h1–h6?
|
Короткий ответ Heading levels описывают структуру документа, а не размер текста. Обычно удобно иметь один ясный main Полный ответ Headings решают две задачи одновременно: помогают человеку быстро scan content и дают machine-readable hierarchy. <h1>Настройки аккаунта</h1>
<h2>Безопасность</h2>
<h3>Двухфакторная аутентификация</h3>
<h2>Уведомления</h2>Это лучше, чем выбирать тег по размеру текста: <h4>Настройки аккаунта</h4>
<!-- только потому что визуально нужен 20px -->Visual style должен задаваться CSS/design system независимо от semantic level. Практический подход:
Исторический HTML outline algorithm для sectioning elements не стал browser reality, поэтому Поисковая система не обязана считать Несколько В component-based UI есть архитектурная проблема: reusable card не должен hardcode На интервью: heading hierarchy — document architecture; CSS отвечает за appearance, а component abstraction не должна ломать semantic level страницы. |
Что такое Open Graph?
|
Короткий ответ Open Graph — набор Полный ответ Open Graph Protocol позволяет странице сообщить social crawler, как представить URL при share/unfurl. Базовый пример: <meta
property="og:title"
content="Angular signals: практическое руководство"
/>
<meta
property="og:type"
content="article"
/>
<meta
property="og:url"
content="https://example.com/angular/signals"
/>
<meta
property="og:image"
content="https://example.com/assets/signals-cover.png"
/>
<meta
property="og:description"
content="Signals, computed и effect на практических примерах."
/>По Open Graph базовыми required properties являются
Open Graph и обычная SEO metadata пересекаются, но не идентичны: <title>...</title>
<meta
name="description"
content="..."
/>
<meta
property="og:title"
content="..."
/>Search engine может использовать свои signals, social network — Open Graph, messenger — собственные rules/fallbacks. Важно учитывать crawler rendering model. Многие link unfurl bots не запускают полноценное SPA приложение, поэтому OG
metadata лучше выдавать в initial HTML response. Если server отдает один generic
Open Graph не заменяет accessible На интервью: OG — внешний metadata contract для link preview; его проектируют per URL и обычно отдают server-side, потому что consumer может не исполнять application JavaScript. |
Как SSR влияет на SEO?
|
Короткий ответ SSR/prerender отдает meaningful HTML, links и metadata уже в initial response, поэтому crawler меньше зависит от JavaScript rendering. Google умеет выполнять JavaScript, но рекомендует SSR/static rendering/hydration как надежные решения; другие bots могут JS не выполнять вообще. Полный ответ CSR-only приложение может сначала вернуть: <div id="app"></div>
<script src="app.js"></script>а реальный content создать только после download/execute/API calls. Пользовательский browser обычно справляется, но для crawler появляется дополнительная dependency chain: SSR или prerender сокращает этот путь: <main>
<h1>Angular signals</h1>
<p>...</p>
<a href="/angular/effects">Effects</a>
</main>Crawler сразу видит primary text, links, title/canonical/social metadata. JavaScript затем может hydrate existing markup и добавить interactivity. Важно не превращать тезис в миф «Google не индексирует JavaScript». Google Search использует Web Rendering Service и выполняет JavaScript. Но официальная документация все равно отмечает limitations и рекомендует server-side rendering, static rendering или hydration вместо dynamic rendering как постоянного workaround. Плюсы SSR/prerender для SEO architecture:
Но SSR сам по себе не гарантирует SEO:
Нужно также сохранять content parity: server version для crawler и hydrated UI для пользователя должны представлять один и тот же meaningful content. Специальная radically different bot version может превратиться в cloaking problem. Для Angular выбор между SSR, prerender и CSR делают по product requirements: public indexable pages часто выигрывают от server/static HTML, private dashboards за auth могут вообще не нуждаться в search indexing. На интервью: SSR уменьшает зависимость indexing от client execution и улучшает reliability, но SEO определяется полным URL/HTTP/content/metadata contract, а не самим фактом server render. |
Чем JPEG, PNG, WebP, AVIF и SVG отличаются друг от друга?
|
Короткий ответ JPEG обычно выбирают для фотографий, PNG — для lossless-графики и alpha transparency, WebP/AVIF — для более эффективного raster compression, SVG — для векторной графики. Выбор зависит от типа контента, качества, размера файла, прозрачности, animation и delivery strategy. Полный ответ Главное различие — как хранится изображение и какой trade-off между качеством, размером и возможностями. JPEG
PNG
WebP
AVIF
SVG
Практический production pipeline часто использует Нельзя выбирать format только по расширению. Нужно измерять реальный byte size + visual quality + decode/render cost + cache strategy на типичных assets. На интервью: raster formats кодируют pixels, SVG — geometry; JPEG/PNG решают разные legacy/use-case задачи, WebP/AVIF обычно улучшают delivery, но формат выбирают по конкретному контенту и инфраструктуре. |
Когда использовать SVG, а когда raster image?
|
Короткий ответ SVG подходит для logos, icons, charts и простой графики, которая должна масштабироваться или стилизоваться. Raster image лучше для фотографий, сложных текстур и pixel-based content. Сложный SVG тоже может быть тяжелым, поэтому vector не означает автоматически быстрее. Полный ответ Выбор начинается с природы изображения. SVG хорош, когда изображение описывается небольшим количеством геометрических primitives:
Пример icon: <svg
viewBox="0 0 24 24"
aria-hidden="true"
>
<path d="..." />
</svg>Плюсы SVG:
Raster лучше, когда content по природе pixel-rich:
Попытка превратить фотографию в тысячи vector paths увеличит markup, memory и paint cost. И наоборот, маленький
monochrome icon в PNG потребует нескольких resolutions и хуже адаптируется к Есть промежуточные случаи. Например, сложная illustration может быть меньше как optimized WebP/AVIF, чем SVG с тысячами nodes. Поэтому performance проверяют измерением, а не правилом «SVG всегда легче». Security тоже отличается: SVG — XML document format с потенциально сложным содержимым. Untrusted SVG нельзя бездумно вставлять inline; upload pipeline должен sanitise/serve его согласно threat model. На интервью: SVG выбирают за geometry/scalability/styling, raster — за efficient representation сложного pixel content; окончательный выбор подтверждают размером и rendering cost. |
Что такое responsive images и как работают srcset/sizes?
|
Короткий ответ Responsive images позволяют браузеру выбрать подходящий image resource вместо загрузки одного большого файла всем
устройствам. Полный ответ Проблема обычного Для resolution switching используют <img
src="photo-800.jpg"
srcset="photo-480.jpg 480w, photo-800.jpg 800w, photo-1600.jpg 1600w"
sizes="(max-width: 40rem) 100vw, 50vw"
width="1600"
height="900"
alt="Команда за рабочим столом"
/>Здесь:
Важно: Для fixed-size icon/avatar можно использовать density descriptors: <img
src="avatar.png"
srcset="avatar.png 1x, avatar@2x.png 2x"
width="48"
height="48"
alt="Максим"
/>Responsive images особенно полезны для LCP/large content images. Они уменьшают network bytes без ручного JavaScript media-query loader. Нужно помнить:
На интервью: |
Что делает loading="lazy"?
|
Короткий ответ
Полный ответ Без lazy loading длинная страница может сразу инициировать десятки image requests, хотя пользователь увидит только первые несколько. <img
src="gallery-12.jpg"
loading="lazy"
width="800"
height="600"
alt="Зал музея"
/>
Что дает lazy loading:
Но есть важный anti-pattern: <img
src="hero.jpg"
loading="lazy"
alt="..."
/>если Для lazy-loaded images полезно задавать dimensions: <img
src="card.jpg"
loading="lazy"
width="640"
height="360"
alt="..."
/>Browser может вычислить aspect ratio и зарезервировать место до download, снижая CLS. Также lazy loading не исправляет oversized image: offscreen 5 MB photo останется 5 MB после начала загрузки. Его
комбинируют с На интервью: lazy loading управляет моментом fetch, responsive images — размером выбранного resource; для хорошего performance нужны оба уровня и нельзя lazy-load critical LCP image без причины. |
Что такое alt и когда он должен быть пустым?
|
Короткий ответ
Полный ответ Хороший Meaningful image: <img
src="chart.png"
alt="Продажи выросли с 12 до 18 млн рублей за второй квартал"
/>Если chart содержит complex data, одного alt может быть недостаточно: рядом нужен text/table explanation. Decorative image: <img
src="separator.svg"
alt=""
/>Пустой Если image уже дублирует соседний text: <a href="/download">
<img
src="download.svg"
alt=""
/>
Скачать отчет
</a>иконка декоративна, потому что link уже имеет понятное accessible name из текста. Если image является единственным content ссылки/кнопки, alt должен передавать функцию, а не форму: <a href="/home">
<img
src="logo.svg"
alt="Компания Example — на главную"
/>
</a>Типичные ошибки:
На интервью: alt — functional/text equivalent image в данном context; |
Для чего нужен элемент picture?
|
Короткий ответ
Полный ответ
Format selection: <picture>
<source
srcset="hero.avif"
type="image/avif"
/>
<source
srcset="hero.webp"
type="image/webp"
/>
<img
src="hero.jpg"
width="1600"
height="900"
alt="Город ночью"
/>
</picture>Browser выбирает первый подходящий source, который соответствует conditions/capabilities; Art direction: mobile может требовать не просто меньший файл, а другой crop/composition. <picture>
<source
media="(max-width: 40rem)"
srcset="portrait-crop.jpg"
/>
<img
src="wide.jpg"
alt="Спикер на сцене"
/>
</picture>Здесь images визуально различаются по composition, но должны сохранять тот же meaningful content/alt contract. Когда <img
srcset="photo-480.jpg 480w, photo-960.jpg 960w"
sizes="100vw"
src="photo-960.jpg"
alt="..."
/>Если задача только выбрать resolution одной и той же картинки, На интервью: |
Что такое SVG?
|
Короткий ответ SVG (Scalable Vector Graphics) — XML-based vector graphics format: изображение описывается shapes, paths, text, gradients и transforms. Browser масштабирует geometry в заданный viewport, поэтому SVG хорошо подходит для icons/logos/diagrams и может быть частью DOM при inline usage. Полный ответ SVG — это не просто «картинка без пикселей». Это отдельная vector graphics model. Минимальный пример: <svg
viewBox="0 0 24 24"
width="24"
height="24"
aria-hidden="true"
>
<circle
cx="12"
cy="12"
r="10"
/>
</svg>Внутри можно описывать:
SVG можно доставлять по-разному: <img
src="logo.svg"
alt="Example"
/>или inline: <svg viewBox="0 0 24 24">...</svg>Inline вариант становится частью DOM и дает больше CSS/control; external Слово Scalable не означает бесплатный rendering. SVG с тысячами paths, filters и animations может быть тяжелым по CPU/memory. Optimization удаляет editor metadata, упрощает paths и уменьшает precision, но должна сохранять semantics/visual result. На интервью: SVG хранит vector scene, а browser rasterizes ее под текущий viewport; это делает format удобным для scalable UI graphics, но complexity scene все равно влияет на performance. |
Почему SVG подходит для scalable icons?
|
Короткий ответ SVG icon описывает geometry в логической coordinate system, поэтому один asset можно отрисовать в 16px, 24px, 48px и на
high-DPR screen без отдельных bitmap resolutions. Полный ответ Bitmap icon хранит конкретную pixel grid. Если растянуть маленький PNG, browser интерполирует pixels, а для разных DPR часто нужны отдельные assets. SVG задает geometry: <svg
viewBox="0 0 24 24"
class="icon"
aria-hidden="true"
>
<path
d="..."
fill="currentColor"
/>
</svg>.icon {
inline-size: 1.5rem;
block-size: 1.5rem;
}
Это удобно для design system:
Но визуально хороший scalable icon иногда требует optical variants. Очень тонкий 24px icon, уменьшенный до 12px, может потерять читаемость. Тогда design system хранит несколько intentional glyph variants, даже если технически SVG масштабируется бесконечно. На интервью: SVG масштабируется математически благодаря geometry/viewBox, но product-quality iconography все равно учитывает stroke weight, optical size и rendering complexity. |
Как сделать SVG-иконку масштабируемой?
|
Короткий ответ Задать корректный Полный ответ Базовый scalable icon: <svg
class="icon"
viewBox="0 0 24 24"
aria-hidden="true"
>
<path
fill="currentColor"
d="..."
/>
</svg>.icon {
width: 1.5rem;
height: 1.5rem;
}Ключевая часть — Если В component API полезно отделить:
Например: .icon--s {
width: 1rem;
height: 1rem;
}
.icon--m {
width: 1.5rem;
height: 1.5rem;
}
.icon--l {
width: 2rem;
height: 2rem;
}Не стоит удалять На интервью: масштабируемость = стабильная internal coordinate system через |
Что такое viewBox в SVG?
|
Короткий ответ
Полный ответ Разберем: <svg
viewBox="0 0 24 24"
width="48"
height="48"
>
<circle
cx="12"
cy="12"
r="10"
/>
</svg>
Для Это позволяет path оставаться таким же: <path d="M4 12h16" />а размер icon менять через CSS.
<svg viewBox="-12 -12 24 24">...</svg>Это полезно для coordinate systems вокруг center. Как content вписывается во viewport, дополнительно контролирует Важно не путать На интервью: |
Чем width/height отличаются от viewBox?
|
Короткий ответ
Полный ответ Пример: <svg
viewBox="0 0 24 24"
width="48"
height="48"
>
...
</svg>Здесь:
Если поменять: svg {
width: 2rem;
height: 2rem;
}geometry не меняется; меняется только space, в который она rasterizes. Почему полезно указывать Для inline icon component часто dimensions задает CSS, а attributes можно опустить или использовать как sensible
defaults. Но Если external viewport имеет другой aspect ratio, вступает На интервью: |
Как менять цвет SVG-иконки через CSS?
|
Короткий ответ Для monochrome icon обычно используют Полный ответ Пример: <button class="action">
<svg
class="icon"
viewBox="0 0 24 24"
aria-hidden="true"
>
<path
fill="currentColor"
d="..."
/>
</svg>
Сохранить
</button>.action {
color: var(--text-action);
}
.action:hover {
color: var(--text-action-hover);
}SVG path наследует current Для stroke icon: <path
d="..."
fill="none"
stroke="currentColor"
stroke-width="2"
/>Преимущества:
Но это работает только если SVG доступен для styling. Inline SVG/symbol обычно позволяет управлять internal paint.
Multi-color illustration не нужно насильно сводить к На интервью: |
Что лучше для иконок: inline SVG, SVG sprite или img?
|
Короткий ответ Нет универсального победителя. Inline SVG проще стилизовать и делать stateful, sprite уменьшает дублирование geometry
для большого icon set, Полный ответ Inline SVG <svg
viewBox="0 0 24 24"
aria-hidden="true"
>
<path
fill="currentColor"
d="..."
/>
</svg>Плюсы:
Минусы:
SVG sprite <svg aria-hidden="true">
<use href="#icon-search" />
</svg>Плюсы:
Trade-offs:
<img
src="/icons/search.svg"
alt=""
/>Плюсы:
Минус: parent page не может обычным CSS изменить individual path fill/stroke external SVG. В современном component library часто icon component скрывает strategy от product code: <tui-icon name="search" />а pipeline решает sprite/inline/caching. Icon fonts обычно проигрывают SVG по semantics, fallback и control over geometry, хотя могут встречаться в legacy systems. На интервью: выбирают не syntax, а delivery architecture: inline — control, sprite — reuse, img — isolation/cache; design system должен унифицировать API и accessibility. |
Какие проблемы появляются при локализации frontend-приложения?
|
Короткий ответ Localization затрагивает layout, plural rules, dates/numbers/currency, sorting, fonts, line breaking, LTR/RTL, accessibility и metadata — не только перевод строк. Компоненты должны выдерживать длинные labels, другой word order и разные locale formats без hardcoded widths/concatenated phrases. Полный ответ Типичный anti-pattern — считать i18n заменой строки: button = locale === 'ru' ? 'Сохранить' : 'Save';Реальный localization contract шире. Длина текста German/Finnish/Russian translation может быть заметно длиннее English. Fixed-width button/card начинает overflow. Grammar/pluralization нельзя надежно собирать простым Date/time/number/currency
Word order Нельзя переводить fragments отдельно: Другой язык может требовать иной порядок/склонение. RTL Arabic/Hebrew требуют logical CSS properties ( Fonts Выбранный font может не содержать Cyrillic/CJK/Arabic glyphs или иметь другой metrics, меняющий layout. Accessibility/metadata Обновляются Images Не стоит вшивать текст в raster/SVG asset без localization pipeline. Text в image хуже переводится, масштабируется и читается assistive technologies. Практический workflow включает pseudo-localization: искусственно удлиняют strings и тестируют accented/RTL content до реальных переводов. На интервью: localization — изменение assumptions интерфейса о text, grammar, direction и formatting; resilient component не зависит от длины и порядка English strings. |
Как сделать SVG-иконку доступной?
|
Короткий ответ Сначала определить, несет ли icon собственный смысл. Decorative SVG скрывают через Полный ответ Decorative icon внутри подписанной кнопки: <button type="button">
<svg
viewBox="0 0 24 24"
aria-hidden="true"
>
...
</svg>
Поиск
</button>Button уже имеет accessible name «Поиск», поэтому отдельное объявление SVG только дублировало бы информацию. Icon-only button: <button
type="button"
aria-label="Закрыть"
>
<svg
viewBox="0 0 24 24"
aria-hidden="true"
>
...
</svg>
</button>Interaction owner — button, значит name принадлежит button, а не внутреннему path/SVG. Meaningful standalone SVG: <svg
role="img"
aria-labelledby="chart-title chart-desc"
viewBox="0 0 400 200"
>
<title id="chart-title">Динамика выручки</title>
<desc id="chart-desc">Рост на 24% за квартал</desc>
...
</svg>Для complex chart SVG name/description редко достаточно: рядом нужен readable data/table summary.
Нельзя ставить На интервью: accessibility SVG определяется ролью в UI: decoration скрываем, interaction name задаем control, standalone meaningful graphic получает semantic name/description. |
Какие ошибки часто делают при работе с SVG-иконками?
|
Короткий ответ Частые ошибки: удаленный/неверный Полный ответ Практический checklist. 1. Теряют После optimizer/export icon перестает нормально resize или получает unexpected crop. 2. Hardcode цвета <path fill="#000" />Theme/hover/disabled states требуют новых assets. Для monochrome icon чаще подходит 3. Оставляют editor noise Figma/Illustrator export может содержать metadata, unnecessary groups, transforms, huge coordinate precision. Optimization уменьшает bytes/DOM complexity. 4. Переоптимизируют Aggressive path simplification может визуально изменить glyph или удалить нужные ids/viewBox. Optimizer config должен тестироваться на real icon set. 5. Неверная accessibility Decorative SVG озвучивается рядом с text или icon-only button вообще не имеет name. 6. Дублируют geometry в application code Десятки teams копируют raw paths. Лучше central icon registry/component/package. 7. Огромный sprite Если single sprite содержит тысячи icons, пользователь может скачать большой unused payload. Нужно смотреть bundle/cache usage. 8. Небезопасно вставляют external SVG markup SVG — markup format. Untrusted uploaded SVG нельзя вставлять как trusted inline HTML без sanitization/threat analysis. 9. Путают visual size и hit target 16×16 icon внутри button не означает, что pointer target должен быть 16×16. Interaction sizing — задача button component. 10. Не тестируют forced colors/themes Hardcoded fills/strokes могут исчезнуть в high-contrast theme. На интервью: хорошая SVG-система — не коллекция файлов, а pipeline: optimize geometry, preserve viewBox, unify color/size, define accessibility ownership и контролировать security/cache. |
Как рассчитывается accessible name?
|
Короткий ответ Accessible name — программно вычисляемое имя объекта в accessibility tree. Browser получает его по Accessible Name and
Description Computation из связанных labels, видимого текста, Полный ответ Accessible name отвечает на вопрос «как этот объект называется для accessibility API?». Role сообщает тип объекта —
например Для обычной кнопки имя часто берется из собственного текста: <button type="button">Сохранить</button>Для form control надежный источник — связанный <label for="email">Email</label>
<input
id="email"
type="email"
/>Если подходящий visible text уже существует в другом element, можно связать его через <h2 id="dialog-title">Удалить проект?</h2>
<div
role="dialog"
aria-labelledby="dialog-title"
>
...
</div>Для icon-only control допустим literal name через <button
type="button"
aria-label="Закрыть"
>
<svg aria-hidden="true">...</svg>
</button>У изображений одним из источников name является Важный trade-off — ARIA naming может переопределить native/visible naming. Например: <button aria-label="Отправить">Сохранить</button>визуально показывает «Сохранить», но accessible name может стать «Отправить». Такой рассинхрон затрудняет работу screen
reader и speech-input users. Поэтому сначала лучше использовать visible/native label, затем
Практически computed name удобно проверять в Accessibility panel DevTools или через accessibility-oriented tests по role/name. Это надежнее, чем угадывать результат только по DOM markup. На интервью: accessible name не является одной конкретной HTML-строкой — browser вычисляет его по стандартному алгоритму из native и ARIA sources; главное понимать precedence и не расходить имя с видимым интерфейсом. |
Когда использовать aria-live?
|
Короткий ответ
Полный ответ Live region нужна, когда DOM изменился вне текущей точки focus, но пользователь assistive technology все равно должен узнать об этом изменении. Типичный вариант — стабильный status container: <p
id="save-status"
role="status"
></p>После успешной операции приложение обновляет его text: document.querySelector('#save-status').textContent = 'Данные сохранены';
Поэтому Для срочного события обычно лучше использовать подходящую semantics вроде Есть дополнительные настройки:
Практический edge case: надежнее, когда live region уже существует в DOM, а приложение обновляет ее содержимое. Создание нового element сразу с готовым текстом может вести себя неодинаково в разных browser/assistive-technology combinations, потому что observer еще не обязательно начал отслеживать region. Также live region не нужна автоматически для любого нового content. Если после submit focus переводится в error summary, screen reader уже получит новый контекст через focus. Дополнительный live announcement может продублировать сообщение. В Angular это обычно означает: держать небольшой status region стабильным в template и менять только его text/state, а
не создавать большой На интервью: |
Что такое structured data и зачем нужен JSON-LD?
|
Короткий ответ Structured data описывает entities и properties страницы в машинно-читаемом формате, обычно с vocabulary Schema.org. Google поддерживает JSON-LD, Microdata и RDFa и рекомендует JSON-LD для Search features; корректная разметка может сделать страницу eligible для rich results, но не гарантирует их показ. Полный ответ Structured data добавляет к странице явную модель фактов, которую crawler может обработать без попытки вывести все relations только из визуального HTML. Например, страница статьи может отдельно сообщить headline, дату публикации и author. JSON-LD размещают в отдельном script block: <script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Frontend interview questions",
"datePublished": "2026-08-19",
"author": {
"@type": "Organization",
"name": "Angular-RU"
}
}
</script>Плюс JSON-LD в том, что semantic graph отделен от layout markup. Компонентам не нужно размазывать Но здесь важны несколько ограничений. Schema.org и Search feature — не одно и то же Schema.org описывает vocabulary. Для конкретного Google rich result нужно дополнительно соблюдать документацию и required/recommended properties именно этого feature. Валидный произвольный Schema.org object сам по себе не обещает расширенный search result. Markup должен соответствовать странице Structured data не должна заявлять rating, author, price или другие facts, которых нет или которые противоречат видимому content. Иначе поисковая система может игнорировать markup или считать его нарушающим guidelines. Rich result не гарантирован Даже корректная разметка только делает страницу eligible. Search engine сам решает, показывать ли расширенный result для конкретного query, device и context. Crawler должен получить страницу Правильный JSON-LD бесполезен, если URL закрыт от crawling/indexing или возвращает ошибочный HTTP contract. Для public indexable routes structured data желательно отдавать уже в server/static HTML вместе с основной metadata, а не зависеть без необходимости от позднего client effect. В Angular/SSR удобно строить JSON-LD из route/domain data и следить, чтобы hydration не оставляла duplicate или конфликтующие blocks при navigation. Еще один engineering detail — serialization. Не стоит собирать JSON-LD строковой конкатенацией из CMS/user content:
нужно корректно сериализовать значения и учитывать HTML Проверка production flow обычно включает Rich Results Test для поддерживаемого feature, проверку реального URL в Search Console и мониторинг reports после deploy. Это важнее, чем просто увидеть зеленый JSON validator локально. На интервью: structured data — machine-readable semantic contract страницы; JSON-LD удобен как отдельный graph, но он должен совпадать с visible content, соответствовать правилам конкретного search feature и не является shortcut к ranking или гарантией rich results. |