Как быстро решить проблему скрытия якорных ссылок из-за липкой навигации с помощью нескольких строк инлайн‑CSS

Когда в документе (блог/вики/руководство) вы нажимаете ссылку с якорем или пунктом TOC, браузер перемещает элемент с #some-id к верхней части окна просмотра. Если вверху закреплена панель навигации position: sticky (или fixed), то элемент оказывается под ней.

Это обычная фронтенд‑проблема, но для бекенд/полноценных разработчиков она может выглядеть странно: «ссылка работает, но контент скрыт».

В этой статье я покажу самый простой способ – добавить несколько строк инлайн‑CSS на страницу, который сразу решит проблему.


Почему это происходит?

Браузер делает следующее:

  • URL меняется на .../page#target
  • Находит элемент id="target'
  • Скроллит так, чтобы начало элемента совпало с верхней частью контейнера прокрутки (обычно viewport).

Но липкая навигация рендерится поверх, поэтому элемент оказывается скрыт.

Схема скрытия якоря липкой навигацией


Самый простой способ: scroll-margin-top (отступ для элемента)

Если добавить scroll-margin-top к элементу, браузер будет пытаться разместить его чуть ниже, чем верхняя часть окна.

Минимальный инлайн‑CSS (рекомендовано)

В <head> или шаблоне страницы достаточно добавить:

<style>
  :root { --sticky-nav-h: 64px; } /* высота навигации */
  [id] { scroll-margin-top: calc(var(--sticky-nav-h) + 12px); }
</style>
  • --sticky-nav-h – высота липкой навигации.
  • + 12px – небольшая свобода, чтобы элемент не прилипал к ней.

Применяя к [id] глобально, вы автоматически исправляете все якорные переходы на странице. Если это слишком обширно, ограничьте область.

Ограничение области для большей безопасности

Например, только в области статьи:

<style>
  :root { --sticky-nav-h: 64px; }
  .article [id] { scroll-margin-top: calc(var(--sticky-nav-h) + 12px); }
</style>

Или только к заголовкам, которые обычно используются в TOC:

<style>
  :root { --sticky-nav-h: 64px; }
  .article h2[id], .article h3[id] {
    scroll-margin-top: calc(var(--sticky-nav-h) + 12px);
  }
</style>

Дополнительный вариант: scroll-padding-top (паддинг контейнера)

scroll-padding-top задаёт «безопасную» область для контейнера прокрутки. В большинстве случаев scroll-margin-top проще, но иногда комбинация повышает надёжность.

<style>
  :root { --sticky-nav-h: 64px; }
  html { scroll-padding-top: calc(var(--sticky-nav-h) + 12px); }
</style>
  • Полезно, если нужно быстро поправить все якорные переходы на уровне страницы.
  • Для точного контроля лучше использовать scroll-margin-top.

Классический трюк для совместимости: ::before с фальшивым отступом

Старая техника: добавляем невидимый блок перед целевым элементом.

<style>
  :root { --sticky-nav-h: 64px; }

  .anchor-target::before {
    content: "";
    display: block;
    height: calc(var(--sticky-nav-h) + 12px);
    margin-top: calc(-1 * (var(--sticky-nav-h) + 12px));
    visibility: hidden;
    pointer-events: none;
  }
</style>

Пример использования:

<h2 id="install" class="anchor-target">Установка</h2>
  • Плюс: работает даже в старых браузерах.
  • Минус: нужно добавлять класс и чуть больше кода.

Современный подход – сначала попробовать scroll-margin-top, а при необходимости – применить ::before.


JavaScript‑вариант: почему инлайн‑CSS лучше

Можно вызвать scrollIntoView() и затем сместить окно: window.scrollBy(0, -navHeight). Но CSS‑решение предпочтительнее:

  • Статические страницы с большим количеством ссылок.
  • Быстрое исправление без изменения роутера.
  • Когда поддержка не требует глубоких знаний JavaScript.

Инлайн‑<style> без зависимостей легко отлаживать и откатывать.


Практический чек‑лист

  • Точно измерьте высоту липкой навигации.
  • Если высота меняется по брейкпоинтам, меняйте только --sticky-nav-h.
  • Не применяйте [id] глобально, если структура страницы сложная – ограничьте область.
  • Добавьте небольшую «пустоту» (+8–16 px) для лучшего восприятия.

Итог: мой любимый один‑шаговый способ

Добавьте на страницу:

<style>
  :root { --sticky-nav-h: 64px; }
  .article [id] { scroll-margin-top: calc(var(--sticky-nav-h) + 12px); }
</style>

Это обычно решает TOC, сноски и глубокие ссылки. Надеюсь, статья поможет разработчикам, которые сталкиваются с проблемой скрытия ссылок под липкой навигацией.


Похожие статьи - Почему важно указывать width и height в теге img - Минимум, который должен знать бекенд‑инженер: лучшие 5 методов и модулей JS