Почему не работает position: sticky в CSS: причины и решения проблем
-
Position: sticky - это удобный способ сделать элемент прилипающим при прокрутке. Но часто он не работает, и страница выглядит не так, как задумано. В этой статье разберём основные причины и покажем, как их исправить.
Понимание механизма поможет быстро диагностировать проблему. Вы узнаете о ключевых условиях, overflow, flex и других нюансах. Это сэкономит часы отладки в DevTools.
Основные условия для работы position: sticky
Position: sticky превращает элемент в relative, а потом в fixed относительно контейнера при достижении порога. Без top, bottom, left или right ничего не сработает - это обязательный инсет-триггер. Представьте боковую панель: она должна прилипнуть к верху экрана, но остаётся на месте.
Проверьте в DevTools раздел Computed - position должен быть sticky. Если нет, добавьте top: 0. Ещё один момент: z-index создаёт stacking context, чтобы элемент перекрывал контент. Без него может прятаться за другими блоками. Логично перейти к чек-листу.
- Обязательные свойства: Укажите top: 0 или bottom: 0 - без этого sticky не активируется.
- Контейнер: Родитель должен иметь прокрутку и высоту больше sticky-элемента.
- Диагностика: Добавьте outline: 1px solid red - увидите границы привязки.
- Z-index: Задайте значение вроде 10, чтобы элемент был поверх.
Проблема Проверка Решение Нет top/bottom Computed в DevTools Добавьте top: 0 Маленький контейнер Bounding rect в консоли Увеличьте height Неправильный z-index Layers панель z-index: 10 Проблемы с overflow в родительских контейнерах
Overflow: hidden, scroll или auto на родителе ломает sticky - создаёт отдельный scroll-context. Элемент не может выйти за пределы и отлипает раньше времени. В реальном проекте это часто бывает с обёртками секций или модальными окнами.
Решение простое: замените на overflow: clip или вынесите sticky за пределы проблемного контейнера. В flex-контейнерах overflow hidden особенно коварен. Проверьте все родители сниппетом в JS - он покажет цепочку overflow.
- Overflow: hidden - убивает sticky полностью, используйте clip.
- В flex/grid - добавьте align-self: flex-start.
- Вынос элемента - переместите sticky выше в DOM.
Overflow Влияние на sticky Фикс hidden Полный отказ clip или вынос scroll/auto Ограничение движения Удалить или flex-start visible Работает Оставить Нюансы с flex, grid и высотой контейнера
В Flexbox sticky растягивается на align-self: stretch и не имеет запаса для движения. Нужно flex-start, чтобы элемент мог скроллиться. То же в Grid - дробите оси выравнивания. Если sticky выше контейнера, он не прилипнет.
Пример: сайдбар в flex-контейнере. Без align-self: flex-start он занимает всю высоту и стоит на месте. Для bottom: 0 элемент должен быть длиннее видимой области - иначе прилипнет сразу и не сдвинется.
- Align-self: Установите flex-start вместо stretch.
- Высота: Контейнер > sticky, иначе нет скролла.
- Bottom: 0 - используйте с align-self: flex-end для прилипания снизу.
Layout Проблема Решение Flex Stretch растягивает align-self: flex-start Grid Ось выравнивания Дробление осей Обычный div Нет height Задайте height: 100vh Дополнительные ловушки: Safari, z-index и браузеры
В старых Safari нужен префикс -webkit-sticky. Проверьте на caniuse - поддержка хорошая, но нюансы есть. Z-index конфликтует, если stacking context разный. Родительский элемент с position может сбить контекст.
Ещё: padding или margin в контейнере создают подушку, и sticky отлипает раньше. Тестируйте в реальном скролле - не в маленьком окне. Safari ниже 13 требует префикса в паре со sticky.
- Префикс Safari: position: -webkit-sticky; position: sticky;
- Stacking context: Проверьте z-index родителей.
- Браузеры: Тест в Chrome, Firefox, Safari.
Браузер Требование Примечание Safari <13 -webkit-sticky Обязательно Chrome/FF top: 0 Стандартно Все Высота контейнера Критично Шпаргалка по быстрой отладке sticky
Большинство багов в тройке: top, overflow, height - 90% случаев. Добавьте outline и смотрите прямоугольник. Если sticky больше контейнера - урежьте. В bottom: 0 нужен запас высоты.
Тестируйте с реальным контентом - пустой контейнер не покажет проблем. Помните: sticky привязан к ближайшему scrolling ancestor, не к viewport.
© 2024 - 2026 ExLends, Inc. Все права защищены.