[VanillaJS] 사이드 내비게이션 바와 모달이 있는 랜딩 페이지 만들기

초코침·2023년 4월 12일
0

VanillaJS

목록 보기
6/7

사이드 내비게이션 슬라이더와 모달 구현을 CSS를 중점적으로 연습했다.

와이어 프레임

기능 목록

  1. 햄버거 버튼을 클릭 시 사이드 내비게이션 바 보이기/숨기기
    • 보이기/숨기기 시에 부드럽게 움직이기
  2. sign up 버튼 클릭 시 form 모달 띄우기
    • 부드럽게 투명도 조절하며 띄우기
  3. 모달 닫기
    • 모달의 여백 클릭 시 모달 닫기
    • 모달의 닫기 버튼 클릭 시 모달 닫기

완성본

완성본(Github) 바로가기

배운점

더미 텍스트 생성하기 (Lorem Ipsum)

Emmet으로 간단하게 더미 텍스트를 만들 수 있다.

  • lorem + ↩︎: 한 단락의 더미 텍스트 생성

  • lorem단어수 + ↩︎: 단어 개수만큼의 더미 텍스트 생성

  • lorem*단락수 + ↩︎: 단락 개수만큼의 더미 텍스트 생성

랜덤 프로필 이미지 가져오기

내비게이션 부분에 들어갈 사진을 Random User API로 가져왔다.

fetch로 가져오지 않고 img의 src 속성에 url을 바로 넣어주었다.

<img src="https://randomuser.me/api/portraits/{성별}/{사람번호}.jpg" alt="user" />

사이드 내비게이션 바 만들기

위치 잡기

사이드 내비게이션 바를 담고 있는 <nav> 태그는 한 줄 전체를 차지하는 block-level 엘리먼트기 때문에 다른 요소 위에 겹쳐서 나타나지 않는다.

즉, 페이지에서 nav 영역이 끝나야만 nav 태그 아래 작성한 내용이 나타난다.

그렇다면 inline으로 보이도록 display 속성을 추가하면 안될까?

🙅‍♂️
height: 100vh 속성이 제대로 적용되지 않고 background-color도 적용되지 않는다.

position: fixed

position: fixed는 브라우저의 relative(상대적인)한 위치에 위치시키는 속성이다.


다른 요소 위에 겹쳐 나타나도록 position: fixed 속성을 적용한다. 이때 내비게이션 바가 다른 요소보다 위에 있도록 z-index 속성도 큰 숫자로 주었다.

transform: translateX(-100%)

내비게이션 바가 버튼을 클릭했을 때 나타나야 하기 때문에 기본적으로는 보이지 않는 상태(body의 왼쪽에 숨어있는 상태)여야 한다.

따라서 x축의 왼쪽으로 이동시켜야 하는데 이때 transform: translateX(이동 값) 속성을 이용할 수 있다. 화면 기준 왼쪽으로 이동해야 하므로 음수 값을 줘야 하고, 요소의 너비만큼 이동하도록 100% 이동하면 된다.

토글 버튼으로 내비게이션 보이기/숨기기

좌측 상단 햄버거 버튼을 클릭하면 숨겨둔 내비게이션이 나타나도록 클릭 이벤트 리스너를 달았다.

transform: translateX(300px);

클릭 시, 내비게이션 우측에 있는 영역인 body가 내비게이션 너비만큼 우측으로 이동하도록 하기 위해 transform: translateX(내비게이션 width) 속성이 담긴 class를 classList에 toggle 메서드로 붙였다.

// Toggle nav
toggle.addEventListener('click', () => {
  document.body.classList.toggle('show-nav');
});


클릭 시 발생하는 transform이 부드럽게 발생하도록 body에 transition: transform 0.3s ease 속성을 주었다. 이는 transform 발생 시 0.3초 간 부드럽게 움직(ease)이도록 한다.

body {
  font-family: 'Lato', sans-serif;
  margin: 0;
  transition: transform 0.3s ease;
}

모달 만들기

전체화면을 차지하도록 하기

전체화면을 차지하게 하려면 다음 css를 적용하면 된다. 공식처럼 쓰이는 것 같다.

.full-screen {
	position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

form을 정가운데 위치시키기

현재 form의 부모 요소는 검정색 반투명 배경이다. 이 배경 즉, 부모로부터 분리시켜 부모와는 별개로 위치를 옮길 수 있도록 position: absolute를 적용한다.

그럼 마치 부모 요소에서 form만 분리되어 어디로든 이동시킬 수 있는 느낌이 되는데, 가운데로 위치시키기 위해 topleft50%를 줬다.


form의 중심이 정가운데에 와야 하므로 transform을 이용해 위치를 옮겨주었다.

transform: translate(-50%, -50%);

display: none으로 안보이던 요소를 보이게 하기

display: none으로 모달 창을 숨겨뒀는데, 이 속성을 없애서 다시 보이게 하려면 어떻게 해야하지 싶었다. display 속성을 지워야하나 했는데 display: block을 적용해주면 된다!

모달 창 부드럽게 띄우기

@keyframes

display: block으로 변경해줬더니 모달이 너무 갑자기 뜬다..ㅎㅎ 그래서 부드럽게 opacity를 변경해주며 나타나도록 애니메이션을 넣었다.

keyframes로 modalopen이라는 애니메이션을 만든다. 이 애니메이션은 opacity가 0이었다가 1로 바뀌는 애니메이션이다.

@keyframes modalopen {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

animation-name 속성에 keyframes로 만든 애니메이션 이름을 넣어주고, from → to로 변하는데 얼마가 걸리게 할지 animation-duration 속성을 작성한다.

.modal {
	/* ... */
	animation-name: modalopen;
	animation-duration: var(--modal-duration);
}

모달의 여백 클릭 시 모달 닫기

클릭 이벤트가 발생한 target이 모달의 여백인 경우(e.target === modal), 모달의 class 중 show-modal을 제거한다.

// Hide modal on outside click
window.addEventListener('click', (e) =>
  e.target === modal ? modal.classList.remove('show-modal') : undefined
);
profile
블로그 이사중 🚚 (https://sungjihyun.vercel.app)

0개의 댓글