Прикрепляемый (sticky) заголовок в React

Что такое прикрепляемый заголовок
Прикрепляемый заголовок (sticky header) — это элемент интерфейса, который остаётся привязанным к верхней части окна при прокрутке страницы. Он сохраняет важную навигацию или информацию постоянно доступной для пользователя.
Важно: прикрепляемый заголовок уменьшает видимую область контента. Держите его компактным и информативным.
Базовая реализация: нативный React-подход
Ниже простой функциональный компонент, который отслеживает прокрутку и переключает состояние isSticky. Код использует хуки и чистые inline-стили, но вы легко переведёте стили в CSS или Tailwind.
import React, { useState, useEffect } from 'react'
function StickyHeader() {
const [isSticky, setSticky] = useState(false)
const handleScroll = () => {
const windowScrollTop = window.scrollY
if (windowScrollTop > 10) {
setSticky(true)
} else {
setSticky(false)
}
}
useEffect(() => {
window.addEventListener('scroll', handleScroll)
return () => {
window.removeEventListener('scroll', handleScroll)
}
}, [])
const items = [
{ name: 'Home', link: '/' },
{ name: 'About', link: '/about' },
{ name: 'Contact', link: '/contact' }
]
const data = Array.from({ length: 36 }, (_, i) => i + 1)
return (
{items.map(item => (
{item.name}
))}
{data.map(x => (
- {x}
))}
)
}
export default StickyHeaderПримечание: обратите внимание на отступ сверху у основного контента (paddingTop), чтобы фиксированный заголовок не перекрывал его.
CSS-класс для фиксированного положения
Если вы предпочитаете не использовать inline-стили, достаточно классически определить позицию в CSS:
.sticky {
position: fixed;
top: 0;
width: 100%;
z-index: 999;
}Результат этой реализации: заголовок фиксируется в верхней части экрана и остаётся видимым при прокрутке.
.jpg?q=50&fit=crop&w=825&dpr=1.5)
Дополнительные возможности: кнопка «вверх» и прозрачность
Ниже пример с кнопкой “Back to top”; она появляется, когда пользователь прокрутил страницу вниз.
import React, { useState, useEffect } from 'react'
function StickyHeaderWithBackToTop() {
const [isSticky, setSticky] = useState(false)
const [showBackToTop, setShowBackToTop] = useState(false)
const handleScroll = () => {
const windowScrollTop = window.scrollY
if (windowScrollTop > 10) {
setSticky(true)
setShowBackToTop(true)
} else {
setSticky(false)
setShowBackToTop(false)
}
}
const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: 'smooth' })
}
useEffect(() => {
window.addEventListener('scroll', handleScroll)
return () => {
window.removeEventListener('scroll', handleScroll)
}
}, [])
const items = [
{ name: 'Home', link: '/' },
{ name: 'About', link: '/about' },
{ name: 'Contact', link: '/contact' }
]
const data = Array.from({ length: 36 }, (_, i) => i + 1)
return (
)
}
export default StickyHeaderWithBackToTopСовет: для лучшего UX сделайте заголовок полупрозрачным или компактным при прокрутке вниз и расширяющимся при прокрутке вверх.
Альтернативные методы: библиотеки
Если не хочется писать логику вручную, можно использовать проверенные библиотеки.
react-sticky
Установка:
npm install react-stickyПример использования:
import React from 'react'
import { StickyContainer, Sticky } from 'react-sticky'
function App() {
const data = Array.from({ length: 36 }, (_, i) => i + 1)
return (
{({ style }) => (
This is a sticky header
)}
{data.map(x => (
- {x}
))}
)
}
export default Appreact-stickynode
Установка:
npm install react-stickynodeПример использования:
import React from 'react'
import Sticky from 'react-stickynode'
function App() {
const data = Array.from({ length: 36 }, (_, i) => i + 1)
return (
This is a sticky header
{data.map(x => (
- {x}
))}
)
}
export default AppСовет по выбору библиотеки: смотрите на размер пакета, поддержку серверного рендеринга и активность репозитория.
Когда прикрепляемый заголовок может не подойти (контрпримеры)
- Малый экран и плотный контент: если заголовок большим образом сокращает видимую область, лучше отказаться или сделать автоматически скрывающимся.
- Сложные макеты с динамической высотой хедера: фиксация может приводить к наложениям и сдвигам layout.
- Доступность: если навигация чрезмерно навязчива, пользователям с клавиатурой будет неудобно ориентироваться.
Альтернативные подходы
- Плавающая кнопка навигации или меню hamburger вместо полного хедера.
- Показ заголовка только при прокрутке вверх; при прокрутке вниз он скрывается.
- «Anchor» навигация внутри страницы вместо постоянного хедера.
Ментальные модели и эвристики
- Trade-off: постоянная доступность навигации vs. потеря пространства для контента.
- Heuristic: если заголовок занимает более 12% высоты экрана на мобильных устройствах, подумайте о сокращении содержания.
Мини-методология для команды (шаги внедрения)
- Определить цель: навигация, поиск, действия пользователя.
- Спроектировать макет: высота, внутренняя структура, вариант скрытия.
- Реализовать прототип: нативно или через библиотеку.
- Протестировать на десктопе и мобильных устройствах; проверить на доступность.
- Измерить влияние: удовлетворённость пользователей и метрики вовлечения.
- Итерации: оптимизировать высоту, переходы и визуальное поведение.
Чеклисты по ролям
- Дизайнер:
- Согласовать высоту и приоритеты элементов в хедере
- Предусмотреть состояние при прокрутке и нажатие кнопок
- Frontend-разработчик:
- Обработать layout shift: добавить отступ для основного контента
- Проверить z-index и перекрытия
- Сделать анимации плавными и экономными по ресурсам
- QA:
- Проверить на разных разрешениях и при включённом масштабировании
- Тестировать клавиатурную навигацию и скринридеры
- Product:
- Оценить, стоит ли сохранять все элементы в хедере
Критерии приёмки
- Заголовок корректно фиксируется при прокрутке на всех целевых разрешениях
- Контент не перекрывается заголовком; есть отступ или placeholder
- Нет значимых layout shift при загрузке и при фиксации
- Навигация доступна с клавиатуры; aria-атрибуты присутствуют
- Кнопка “вверх” появляется и скроллит плавно
Чаевый лист: быстрые подсказки
- Всегда проверяйте z-index; конфликтующие значения чаще всего ломают фиксацию.
- Используйте transform: translateZ(0) аккуратно для аппаратного ускорения, но замеряйте производительность.
- Для плавности анимаций применяйте transition на высоте, прозрачности или transform.
- Для server-side rendering убедитесь, что поведение не зависит от window без проверки существования.
Производительность и доступность
- Уменьшайте частоту вычислений в обработчике scroll: используйте throttle или passive listeners.
- Для крупных приложений лучше детектировать только изменение позиции, а не вызывать setState на каждую мелкую прокрутку.
- Добавьте aria-label и logical tab order; снабдите хедер skip-link для быстрого перехода к контенту.
Миграция и совместимость
- Проверяйте, поддерживается ли библиотека для вашей версии React и вашего сборщика.
- Если вы используете SSR (Next.js, Gatsby), убедитесь, что библиотека корректно рендерит на сервере или отложите инициализацию до монтирования на клиенте.
Краткое резюме
Прикрепляемый заголовок повышает удобство навигации, но требует внимания к месту на экране, доступности и производительности. Для простых случаев достаточно нативной реализации на хуках; для продвинутых — библиотеки типа react-sticky или react-stickynode.
Важно: протестируйте решение на мобильных устройствах и в сценариях с клавиатурной навигацией.
Похожие материалы
Технологические новости: Facebook, Apple, Microsoft и другое
Нативное разрешение экрана на Mac — как узнать
Как отключить людей от Wi‑Fi и защитить роутер
Как объединить устройства HomeKit в комнаты, зоны и сцены
Меню «Дополнительные параметры» в Windows 11 — как использовать