Как закрепить панель навигации в верхней части страницы только с помощью CSS и не скроллить её вместе с контентом.
Долгое время для фиксации панели навигации требовалось использовать JavaScript, чтобы определить, когда при прокрутке страницы ей нужно добавить CSS-класс для переключения в position: absolute
.
Чтобы получить аналогичный эффект, можно использовать только простое CSS-свойство.
position: sticky
Свойство position: sticky
укажет браузеру, что следует позволить элементу прокручиваться вместе с остальной частью документа, пока он не достигнет верхней части страницы. Как только это произойдет, позиция элемента фиксируется, а остальные элементы на странице прокручиваются за ним.
.sticky {
position: -webkit-sticky;
position: sticky;
top: 0;
}
<nav class="sticky">
<ul>
<li><a href="#a">Section A</a></li>
<li><a href="#b">Section B</a></li>
<li><a href="#c">Section C</a></li>
<li><a href="#d">Section D</a></li>
</ul>
</nav>
На первый взгляд всё работает нормально. Но, если приглядеться, клик по ссылке в навигации скроллит контент так, что заголовок секции самым бесстыдным образом оказывается под зафиксировавшейся панелью с навигацией. Это поправимо.
scroll-margin-top
Свойство scroll-margin-top
укажет браузеру высоту отступа, которую он должен использовать при скролле к контейнеру. Это свойство следует указывать элементам с якорями, на которые ведут ссылки из панели навигации.
Добавим контейнерам свойство scroll-margin-top
и присвоим ему значение 1em
. Теперь, когда браузер перейдёт по ссылке к якорю, он оставит сверху отступ 1em
.
И ещё: этот отступ применяется только к прокрутке. Сам элемент-контейнер по-прежнему сохраняет свои обычные отступы в контексте документа.
HTML-код примера фиксирующейся при прокрутке панели навигации
<h1>Scroll Margin</h1>
<nav class="sticky">
<ul class="list-inline">
<li><a href="#a">Section A</a></li>
<li><a href="#b">Section B</a></li>
<li><a href="#c">Section C</a></li>
<li><a href="#d">Section D</a></li>
</ul>
</nav>
<main>
<article class="section" id="a"><h2>Section A</h2></article>
<article class="section" id="b"><h2>Section B</h2></article>
<article class="section" id="c"><h2>Section C</h2></article>
<article class="section" id="d"><h2>Section D</h2></article>
</main>
CSS-код примера фиксирующейся панели скролл-навигации
body {
margin: 0 auto;
max-width: 40em;
width: 88%;
}
.section {
color: #ffffff;
height: 75vh;
margin: 0;
scroll-margin-top: 1em;
}
#a { background-color: #0074d9; }
#b { background-color: #2ecc40; }
#c { background-color: #ff851b; }
#d { background-color: #b10dc9; }
h2 {
margin: 0;
padding: 0;
}
.sticky {
background-color: #ffffff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
.list-inline {
list-style: none;
margin-left: -0.5em;
margin-right: -0.5em;
padding: 0;
}
.list-inline > li {
display: inline-block;
margin-left: 0.5em;
margin-right: 0.5em;
}
.list-inline > li:before {
content: "\200B"; /* 1 */
position: absolute; /* 2 */
}
Пара слов о поддержке position: sticky
и scroll-margin-top
браузерами
Свойство position: sticky работает во всех современных браузерах, но на момент написания этой заметки не работает с элементами thead
и tr
в Chrome и Edge (хотя оно работает с th
), а также table
в Firefox.
Свойство scroll-margin-top работает во всех современных браузерах.
Оба CSS свойства не работают в маргинальном IE-11 и более старых версиях IE.
How to prevent anchor links from scrolling behind a sticky header with one line of CSS
Поддержка CSS position: sticky
в вашем браузере
position: sticky