웹페이지를 만들때 첫번째 고비는 GNB 즉 navbar를 만드는 것이고 두번째 고비는 mediaquery를 이용해 모바일 기기에 대응하는 레이아웃으로 만드는 것이다. 그리고 이 두가지의 고난이 동시에 오는 순간이 navbar를 mediaquery로 재선언하는 순간인데 처음 레이아웃을 크게 바꾸는 작업인만큼 미디어쿼리를 접했을 때 스타일링의 재정의가 까다로워서 고생을 했다.
하지만 요즘 대부분의 웹사이트가 모바일기기 대응을 제공하는 이상 모바일기기 대응작업은 웹페이지를 만들 때 빼놓을 수 없는 과정이기도 하다.
이렇게 나를 괴롭혔던 navbar의 mediaquery를 가장 쉽고 직관적이게 만들수 있는 방법에 대해 포스팅을 해보았다.
완성도는 위와 같다. 로고와 메뉴로 이루어진 navbar를 모바일기기 사이즈로 변경되었을 때, 토글버튼이 생기면서 버튼을 눌렀을 때 메뉴가 세로정렬 되는 navbar을 만들어 볼 것이다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hiko's Portfolio</title>
<script
src="https://kit.fontawesome.com/9eb162ac0d.js"
crossorigin="anonymous"
></script>
<link
href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
<script src="main.js" defer></script>
</head>
<body>
<!-- Navbar -->
<nav id="navbar">
<div class="navbar__logo">
<i class="fab fa-angellist"></i>
<a href="#">Hiko</a>
</div>
<ul class="navbar__menu">
<li class="navbar__menu__item">Home</li>
<li class="navbar__menu__item">About</li>
<li class="navbar__menu__item">Studio</li>
<li class="navbar__menu__item">Works</li>
<li class="navbar__menu__item">Process</li>
<li class="navbar__menu__item">Contact</li>
</ul>
<button class="navbar__toggle-btn">
<i class="fas fa-bars"></i>
</button>
</nav>
</body>
</html>
/* Global */
:root {
/* Color */
--color-dark-white: #bdbdbd;
--color-black: #4d4d4d;
--color-grey: #616161;
--color-light-grey: #7c7979;
--color-black: #000000;
/* Font size */
--font-large: 48px;
--font-medium: 28px;
--font-regular: 18px;
--font-small: 16px;
--font-micro: 14px;
/* Font weight */
--weight-bold: 700;
--weight-semi-bold: 600;
--weight-regular: 400;
* {
box-sizing: border-box;
}
body {
font-family: 'Open Sans', sans-serif;
margin: 0;
height: 3000px;
}
a {
text-decoration: none;
color: var(--color-black);
}
ul {
padding-left: 0;
margin: 0;
}
li {
list-style: none;
}
button {
background-color: transparent;
cursor: pointer;
border: none;
outline: none;
padding: 0;
}
/* 1. Navbar 정렬 */
#navbar {
position: fixed;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid var(--color-light-grey);
}
.navbar__logo {
font-size: var(--font-medium);
font-weight: var(--weight-semi-bold);
}
.navbar__menu {
display: flex;
}
.navbar__menu__item {
padding: 8px 12px;
margin: 0 4px;
cursor: pointer;
border: 1px solid var(--color-light-grey);
}
/* 2.toggle btn */
.navbar__toggle-btn {
position: absolute;
right: 32px;
top: 24px;
font-size: 24px;
display: none;
}
/* 3.mediaquery */
@media screen and (max-width: 768px) {
.navbar__toggle-btn {
display: block;
}
#navbar {
/* logo와 gnb 수직배열 */
flex-direction: column;
/* logo 제자리로 돌리기 */
align-items: flex-start;
}
.navbar__menu {
/* gnb menu 수직배열 */
flex-direction: column;
/* 텍스트 화면전체 너비의 중앙배열 */
width: 100%;
text-align: center;
display: none;
}
.navbar__menu.open {
display: block;
}
}
#navbar {
position: fixed;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
transition: all var(--animation-duration) ease-in-out;
border-bottom: 1px solid var(--color-light-grey);
}
스크롤을 내려도 메뉴를 고정시키기 위해 fixed
를 주고 화면너비 전체를 사용하기 위해 width:100%
를 주었다. 그리고 블럭요소를 수평 정렬시키기 위해 flexbox
를 사용했다.
😳 nav를 스타일링할 때 습관적으로 nav안의 요소에 너비나 높이를 설정하게 되면 화면이 바뀌었을 때 대응하기가 어려워진다. 버튼 하나하나에 너비를 주고싶은 경우에 padding을 주는 것이 좋다.
/* 2.toggle btn */
.navbar__toggle-btn {
position: absolute;
right: 32px;
top: 24px;
font-size: 24px;
display: none;
}
모바일 화면에서 메뉴를 노출시킬 토글버튼을 스타일링한다. position: absolute
로 나머지 두 요소와 상관없이 위치를 잡아두고 모바일 화면에서만 노출시켜야 하기 때문에 display: none;
으로 숨겨둔다.
/* 3.mediaquery */
@media screen and (max-width: 768px) {
.navbar__toggle-btn {
display: block;
}
#navbar {
/* logo와 gnb 수직배열 */
flex-direction: column;
/* logo 제자리로 돌리기 */
align-items: flex-start;
}
.navbar__menu {
/* gnb menu 수직배열 */
flex-direction: column;
/* 텍스트 화면전체 너비의 중앙배열 */
width: 100%;
text-align: center;
display: none;
}
.navbar__menu.open {
display: block;
}
}
화면이 768px 밑으로 떨어졌을 때 바뀔 레이아웃을 스타일링한다. 먼저 숨겨둔 토글버튼을 다시 노출시킨다.
navbar에서 수평배열 되있던 로고와 메뉴를 flex-direction: column;
으로 변경하여 수직배열로 한다.
이 경우 윗처럼 로고와 메뉴와 같이 정렬되어 로고가 중간에 온다. 이것을 해결하기 위해 align-items: flex-start;
를 사용해 로고가 원래 있던 자리를 유지시킨다.
로고가 중간에 오는 이유는 미리 선언한 align-items: center;가 적용된 상태이기 때문이다. flex-direction이 column일 경우 교차축은 수평이 되어 중앙으로 정렬된다.
open
이라는 class를 붙은 선택자에 스타일링해준다.
const navbarMenu = document.querySelector('.navbar__menu');
const navbarToggleBtn = document.querySelector('.navbar__toggle-btn');
navbarToggleBtn.addEventListener('click', () => {
navbarMenu.classList.toggle('open');
});
.navbar__menu
와 .navbar__toggle-btn
을 변수에 넣는다.addEventListener()
를 사용하여 navbarToggleBtn
을 클릭했을 때 작동될 함수를 만든다toggle()
을 이용해 navbarMenu
에 open
이라는 class가 추가되었다 사라졌다 한다navbarMenu
는 open
에 인해 display:none
, display:block
이 반복되며 메뉴를 노출시킨다.
안녕하세요. 드림코딩 아카데미 강의 내용이 블로그에 올라와 있다는 다른 수강생 분의 보고를 받고 방문하게 되었습니다. 아카데미 강의 내용은 블로그에 공개적으로 작성할 수 없습니다. 이는 엄연히 저작권 위반이며, 비공개 또는 삭제 처리 부탁드립니다. 블로그에 올리신 유사 포스트도 조치 부탁드립니다.