2022.10.20~10.30
2023.01.05~01.10
1024px 이하면 Main Navigation 바를 숨기고, 햄버거 버튼이 등장합니다. media query를 사용하여 구현했습니다.
1024px 이하일 때, 햄버거 버튼을 누르면 Main Navigation 이 보입니다. 버튼 클릭과 Main Navigation 안의 리스트 토글은 JavaScript로 구현하였습니다. 클릭될 항목들은 querySelector로 선택했고, 이벤트리스너를 사용하여 클릭 후에 일어날 동작들을 설정해줬습니다.
const mobileNav = document.querySelector('.mobile-nav-container');
// 드롭메뉴 열기 버튼
const openBtn = document.querySelector('.mobile-nav-container > button');
openBtn.addEventListener('click', (e) => {
mobileNav.querySelector('nav').style.display = 'block';
});
// 드롭메뉴 닫기 버튼
const closeBtn = document.querySelector('.mobile-nav-top button:last-child');
closeBtn.addEventListener('click', () => {
mobileNav.querySelector('nav').style.display = 'none';
});
// 드롭메뉴 리스트 토글
const mobileList = document.querySelectorAll('.mobile-nav-lists div');
mobileList.forEach((list) => {
list.addEventListener('click', (e) => {
const submenuUl = e.target.closest('.mobile-nav-lists').querySelector('.submenu');
submenuUl.classList.toggle('submenu-clicked');
});
});
우측 사이드바는 767px 이하가 되면 하단의 고정된 바 형태로 변경됩니다. 창크기에 따른 변화는 media query를 사용하여 구현했고, 하단 바를 고정시킨 것은 position: fixed
로 구현하였습니다.
.side-nav {
position: fixed;
right: 0;
bottom: 150px;
z-index: 9999;
}
@media screen and (max-width: 768px) {
.side-nav {
bottom: 0;
width: 100%;
}
}
main menu인 top-nav-lists
에 마우스를 올리면submenu
가 등장합니다. submenu에 해당하는 것을 display:none
으로 해뒀다가 hover 했을 때 display: block
으로 설정해주어 구현했습니다.
.top-nav-lists:hover .submenu {
display: block;
}
우측 사이드바가 하단에 고정된 것과 마찬가지로, 스크롤에 사이드바가 따라다니는 것은 position: fixed
로 구현하였습니다.
.side-nav {
position: fixed;
right: 0;
bottom: 150px;
z-index: 9999;
}
내비게이션바 메뉴 사이의 노란색 도형 추가하는 작업시, 마지막요소를 제외하는 것이 어려워, :last-child
를 써서 마지막요소를 제외하곤 했습니다. 패스트캠퍼스 과정 중 멘토님의 코드리뷰를 통해 li + li
처럼 연산자로 처리해주는 방법을 알게돼 좀더 가독성 좋게 처리하였습니다. 또 margin, padding 값을 속기형으로 알맞게 적어주지 않아, 불필요한 코드들이 많았는데 리팩토링을 통해 수정했습니다.
.top-nav-lists {
position: relative;
padding: 0 10px 0 17px;
white-space: nowrap;
}
.top-nav-lists button {
height: 60px;
font-size: 20px;
font-weight: 600;
line-height: 3;
}
.top-nav-lists + .top-nav-lists button::after {
content: '';
position: absolute;
left: 0;
width: 8px;
height: 8px;
margin: 26px 0;
border-radius: 50%;
background-color: var(--color-nav-after);
}
이미지는 flex를 사용하여 배치하였습니다. 이미지별로 사이즈가 모두 달랐기에, 반응형에 따라 container와 각각의 이미지가 일정 비율대로 줄어들고 늘어나도록 하는 것이 어려웠습니다. 개발자도구를 통해 최적 수치를 찾아 해결했습니다. 되도록이면 px
보다 %
, rem
를 쓰는 것이 다양한 디바이스에 대비하기 좋다는 것을 알게됐습니다. 이미지 내의 text는 positon: absolute
를 줘서 하나의 이미지에서 위치를 조정하였습니다.
.program-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
padding-top: 50px;
}
.program-container .item {
position: relative;
border-radius: 20px;
background-color: #000;
overflow: hidden;
}
.program-container .item:first-child {
width: 58%;
}
.program-container .item:nth-child(2) {
width: 36.8%;
}
.program-container .item:nth-child(3),
.program-container .item:nth-child(4),
.program-container .item:nth-child(5) {
width: 30.8%;
}
.program-container .item img {
width: 100%;
height: 100%;
opacity: 65%;
border-radius: 20px;
transition: var(--trans);
}
.program-container .item img:hover {
transform: scale(1.05);
}
.program-container .item .text {
position: absolute;
bottom: 32px;
left: 34px;
color: #fff;
font-size: 28px;
font-weight: 600;
line-height: 1.4;
}
.program-container .item .text strong {
display: block;
margin-bottom: 10px;
color: #fff8c8;
font-size: 18px;
}
.program-container .item .text strong::before {
content: '';
display: inline-block;
width: 10px;
height: 10px;
margin: 3px 8px 0 0;
border-radius: 50%;
background-color: #fff8c8;
}
.program-container .item:first-child .text {
font-size: 34px;
}
aria-label
등 접근성을 향상시킬 수 있는 코드를 쓰고자 노력했습니다. 이 과정이 정말 재밌게 느껴졌고, WAI-ARIA를 자유자재로 쓸 수 있을 만큼 익숙해지고 싶다는 생각을 했습니다. 더 자세히 알고 싶어 따로 포스팅하였습니다.
프로그램 목록의 이미지 hover시, transition 효과 자연스럽지 못한 문제가 있었습니다.
해결
calc()
사용리팩토링의 장점에 대해 알게 됐습니다. 복습도 되고 예전에 제가 쓴 코드를 보며 부족했던 것을 깨닫는 것 자체에서 성장했음을 느낄 수 있었습니다. 프로젝트가 진행되는 기간도 중요하지만, 앞 뒤로 프로젝트를 잘 시작하고 잘 마무리하는 것 또한 프로젝트의 중요한 일부라는 것을 깨달았습니다. 관심있는 사이트를 이렇게 구석구석 뜯어본 것이 재밌는 경험이었고, 강의 들으면서 해봤던 것보다 더 다양한 것들을 시도해볼 수 있어서 좋았습니다!