position: sticky - гибрид relative и fixed: элемент ведёт себя как обычный, пока страница (или контейнер) не прокрутится до заданного порога, а затем "прилипает" к краю и остаётся на месте, пока не закончится место внутри родителя. Без явного top/right/bottom/left sticky не отличить от обычного relative.
В этом уроке
Попробуй прямо сейчас: прокрути список внутри блокнота - заголовок "приклеится" к верхней границе именно этого прокручиваемого блока, а не ко всему экрану.
Гибрид relative и fixed: как работает порог прилипания
sticky-элемент ведёт себя как обычный position: relative, оставаясь в потоке документа, пока не будет достигнут заданный порог прокрутки - например, top: 10px означает "веди себя как relative, пока до верхней границы контейнера прокрутки не останется 10px". После этого элемент "прилипает" - визуально ведёт себя как fixed, но только внутри границ своего родителя, а как только родитель заканчивается (прокрутка дошла до его нижнего края), sticky-элемент снова уходит в обычный поток вместе с родителем.
position: sticky; top: 0; - классический "липкий" заголовок списка или таблицы, который останавливается у верхнего края при прокрутке.
position: sticky; без top/left и подобных, ожидая прилипание "по умолчанию" - без заданного порога sticky ничем не отличается от обычного relative.
Без offset sticky не работает вообще
Ключевое правило: sticky ОБЯЗАТЕЛЬНО нужен хотя бы один из top, right, bottom или left, задающий сам порог прилипания. Без него браузеру не от чего отталкиваться, и элемент просто останется обычным relative - визуально прилипания не будет вообще, даже если написать position: sticky.
position: sticky; bottom: 0; - элемент прилипнет к нижнему краю контейнера при прокрутке вниз.
position: sticky; без единого offset - самая частая причина, по которой "sticky не работает": свойство написано верно, но порог не задан вовсе.
Прокручиваемый предок и почему sticky "ломается"
sticky прилипает не ко всей странице, а к своему БЛИЖАЙШЕМУ ПРОКРУЧИВАЕМОМУ ПРЕДКУ - границы прилипания задаёт именно он. По спецификации "механизм прокрутки" создаёт любой предок с overflow: hidden, scroll, auto или overlay - причём даже если сам этот предок фактически не прокручивается. Это самая частая причина, когда sticky "не работает": где-то в цепочке предков случайно оказался overflow, отличный от visible - об этой же проблеме, только со стороны overflow, уже говорилось в уроке про overflow. Ещё две частые причины: у родителя sticky-элемента задана высота auto вместо явного значения (прилипать физически некуда без известных границ), или сам sticky-элемент по размеру больше, чем родитель.
.list-wrap { overflow-y: auto; height: 300px; } с явной высотой - предсказуемый контейнер, внутри которого sticky будет работать корректно.
.wrapper { overflow: hidden; } где-то выше по дереву предков, случайно (например, для обрезки декоративного элемента) - это создаёт "механизм прокрутки", который может испортить прилипание sticky-элемента внутри.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Забывают задать top/right/bottom/left | sticky ведёт себя как обычный relative, никакого прилипания | Всегда задавать хотя бы один порог (чаще всего top) |
| У одного из предков случайно overflow ≠ visible | sticky перестаёт прилипать как задумано - предок создал "механизм прокрутки" | Проверять всю цепочку предков на overflow: hidden/scroll/auto/overlay |
| У родителя sticky-элемента высота auto | Прилипать физически некуда - границы родителя неизвестны заранее | Задать родителю явную высоту |
| Ждут прилипания ко всей странице, а не к ближайшему прокручиваемому контейнеру | Элемент прилипает к границе своего родителя-контейнера с прокруткой, а не ко всему окну | Проверять, какой именно предок на самом деле прокручивается |
Шпаргалка
| Что нужно | Как сделать |
|---|---|
| Липкий заголовок списка/таблицы | position: sticky; top: 0; |
| Обязательное условие для работы sticky | хотя бы один из top/right/bottom/left |
| Где sticky "прилипает" | к ближайшему прокручиваемому предку, не обязательно ко всей странице |
| Частая причина поломки | overflow ≠ visible у одного из предков |
| Ещё одна причина поломки | height: auto у родителя sticky-элемента |
Коротко: отвечаем на вопросы
Почему мой position: sticky не прилипает?
Чаще всего причина одна из трёх: не задан ни один offset (top/right/bottom/left); у одного из предков случайно overflow: hidden, scroll или auto, что создаёт мешающий "механизм прокрутки"; или у родителя sticky-элемента высота auto, из-за чего границы для прилипания неизвестны заранее.
Чем sticky отличается от fixed?
fixed всегда привязан к окну просмотра целиком и не зависит от родителя. sticky ведёт себя как relative, пока не достигнут порог прокрутки, а затем прилипает только внутри границ своего ближайшего прокручиваемого родителя - и снова "отклеивается", когда родитель заканчивается.
К чему прилипает sticky-элемент - ко всей странице?
Не обязательно. sticky прилипает к своему ближайшему прокручиваемому предку - это может быть как вся страница, так и отдельный блок с overflow: auto/scroll, если он находится ближе в дереве предков.