Есть одна давняя и нерешённая проблема: неверная иерархия заголовков. А именно пропущенные уровни заголовков, когда за
<h1> следует <h3>. Ухудшается структура страницы и навигация с помощью вспомогательных технологий.С компонентным подходом может быть трудно учесть контекст. Страница с
<h1> рисует компонент «популярные товары» с заголовком <h2>, а он рисует компонент «список товаров» с карточками, у каждой из которых заголовок <h3>.// Код для иллюстрации
function HomePage() {
return `
<main>
<h1>Магазин</h1>
${BestSellers()}
</main>
`;
}
function BestSellers() {
return `
<section>
<h2>Популярные товары</h2>
${ProductList()}
</section>
`;
}
function ProductList() {
return `
<ul>
${products.map(product => `
<li>
<article>
<h3>${product.title}</h3>
</article>
</li>
`).join('')}
</ul>
`;
}
document.body.innerHTML += HomePage();
В таком сценарии структура будет верной:
Магазин
└── Популярные товары
├── Товар 1
├── Товар 2
└── ...
Если использовать тот же компонент «список товаров» на странице каталога, где в
<h1> обычно название категории, а дальше идёт сетка с карточками товаров, то получится пропуск заголовка <h2>. Карточки не учитывают контекст.function CollectionPage() {
return `
<main>
<h1>Холодильники</h1>
${ProductList()}
</main>
`;
}
function ProductList() {
// как в предыдущем примере
}
document.body.innerHTML += CollectionPage();Проблему пытаются решить уже давно. На канале есть пост про структуру заголовков и outline, где попытки подробно описаны. Если кратко, то много лет пытались, не смогли, удалили алгоритм из стандарта и отказались от реализации.
Тут на днях Джейк Арчибальд рассказал, что в Firefox экспериментируют с решением проблемы пропуска уровней заголовков. То есть вновь предпринимается попытка решить проблему. И решение планируют стандартизировать.
Дисклеймер: это обзор раннего предложения новых функций. Синтаксис может измениться в будущем или от функций могут отказаться
Предлагается новый глобальный атрибут
headingoffset. Он задаёт смещение уровня для всех вложенных заголовков. С этим вновь предлагается использовать для заголовков только <h1> и его уровень будет вычисляться на основе смещения.<main>
<h1>Магазин</h1>
<!--
задано смещение
уровня заголовков
-->
<section headingoffset="1">
<!-- тут будет уровень 2 -->
<h1>Популярные товары</h1>
<!--
задано смещение
уровня заголовков
-->
<ul headingoffset="1">
<li>
<article>
<!-- тут будет уровень 3 -->
<h1>Товар 1</h1>
</article>
</li>
<li>
<article>
<!-- тут будет уровень 3 -->
<h1>Товар 1</h1>
</article>
</li>
...
</ul>
</section>
</main>
В комментариях подтвердили, что это также работает с элементами
<h2>-<h6>. Если задано смещение, то уровень заголовка меняется на совокупное смещение. При смещении в 1 уровень <h2> становится <h3> и так далее.Может возникнуть вопрос: а что будет с
<h6>? На это также дали ответ: он станет <h7> и так вплоть до 9 уровня максимум. В HTML нет <h7>, но с помощью атрибута aria-level="7" заголовку можно задать более глубокий уровень.Заголовки иногда стилизуют по селектору элемента, который привязывает стили к уровню в названии элемента. Как тогда стилизовать заголовки по уровнями, если все они
<h1>? Об этом тоже подумали и добавили селектор :heading()::heading(2) {
/*
Выберет все заголовки у которых
вычисленный уровень 2
*/
}Реализация появится в Firefox Nightly 153 за флагом экспериментальных технологий. С одной стороны крутая функция, с другой это возврат к использованию
<h1> для всех заголовков, что сломает текущие инструменты анализа дерева заголовков.#html #a11y