Семантическая разметка описывает смысл и назначение элементов интерфейса, а не их внешний вид. В контексте JSX это означает осознанный выбор HTML-тегов, которые корректно передают структуру документа, и сохранение этой структуры при компонентном подходе. Preact не изменяет правила HTML-семантики: JSX компилируется в обычные DOM-узлы, поэтому все принципы нативной разметки остаются актуальными.
Корректная семантика влияет на:
JSX позволяет использовать стандартные HTML-теги без ограничений. Семантические элементы применяются так же, как в обычной разметке:
const Layout = () => (
<div>
<header>
<h1>Заголовок страницы</h1>
</header>
<main>
<article>
<section>
<h2>Раздел</h2>
<p>Основной контент</p>
</section>
</article>
</main>
<footer>
<small>© 2025</small>
</footer>
</div>
);
Ключевые элементы семантической структуры:
<header> — вводная часть страницы или
раздела;<nav> — навигационные блоки;<main> — основной уникальный контент
документа;<section> — логически объединённый фрагмент;<article> — самостоятельная единица
контента;<aside> — побочный, вспомогательный контент;<footer> — завершающая информация.Использование <div> оправдано только при
отсутствии подходящего семантического тега.
Компонентный подход не отменяет требований к структуре HTML. Каждый компонент должен сохранять смысловую роль.
Пример семантически корректного компонента списка:
const Menu = () => (
<nav>
<ul>
<li><a href="/">Главная</a></li>
<li><a href="/blog">Блог</a></li>
<li><a href="/about">О проекте</a></li>
</ul>
</nav>
);
Нарушение семантики часто возникает при оборачивании всего в универсальные контейнеры:
// плохая практика
const Menu = () => (
<div>
<div>Главная</div>
<div>Блог</div>
</div>
);
JSX не навязывает структуру, поэтому ответственность за семантику лежит на архитектуре компонентов.
Preact поддерживает Fragment, позволяющий избежать
лишних DOM-узлов без потери семантики:
import { Fragment } from 'preact';
const Article = () => (
<article>
<>
<h2>Заголовок</h2>
<p>Текст статьи</p>
</>
</article>
);
Использование Fragment предпочтительнее, чем добавление
<div>, когда контейнер не несёт смысловой
нагрузки.
Иерархия <h1>–<h6> формирует
логическую структуру документа. JSX не проверяет корректность уровней,
поэтому важно соблюдать последовательность:
<main>
<h1>Документация</h1>
<section>
<h2>Установка</h2>
<h3>Через npm</h3>
</section>
</main>
Пропуски уровней (h1 → h4) затрудняют
навигацию для скринридеров, даже если визуально всё выглядит
корректно.
Семантика форм особенно критична для доступности. JSX требует явного
связывания <label> и <input>:
const LoginForm = () => (
<form>
<label htmlFor="email">Email</label>
<input id="email" type="email" />
<button type="submit">Войти</button>
</form>
);
В JSX используется htmlFor вместо for, так
как for является зарезервированным словом JavaScript.
Кнопки должны оставаться <button>, а не
<div> с обработчиком клика. Это обеспечивает:
Списки применяются для перечислений, навигации и групп данных:
<ul>
<li>Элемент</li>
<li>Элемент</li>
</ul>
Таблицы используются только для табличных данных, а не для верстки:
<table>
<thead>
<tr>
<th>Имя</th>
<th>Возраст</th>
</tr>
</thead>
<tbody>
<tr>
<td>Анна</td>
<td>28</td>
</tr>
</tbody>
</table>
Использование <div> вместо
<table> лишает данные смысловой структуры и ухудшает
восприятие вспомогательными технологиями.
ARIA применяется только при отсутствии нативного семантического элемента. JSX позволяет задавать ARIA-атрибуты напрямую:
<div role="dialog" aria-labelledby="title">
<h2 id="title">Окно</h2>
</div>
При наличии семантического аналога предпочтение отдаётся HTML-тегу:
<dialog open>
<h2>Окно</h2>
</dialog>
Избыточное использование ARIA ухудшает доступность, а не улучшает её.
При условном выводе важно сохранять структуру документа:
{isAuthorized && (
<nav>
<a href="/profile">Профиль</a>
</nav>
)}
Удаление или замена семантических блоков не должна приводить к появлению «пустых» контейнеров или нарушению иерархии заголовков.
Preact оптимизирован для минимального DOM-дерева. Семантическая разметка способствует этому, так как:
Правильный выбор тегов снижает потребность в дополнительных атрибутах и обработчиках.
Распространённые нарушения семантики в JSX:
<div> и <span>
вместо <button>, <a>,
<section>;<main> на странице;<h1> без необходимости;JSX не предотвращает эти ошибки, поэтому контроль семантики является частью ответственности при разработке компонентов.
В Preact семантика закладывается на уровне проектирования компонентов. Компонент должен описывать не только поведение и внешний вид, но и смысловую роль в документе. Такой подход упрощает повторное использование, улучшает доступность и делает код ближе к стандартам веб-платформы.