Day 24 - Sticky Nav

이번 과제는 반응형 웹에서 많이 쓰이는 디자인으로, 스크롤할 때 내비게이션 바(메뉴)가 고정되어 내려가고, 로고가 보이는 효과이다.

이전 과제 중에 scroll 속성을 이용한 과제들이 많았는데, 이번에도 그렇고, 쉬운 편이다.

CSS 속성 추가하기

우선 우리가 고정시켜야 하는 내비게이션 바는 <nav>로 감싸져 있다. 특정 시점에서 .fixed-nav라는 class 속성을 추가하면 css 스타일의 변화도 쉽게 끄고 켜는 개념으로 조정할 수 있다.

상단에 메뉴 고정시키기

원래의 nav 속성은

1
2
3
4
5
6
7
8
nav {
background: black;
top: 0;
width: 100%;
transition: all 0.5s;
position: relative;
z-index: 1;
}

이렇게 relative 속성이기 때문에 스크롤을 내리지 않은 상태에서는 그냥 중간에 위치한 메뉴바처럼 생겼다.

이제 .fixed-nav 속성이 body에 추가된 경우의 속성을 작성하자.

1
2
3
4
body.fixed-nav nav {
position: fixed;
box-shadow: 0 5px 0 rgba(0, 0, 0, 0.1);
}

이미 navtop: 0이고 fixed 위치 속성으로 바꿔줌으로써 상단에 고정시킬 수 있다.

로고 보이게 하기

원래의 로고는

1
2
3
4
5
6
7
8
li.logo {
max-width: 0;
overflow: hidden;
background: white;
transition: all 0.5s;
font-weight: 600;
font-size: 30px;
}

max-width가 0으로 설정되어 보이지 않는다. 간단하게 .fixed-nav 속성이 body에 추가됐을 때 위에서 한 것과 똑같이 li.logomax-width 속성만 바꾸면 된다.

1
2
3
.fixed-nav li.logo {
max-width: 500px;
}

transition: all 0.5s;로 설정되었기 때문에 모든 효과들이 보기 좋게 변한다. (스르륵 변화한다)

JS 작성하기

이번 자바스크립트 작성은 정말 쉽다. window.scrollY로 스크롤 한 Y 좌표 값(높이값)을 구해서 내비게이션 바의 offsetTop과 비교해주고 class 속성을 넣었다 뺐다 하면 끝난다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const nav = document.querySelector("#main");
const topOfNav = nav.offsetTop;

function fixNav() {
if (window.scrollY > topOfNav) {
document.body.style.paddingTop = nav.offsetHeight + "px";
document.body.classList.add("fixed-nav");
} else {
document.body.style.paddingTop = 0;
document.body.classList.remove("fixed-nav");
}
}

window.addEventListener("scroll", fixNav);

paddingTop을 설정하는 이유는 fixed로 속성이 변경될 때 의도하지 않는 여백이 생겨버려 뚝뚝 끊겨버리기 때문이다.

이제 부드러운 상단 고정 메뉴바가 완성되었다.