Материал

Фиксирование блока при прокрутке страницы на CSS

Фиксирование блока при прокрутке страницы на CSS и HTML без JavaScript

При разработке интернет ресурсов часто возникает потребность в фиксации блока при прокрутке. При использовании параметра fixed для display в CSS происходит фиксирование, но оно не зависит от внешних блоков. Как же решить эту проблему?

Пару-тройку лет назад это решалось при помощи jаvascript. Программа вычисляла нахождение начала блока и следующего (граничащего снизу) блока и ставила и, соответственно, снимала значение fixed для display в css в нужный момент.

Но все развивается и появляются новые способы более быстрого решения, зачастую, насущной проблемы.

Рассмотрим работу фиксирования блока при прокрутке страницы на CSS на примере уже сверстанной страницы при помощи flex контейнеров.

Немного переделав программный код HTML и CSS, я получил следующее:

<style>
body {
margin: 0;
font-size:24px;
text-align:center;
}
.container {
display: flex;
min-height: 65%;
}
.main {
flex-grow: 1;
order: 2;
height:4000px;
padding-top:75px;
}
nav, .sidebar {
background-color: #a4c0f3;
flex-grow: 0;
flex-shrink: 0;
flex-basis: 15%;
}
nav {
order: 1;
}
.sidebar {
order: 3;
}
footer {
background-color: #638fe0;
height: 300px;
}
</style>
<body>
<div class="container">
<div class="main">Основной контейнер</div>
<nav>Меню</nav>
<div class="sidebar">Сайдбар</div>
</div>
<footer>Подвал</footer>
</body>

Фиксируем блок при помощи CSS sticky

В правый сайдбар я поместил изображение, которое как раз должно фиксироваться. Фиксирование должно произойти при достижении изображения (блока с изображением) верхней части окна браузера и перестать фиксироваться после достижения подвала (footer).

Для фиксации мы используем свойство sticky спецификации display для CSS. Главное правило при использовании sticky состоит в том, что для фиксирования блока при прокрутке страницы на CSS его нужно поместить в контейнер, имеющий запас высоты между верхней и нижней его границей. То есть контейнер, в котором должно иметься пустое место между его краями для перемещения фиксированного блока внутри. Иначе ничего работать не будет. Обычно для контейнера, в котором будет происходить фиксация, указывается значение высоты height:100%. Для того, чтобы не «мучаться» со значениями высоты в 100%, которое не всегда воспринимает display: block, мы будем использовать flex контейнеры (не забывайте, что в старых браузерах это не работает, собственно, как и свойство CSS display - sticky). Итак, наш код изменится и будет выглядеть следующим образом:

<style>
body {
margin: 0;
font-size:24px;
text-align:center;
}
.container {
display: flex;
min-height: 65%;
}
.main {
flex-grow: 1;
order: 2;
height:4000px;
padding-top:75px;
}
nav, .sidebar {
background-color: #a4c0f3;
flex-grow: 0;
flex-shrink: 0;
flex-basis: 20%;
}
nav {
order: 1;
}
.sidebar {
order: 3;
}
footer {
background-color: #638fe0;
height: 800px;
}
</style>
<body>
<div class="container">
<div class="main">Основной контейнер</div>
<nav>Меню</nav>
<div class="sidebar">
<div style="height:500px;border-bottom-color: black;
border-bottom-width:2px;border-bottom-style:solid;">
<p>Текст сайдбара, меню, быстрые ссылки или любая другая информация.</p>
</div>
<div style="position:sticky;top:10px;">
<img src="sale.jpg" style="width:100%;">
</div>
</div>
</div>
<footer>Подвал</footer>
</body>

Я поместил контейнер с изображением, которое нужно фиксировать при прокрутке в блок sidebar. Специально увеличил высоту подвала, чтобы было видно ограничение фиксации снизу при прокрутке. Для блока, который нужно зафиксировать, указано следующее значение CSS (обязательно нужно указать отступ сверху для элемента):

position:sticky;top:10px;
Графически полученная html страница выглядит следующим образом:
При прокрутке страницы блок с изображением SUPER SALE фиксируется до пересечения его с тегом footer (подвалом страницы). В коде я специально добавил нижнюю границу в 2 пикселя блока, от которого начинается фиксация. Можно использовать любое количество фиксированных элементов на сайте, все зависит от поставленных задач. 

Поделиться в соц. сетях: