$ sudo teach IT

Вы наверняка замечали шапки сайтов, которые сначала прокручиваются вместе со страницей, а потом «прилипают» к верху экрана и остаются на виду. Или боковые панели, которые следуют за вами до определённого момента. Такое поведение сочетает поток и закрепление — и делается оно одним значением position: sticky. Это удобнейший инструмент: меню и заголовки разделов остаются под рукой, не занимая экран постоянно, как fixed, и не выпадая из потока заранее.

После этого урока вы сможете делать «прилипающие» шапки и панели, которые остаются в потоке до нужного момента, а затем закрепляются у края экрана при прокрутке.

Что уже умеем / что добавим

Вы умеете смещать элементы через relative и выводить из потока через absolute и fixed. Теперь освоим гибрид этих подходов — sticky. В сквозном проекте мы сделаем шапку сайта прилипающей: при прокрутке она закрепится вверху и меню всегда будет доступно.

Что вы узнаете в рамках статьи

  • Как работает position: sticky и чем он отличается от fixed.
  • Зачем stickyэлементу обязательно задавать порог (например, top).
  • В каких границах действует «прилипание».
  • Где sticky полезен на практике.

Ключевые термины

  • sticky — гибрид потока и закрепления: элемент прилипает к краю при прокрутке.
  • Порог прилипания — значение top/bottom, при достижении которого элемент закрепляется.
  • Контейнер прокрутки — область, в пределах которой действует «липкость».
  • Поток — обычное положение элемента до срабатывания порога.

Как работает sticky

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

Обязательное условие: у sticky-элемента должен быть задан порог — чаще всего top. Без него прилипать не к чему, и элемент просто останется в потоке.

.header {
  position: sticky;
  top: 0;
}

Здесь top: 0 означает: «пока не дойдёшь до верхнего края — едь в потоке, а как коснёшься верха, прилипни к нему». Шапка прокрутится вместе со страницей до верха окна и там закрепится.

Порог прилипания

Порог задаёт, на каком расстоянии от края элемент закрепится. top: 0 прилепит его вплотную к верху, top: 20px — с отступом в 20 пикселей:

.section-title {
  position: sticky;
  top: 16px;
}

Такой заголовок раздела при прокрутке закрепится в 16 пикселях от верхнего края и будет висеть там, пока виден его раздел. Порог можно задавать и снизу через bottom — тогда элемент прилипает к нижнему краю (полезно для панелей внизу экрана). Ключевое отличие от fixed: sticky-элемент до достижения порога живёт в потоке и занимает своё место, поэтому соседи не наезжают на него и раскладка не ломается.

Границы действия sticky

Важная особенность: sticky-элемент прилипает не навсегда, а лишь в пределах своего родителя. Как только вы прокрутите страницу за границы контейнера, в котором лежит липкий элемент, он «отклеится» и уедет вместе с этим контейнером.

Это очень удобно для заголовков разделов: заголовок прилипает, пока виден его раздел, а при переходе к следующему — уступает место новому заголовку. Если же вы хотите, чтобы шапка сайта прилипала на протяжении всей страницы, её родителем должен быть элемент во всю высоту документа (обычно так и есть, если шапка лежит прямо в body). Понимание этой границы избавляет от частого недоумения «почему мой sticky перестал липнуть».

.sidebar {
  position: sticky;
  top: 20px;
}

Боковая панель будет следовать за прокруткой, закрепившись в 20 пикселях от верха, но только пока виден её контейнер — а затем прокрутится дальше вместе с ним.

Применяем в проекте

Сделаем шапку сайта компании прилипающей. При прокрутке страницы она закрепится у верхнего края, и меню всегда будет под рукой.

<header class="site-header">
  <div class="logo">Компания</div>
  <nav class="nav">
    <a href="#">Главная</a>
    <a href="#">Услуги</a>
    <a href="#">Контакты</a>
  </nav>
</header>
.site-header {
  position: sticky;
  top: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
  background-color: #fff;
}

Обновите страницу и прокрутите её вниз: шапка сначала уезжает вместе с содержимым, а достигнув верха окна, прилипает к нему и остаётся на виду. Меню теперь доступно с любой точки страницы, при этом шапка не выпадает из потока заранее и не перекрывает контент в начале. Обратите внимание на фон у шапки: без него прокручиваемый контент просвечивал бы сквозь прилипшую шапку.

Частые ошибки

  • Забыт порог.
    Без top (или bottom) sticky не срабатывает — элемент остаётся в потоке. Порог обязателен.
  • Прозрачный фон.
    У прилипшей шапки под ней проезжает контент; задайте фон, иначе текст будет просвечивать.
  • Ограничивающий родитель.
    sticky действует только внутри своего контейнера; если тот невысокий, прилипание быстро закончится.
  • Путаница с fixed.
    fixed вырывает из потока сразу, sticky — только по достижении порога; для шапок обычно нужен именно sticky.

Итоги

Замечательно — вы освоили один из самых приятных приёмов вёрстки! Вы поняли, как position: sticky сочетает поток и закрепление, почему ему обязательно нужен порог вроде top: 0 и в каких границах он действует. Ваша шапка теперь прилипает к верху экрана при прокрутке, и меню всегда под рукой — сайт сразу стал ощущаться современнее и удобнее.

Отличная работа! В следующем уроке мы завершим раздел о позиционировании: разберёмся со слоями и наложением элементов через z-index и поймём, почему иногда элементы перекрывают друг друга не так, как ожидаешь.

На следующий урок