웹 페이지를 아무리 아래로 스크롤해도 항상 화면 상단에 붙어 있는 스티키(Sticky) 내비게이션 바는 메뉴 접근성을 높여 사용자 경험을 개선하는 대표적인 UI 패턴입니다. 이 글에서는 CSS와 JavaScript를 활용해 스티키 내비게이션 바를 구현하는 방법을 예제 코드와 함께 자세히 살펴보겠습니다.
구현 원리
핵심 아이디어는 간단합니다. JavaScript의 window.onscroll 이벤트로 스크롤 위치를 실시간으로 감시하고, 내비게이션 바의 초기 위치(offsetTop)보다 스크롤이 더 내려가면 position: fixed 스타일이 적용된 클래스를 추가하는 방식입니다. 반대로 위로 스크롤해 원래 위치로 돌아오면 해당 클래스를 제거합니다.
전체 예제 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
margin:0px;
margin-top:10px;
padding: 0px;
height: 150vh; /* 스크롤 효과를 만들기 위한 높이 */
}
nav{
width: 100%;
background-color: rgb(39, 39, 39);
overflow: auto;
height: auto;
}
.links {
display: inline-block;
text-align: center;
padding: 14px;
color: rgb(178, 137, 253);
text-decoration: none;
font-size: 17px;
}
.links:hover {
background-color: rgb(100, 100, 100);
}
.selected{
background-color: rgb(0, 18, 43);
}
.fixed{
position:fixed;
top:0;
}
.fixed + .sample-content{
padding-top: 60px;
}
</style>
</head>
<body>
<div class="sample-content">
<h1>Here are some headers</h1>
<h2>Here are some headers</h2>
<h3>Here are some headers</h3>
<h4>Here are some headers</h4>
</div>
<nav>
<a class="links selected" href="#"> Home</a>
<a class="links" href="#"> Login</a>
<a class="links" href="#"> Register</a>
<a class="links" href="#"> Contact Us</a>
<a class="links" href="#">More Info</a>
</nav>
<div class="sample-content">
<h1>Here are some headers after nav</h1>
<h2>Here are some headers after nav</h2>
<h3>Here are some headers after nav</h3>
<h4>Here are some headers after nav</h4>
</div>
<script>
window.onscroll = scrollShowNav;
let navEle = document.getElementsByTagName("nav")[0];
let stickyTop = navEle.offsetTop;
function scrollShowNav() {
if (window.pageYOffset >= stickyTop){
navEle.classList.add("fixed");
} else {
navEle.classList.remove("fixed");
}
}
</script>
</body>
</html>
코드 설명
- CSS 부분:
.fixed클래스는position: fixed; top: 0;을 적용해 요소를 화면 최상단에 고정합니다. 또한 인접 형제 선택자(.fixed + .sample-content)를 활용해 내비게이션 바가 고정될 때 뒤쪽 콘텐츠가 가려지지 않도록 상단 패딩을 추가합니다. - JavaScript 부분:
navEle.offsetTop으로 내비게이션 바의 문서상 세로 위치를 미리 저장해 두고, 현재 스크롤 위치(window.pageYOffset)가 그 값 이상이 되면fixed클래스를 추가하고, 그렇지 않으면 제거합니다.
참고로 순수 CSS만으로도 position: sticky; 속성을 사용해 비슷한 효과를 얻을 수 있습니다. 하지만 위와 같은 JavaScript 방식은 스크롤 위치에 따라 애니메이션, 크기 축소 등 추가 로직을 자유롭게 넣을 수 있다는 장점이 있습니다.
실행 결과
위 코드를 실행하면 다음과 같은 화면이 출력됩니다.

지정된 위치까지 스크롤하면 아래 그림처럼 내비게이션 바가 position: fixed처럼 동작하며 화면 상단에 고정됩니다.
