Нативный CSS position: sticky

Свойство position: sticky объединяет поведение relative и fixed. Элемент с sticky остаётся в потоке документа, пока не достигает заданной позиции относительно своего ближайшего контейнера с прокруткой. После достижения этой позиции элемент «прилипает» к указанному краю контейнера до конца видимой области.

Ключевые моменты:

  • Элемент остаётся в потоке документа. В отличие от fixed, sticky не выводит элемент из потока, поэтому соседние блоки учитывают его размеры.
  • Контейнер ограничивает область прилипания. Элемент «прилипает» только внутри родительского блока, у которого нет overflow: visible.
  • Триггером является направление и offset. Для срабатывания требуется top, bottom, left или right. Например, top: 0 фиксирует элемент к верхней границе контейнера при прокрутке вниз.

Пример CSS:

.sticky-element {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: white;
}

Ограничения нативного sticky

  1. Неподдержка в старых браузерах. Хотя большинство современных браузеров поддерживают sticky, старые версии IE и Edge не обрабатывают его.
  2. Родитель с overflow. Если родительский блок имеет overflow: hidden или overflow: auto, элемент «прилипает» только внутри этого блока.
  3. Элемент должен иметь определённый offset. Без top, bottom, left или right эффект не сработает.
  4. Не работает с display: table-row и некоторыми таблицами. Sticky не поддерживается для отдельных строк таблицы (tr) и ячеек (td) в большинстве браузеров.

Введение Stickybits

Stickybits — это лёгкая библиотека для полифила и управления «прилипшими» элементами на основе нативного position: sticky. Она автоматически решает большинство ограничений нативного sticky и обеспечивает плавное поведение даже в старых браузерах.

Ключевые особенности Stickybits:

  • Автоматический fallback. В браузерах без поддержки sticky библиотека переключает элемент на position: fixed.
  • Гибкая настройка offsets. Можно управлять верхним или нижним прилипающим отступом через опции.
  • События и коллбеки. Позволяет отслеживать момент прилипания (stick) и отпускания (unstick).
  • Минимальный вес. Библиотека около 2 КБ, не нагружает страницу.

Установка и базовое использование

Подключение через npm:

npm install stickybits

Или через CDN:

<script src="https://unpkg.com/stickybits@3/dist/stickybits.min.js"></script>

Инициализация:

stickybits('.sticky-element');

Опции по умолчанию:

{
  stickyBitStickyClass: 'is-sticky',  // Класс, добавляемый при прилипания
  stickyBitParentClass: 'is-sticky-parent', // Класс для родителя
  useStickyClasses: true,  // Добавлять CSS-классы
  scrollEl: window,  // Элемент, на котором отслеживается прокрутка
  verticalPosition: 'top', // Направление прилипания
}

Продвинутая настройка

Offset и вертикальная позиция

Можно задать собственный отступ прилипания:

stickybits('.sticky-element', { 
  verticalPosition: 'top', 
  offset: 20
});

Элемент будет «прилипать» 20px ниже верхней границы контейнера.

Sticky в контейнерах с прокруткой

По умолчанию Stickybits отслеживает window.scroll. Для элемента с внутренней прокруткой:

const container = document.querySelector('.scroll-container');
stickybits('.sticky-element', { scrollEl: container });

Теперь прилипающий элемент будет учитывать прокрутку именно этого блока.

Управление классами

Stickybits автоматически добавляет классы:

  • .is-sticky — элемент прилип
  • .is-stuck — элемент достиг конца родителя
  • .is-unstuck — элемент отпущен

Можно использовать эти классы для анимаций и CSS-трансформаций:

.is-sticky {
  transition: all 0.3s ease;
  box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}

События и API

Stickybits предоставляет методы для динамического контроля:

  • stickybits.update() — пересчитать позиции элементов после изменения DOM
  • stickybits.cleanup() — удалить все эффекты прилипания и классы
  • stickybits.destroy() — полностью удалить библиотеку со страницы

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

const sticky = stickybits('.sticky-element', {
  useStickyClasses: true
});

document.querySelector('.sticky-element').addEventListener('stickybit:stick', () => {
  console.log('Элемент прилип');
});

document.querySelector('.sticky-element').addEventListener('stickybit:unstick', () => {
  console.log('Элемент отпущен');
});

Практические сценарии применения

  1. Фиксированные заголовки таблиц и списков. Stickybits позволяет закреплять шапку таблицы при скролле, избегая проблем с position: sticky в старых браузерах.
  2. Плавающие боковые панели. Боковые меню или навигационные панели остаются на экране даже при длинной прокрутке, с возможностью ограничения их границ родителя.
  3. Анимации и переходы при прилипаниях. Благодаря классам is-sticky и is-stuck легко реализуются визуальные эффекты, например изменение цвета фона или появление тени.
  4. Многоэлементные sticky-области. Можно одновременно закреплять несколько элементов с разными offset и вертикальной позицией.

Сравнение с нативным sticky

Характеристика position: sticky Stickybits
Поддержка старых браузеров нет да, через fallback на fixed
Классы при прилипаниях нет есть (is-sticky, is-stuck)
Offset кастомизация только через CSS через JS и CSS
Контейнеры с прокруткой поддерживается частично полностью настраивается
API и динамическое управление нет update, cleanup, destroy

Советы по оптимизации

  • Минимизировать количество прилипающих элементов на странице, чтобы не нагружать рендер.
  • Устанавливать z-index только при необходимости, иначе может нарушиться наложение элементов.
  • Проверять overflow у родителей — Stickybits корректно обрабатывает только контейнеры с overflow: visible, auto или scroll.
  • Использовать update() после динамического изменения DOM, чтобы корректно пересчитать позиции элементов.

Stickybits расширяет возможности нативного position: sticky, обеспечивая кроссбраузерность, управление offset, классы для CSS и события для JS, позволяя строить сложные интерфейсы с «прилипшими» элементами без ограничений стандартного CSS.