Нові можливості та API html5
Нові можливості HTML5 - стандарт 2014 року, який замінив плагінозалежну розробку нативними можливостями браузера: семантична структура, вбудовані медіа, розумніші форми та JavaScript API.
Теорія
Коротко
- Семантичні елементи (
<article>,<section>,<nav>) описують зміст, а не зовнішній вигляд <video>та<audio>повністю замінили Flash; для сумісності між браузерами додавай кілька тегів<source>- Поля форм мають вбудовану валідацію через
type="email",required,pattern, без JavaScript - API (Geolocation, LocalStorage, Canvas, Web Workers) перенесли можливості з плагінів у браузер
- Canvas = малювання пікселів для ігор і графіки; SVG = векторні форми для іконок і масштабованих ілюстрацій
Швидкий приклад
<!-- До HTML5: безглузді div-и -->
<div id="header">
<div id="nav">...</div>
</div>
<!-- HTML5: структура має зміст -->
<header>
<nav>...</nav>
</header>
<main>
<article>
<h1>Огляд продукту</h1>
<section>...</section>
</article>
</main>
<footer>...</footer>
<!-- Нативне відео, Flash не потрібен -->
<video controls width="640">
<source src="movie.webm" type="video/webm">
<source src="movie.mp4" type="video/mp4">
</video>
<!-- Вбудована валідація форм -->
<input type="email" required>
<input type="date">Зчитувачі екрана та пошукові системи читають типи елементів безпосередньо. Для базової структури атрибути ARIA не потрібні.
Що насправді змінив HTML5
HTML4 описував, як виглядає контент. HTML5 описує, що він означає. Тег <nav> повідомляє зчитувачу екрана «це навігація» без жодної додаткової розмітки. Тег <article> сигналізує пошуковим системам про автономний контент. У цьому і є головна ідея: перехід від презентації до семантики.
API перенесли можливості з плагінів у JavaScript. До HTML5 потрібен був Flash для відео, Java-аплети для графіки, сторонні бібліотеки для геолокації. Тепер все це працює нативно в браузері.
Семантичні елементи
| Елемент | Призначення |
|---|---|
<header> | Заголовок сторінки або секції |
<nav> | Навігаційні посилання |
<main> | Основний контент (один на сторінку) |
<article> | Автономний контент (пост, картка товару) |
<section> | Тематичне групування всередині article |
<aside> | Пов'язаний, але другорядний контент (сайдбар) |
<footer> | Футер сторінки або секції |
<figure> / <figcaption> | Зображення або діаграма з пов'язаним підписом |
<details> / <summary> | Контент, що згортається, без JavaScript |
Використовуй їх для будь-якого структурного контенту. Вони безкоштовно покращують доступність і SEO.
JavaScript API
| API | Що робить | Коли застосовувати |
|---|---|---|
| Canvas API | Малювання на рівні пікселів через <canvas> | Ігри, редагування зображень, графіки |
| Geolocation | Отримує координати користувача від ОС | Карти, локальний пошук |
| LocalStorage / SessionStorage | Зберігання ключ-значення на клієнті (5-10 МБ) | Налаштування, офлайн-дані |
| Web Workers | Фонові потоки, що не блокують UI | Важкі обчислення, обробка даних |
| WebSocket | Постійне двостороннє з'єднання з сервером | Чат, live-дашборди |
| Service Workers | Перехоплення мережевих запитів, офлайн | PWA, стратегії кешування |
| History API | pushState / replaceState для роутингу SPA | Навігація в односторінкових застосунках |
| Fetch API | Сучасні HTTP-запити, замінив XMLHttpRequest | Всі API-запити в сучасному коді |
Canvas проти SVG
| Характеристика | Canvas | SVG |
|---|---|---|
| Тип | Растровий (пікселі) | Векторний (форми) |
| Масштабованість | Втрачає якість при збільшенні | Масштабується без втрат |
| Доступ до DOM | Немає (тільки пікселі) | Є (кожна форма - вузол DOM) |
| Обробка подій | Ручна, за координатами | Вбудована, по елементу |
| Найкраще для | Ігор, обробки зображень, графіків | Іконок, логотипів, ілюстрацій |
Поширена помилка на співбесідах: кандидати кажуть «Canvas для всього графічного». Це не так. Контент Canvas не можна виділити, знайти через пошук або зробити доступним для зчитувачів екрана. SVG підходить для всього, що потребує інтерактивності або масштабування.
Типові помилки
Помилка 1: <div> замість семантичних елементів
<!-- Неправильно: зчитувач екрана бачить звичайний блок -->
<div class="nav">
<a href="/">Головна</a>
</div>
<!-- Правильно: навігація оголошується як навігація -->
<nav>
<a href="/">Головна</a>
</nav>Приблизно 15% користувачів покладаються на допоміжні технології. <div> нічого не повідомляє зчитувачу екрана. <nav> дає змогу одразу перейти до навігації.
Помилка 2: Одне джерело для відео
<!-- Неправильно: може не відтворюватись у Firefox -->
<video controls>
<source src="video.mp4" type="video/mp4">
</video>
<!-- Правильно: браузер обирає перший підтримуваний формат -->
<video controls>
<source src="video.webm" type="video/webm">
<source src="video.mp4" type="video/mp4">
</video>Різні браузери підтримують різні кодеки. WebM менший за розміром, але не підтримується у всіх версіях Safari. MP4 працює ширше. Кілька джерел гарантують відтворення скрізь.
Помилка 3: Покладатися на HTML5-валідацію форм для безпеки
<!-- Хибне припущення: цього достатньо для захисту -->
<input type="email" required>
<!-- Будь-який користувач обходить це через DevTools:
element.removeAttribute('required')
Або надсилає запит напряму через curl. -->Валідація HTML5 - це UX-фіча. Вона покращує досвід користувача, але не захищає сервер. Завжди валідуй дані на сервері.
Помилка 4: Чутливі дані у LocalStorage
// Неправильно: будь-який скрипт на сторінці читає це
localStorage.setItem('auth_token', token);
// Правильно: для токенів використовуй HttpOnly cookies
// Сервер надсилає: Set-Cookie: auth_token=...; HttpOnly; Secure
// JavaScript взагалі не має до цього доступуXSS-атаки крадуть дані з LocalStorage. Кукі з HttpOnly недоступні для JavaScript і передаються з запитами автоматично.
Помилка 5: Важкі обчислення в основному потоці
// Неправильно: UI повністю зависає
function processImage(data) {
for (let i = 0; i < data.length; i++) {
// важка математика блокує все
}
}
// Правильно: делегувати Web Worker
const worker = new Worker('processor.js');
worker.postMessage(imageData);
worker.onmessage = (e) => ctx.putImageData(e.data, 0, 0);JavaScript виконується в одному потоці. Довгі цикли блокують усі взаємодії з користувачем. Web Workers працюють в окремих потоках ОС.
Де це зустрічається
- React:
type="email"на полях вводу,<figure>для галерей, семантичні елементи у компонентах - Next.js: семантичний HTML для SEO при серверному рендерингу, Canvas для попереднього перегляду зображень
- Figma / Excalidraw: Canvas API для малювання, Web Workers для рендерингу великих документів без зависання вкладки
- Google Maps / Mapbox: Canvas для плиток карти, Geolocation для позиції користувача
- YouTube / Vimeo:
<video>з адаптивним стрімінгом, Canvas для генерації мініатюр - PWA: LocalStorage разом із Service Workers для синхронізації даних в офлайн-режимі
Питання на співбесіді
Q: Яка різниця між LocalStorage і SessionStorage?
A: LocalStorage зберігається доки його не очистять вручну і виживає після перезапуску браузера. SessionStorage зникає коли вкладка закривається. LocalStorage підходить для налаштувань користувача, SessionStorage - для тимчасових даних на кшталт частково заповнених форм.
Q: Чи можна обійтись без семантичних елементів, якщо скрізь додавати атрибути ARIA?
A: Технічно можна, але сенсу немає. Семантичні елементи дають доступність автоматично. <nav> рівнозначний <div role="navigation">, але без зайвого коду і ризику помилок. Спочатку нативні елементи, ARIA тільки для того, чого HTML не покриває.
Q: Як браузер обирає, який <source> відтворювати у <video>?
A: Читає атрибут type і перевіряє чи може декодувати цей кодек. Бере перший підходящий. Для адаптивного стрімінгу (перемикання якості залежно від ширини каналу) прості теги <source> не підходять. Тут потрібен HLS або DASH, зазвичай через бібліотеку на зразок HLS.js.
Q: Коли не варто використовувати Web Workers?
A: Створення Worker коштує близько 50 мс. Для завдань коротших за 100 мс витрати перевищують вигоду. Спочатку проміряй задачу. Workers мають сенс для обробки зображень, парсингу великого JSON або фізичних симуляцій.
Q: Fetch API є частиною HTML5?
A: Технічно Fetch - це окремий Living Standard від WHATWG, не в оригінальній специфікації HTML5. Але це браузерний API з тієї ж епохи стандартизації, який є в кожному сучасному браузері. На співбесідах групувати його з HTML5 API цілком нормально.
Приклади
Семантична структура сторінки з валідацією форм
<header>
<nav>
<a href="/">Головна</a>
<a href="/products">Товари</a>
</nav>
</header>
<main>
<article>
<h1>Бездротові навушники</h1>
<section>
<h2>Характеристики</h2>
<p>Преміум навушники з шумозаглушенням...</p>
</section>
<section>
<h2>Відгуки</h2>
<details>
<summary>Показати 5-зіркові відгуки (12)</summary>
<p>Тут завантажується контент відгуків</p>
</details>
</section>
<aside>
<h3>Схожі товари</h3>
</aside>
</article>
<form>
<input type="email" placeholder="Email" required>
<input type="number" min="1" max="10" value="1">
<input type="date" required>
<button type="submit">Замовити</button>
<!-- Браузер блокує відправку якщо поля не пройшли валідацію -->
</form>
</main>
<footer>
<p>© 2025 Магазин</p>
</footer>Комбо <details> і <summary> дає секцію, що згортається, без жодного рядка JavaScript. Форма відправляється лише після того, як браузер перевірить формат type="email" і заповненість обов'язкових полів.
Canvas з Web Workers для обробки зображень
// main.js - виконується у вкладці браузера
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const worker = new Worker('grayscale.js');
worker.postMessage(imageData);
worker.onmessage = (event) => {
ctx.putImageData(event.data, 0, 0);
// Canvas оновився, користувач весь цей час міг натискати кнопки
};
// grayscale.js - виконується в окремому потоці
self.onmessage = (event) => {
const imageData = event.data;
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const gray = data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114;
data[i] = data[i + 1] = data[i + 2] = gray; // R, G, B отримують значення сірого
}
self.postMessage(imageData);
};Worker виконується в окремому потоці ОС. Event loop основної вкладки залишається вільним. Без Worker цикл по зображенню 4K заморозив би UI на кілька сотень мілісекунд.
LocalStorage з терміном дії
// Простий підхід: токен ніколи не прострочується
localStorage.setItem('user_token', token);
// Краще: обгортаємо з метаданими часу
function setWithExpiry(key, value, ttlMs) {
const item = {
value: value,
expiry: Date.now() + ttlMs
};
localStorage.setItem(key, JSON.stringify(item));
}
function getWithExpiry(key) {
const raw = localStorage.getItem(key);
if (!raw) return null;
const item = JSON.parse(raw);
if (Date.now() > item.expiry) {
localStorage.removeItem(key);
return null; // прострочений, повертаємо null
}
return item.value;
}
// Токен живе одну годину
setWithExpiry('user_token', token, 60 * 60 * 1000);У LocalStorage немає вбудованого механізму прострочення. Цей патерн обгортає значення в об'єкт з часовою міткою. Геттер сам займається видаленням. Але для справжніх токенів автентифікації обирай HttpOnly cookies.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.