본문 바로가기
JavaScript

[JavaScript] 반응형 내비게이션 바 만들기

by teamnova 2024. 4. 1.
728x90

 

오늘은 반응형 내비게이션 바를 만들고, 

js를 이용하는 것 까지 해보겠습니다. 

 

 

알아야 할 내용  

 

1. @media screen and (mid-width : 800px) : 화면 너비가 800px이상일때 적용하는 미디어 쿼리를 이용한 반응형 스타일입니다.

2. nav-toggle{ display : none ;} : 네비게이션의 햄버거 메뉴를 숨깁니다. (이 코드는 미디어 쿼리 안에 있습니다. 즉 큰화면에서는 햄버거 메뉴가 안보이고, 800px이하일때는 햄버가 메뉴가 보이게 됩니다. )

3. links.classList.toggle("show-links") : show-links 클래스가 있으면 제거하고, 없으면 추가하는 코드입니다. 

 

 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Navbar</title>
    <!-- font-awesome -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
    />

    <!-- styles -->
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <nav>
      <div class="nav-center">
        <!-- nav header -->
        <div class="nav-header">
          <img src="./logo.svg" class="logo" alt="logo" />
          <button class="nav-toggle">
            <i class="fas fa-bars"></i>
          </button>
        </div>
        <!-- links -->
        <ul class="links">
          <li>
            <a href="index.html">home</a>
          </li>
          <li>
            <a href="about.html">about</a>
          </li>
          <li>
            <a href="projects.html">projects</a>
          </li>
          <li>
            <a href="contact.html">contact</a>
          </li>
        </ul>
        <!-- social media -->
        <ul class="social-icons">
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-facebook"></i>
            </a>
          </li>
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-twitter"></i>
            </a>
          </li>
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-behance"></i>
            </a>
          </li>
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-linkedin"></i>
            </a>
          </li>
          <li>
            <a href="https://www.twitter.com">
              <i class="fab fa-sketch"></i>
            </a>
          </li>
        </ul>
      </div>
    </nav>
    <!-- javascript -->
    <script src="app.js"></script>
  </body>
</html>

 

app.js

// ".nav-toggle" 클래스를 가진 요소를 찾아서 navToggle 변수에 할당합니다.
// ".links" 클래스를 가진 요소를 찾아서 links 변수에 할당합니다.
const navToggle = document.querySelector(".nav-toggle");
const links = document.querySelector(".links");

navToggle.addEventListener("click", function () {
  links.classList.toggle("show-links"); // "show-links" 클래스가 이미 존재하면 제거하고 존재하지 않으면 추가
});

 

 

styles.css

/*
=============== 
Fonts
===============
*/
@import url("https://fonts.googleapis.com/css?family=Open+Sans|Roboto:400,700&display=swap");

/*
=============== 
Variables
===============
*/

:root {
  /* dark shades of primary color*/
  --clr-primary-1: hsl(205, 86%, 17%);
  --clr-primary-2: hsl(205, 77%, 27%);
  --clr-primary-3: hsl(205, 72%, 37%);
  --clr-primary-4: hsl(205, 63%, 48%);
  /* primary/main color */
  --clr-primary-5: hsl(205, 78%, 60%);
  /* lighter shades of primary color */
  --clr-primary-6: hsl(205, 89%, 70%);
  --clr-primary-7: hsl(205, 90%, 76%);
  --clr-primary-8: hsl(205, 86%, 81%);
  --clr-primary-9: hsl(205, 90%, 88%);
  --clr-primary-10: hsl(205, 100%, 96%);
  /* darkest grey - used for headings */
  --clr-grey-1: hsl(209, 61%, 16%);
  --clr-grey-2: hsl(211, 39%, 23%);
  --clr-grey-3: hsl(209, 34%, 30%);
  --clr-grey-4: hsl(209, 28%, 39%);
  /* grey used for paragraphs */
  --clr-grey-5: hsl(210, 22%, 49%);
  --clr-grey-6: hsl(209, 23%, 60%);
  --clr-grey-7: hsl(211, 27%, 70%);
  --clr-grey-8: hsl(210, 31%, 80%);
  --clr-grey-9: hsl(212, 33%, 89%);
  --clr-grey-10: hsl(210, 36%, 96%);
  --clr-white: #fff;
  --clr-red-dark: hsl(360, 67%, 44%);
  --clr-red-light: hsl(360, 71%, 66%);
  --clr-green-dark: hsl(125, 67%, 44%);
  --clr-green-light: hsl(125, 71%, 66%);
  --clr-black: #222;
  --ff-primary: "Roboto", sans-serif;
  --ff-secondary: "Open Sans", sans-serif;
  --transition: all 0.3s linear;
  --spacing: 0.1rem;
  --radius: 0.25rem;
  --light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  --dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  --max-width: 1170px;
  --fixed-width: 620px;
}


/*
모든 요소, 가상 요소에 대해 마진과 패딩을 0으로 설정하고, box-sizing을 border-box로 설정
*/
*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
/*
body 요소에 대한 기본 스타일을 설정합니다. 폰트, 배경색, 글자색, 줄 높이, 폰트 크기 등
*/
body {
  font-family: var(--ff-secondary);
  background: var(--clr-grey-10);
  color: var(--clr-grey-1);
  line-height: 1.5;
  font-size: 0.875rem;
}
/*
모든 ul 요소의 리스트 스타일을 없앱니다.
*/
ul {
  list-style-type: none;
}
/*
모든 링크(a 태그)의 밑줄을 제거합니다.
*/
a {
  text-decoration: none;
}
/*
제목 태그(h1, h2, h3, h4)에 대해 글자 간격, 텍스트 변환, 줄 높이, 마진 하단, 폰트 패밀리를 설정
*/
h1,
h2,
h3,
h4 {
  letter-spacing: var(--spacing);
  text-transform: capitalize;
  line-height: 1.25;
  margin-bottom: 0.75rem;
  font-family: var(--ff-primary);
}

h1 {
  font-size: 3rem; /* h1 태그의 폰트 크기를 3rem으로 설정 */
}
h2 {
  font-size: 2rem; /* h2 태그의 폰트 크기를 2rem으로 설정 */
}
h3 {
  font-size: 1.25rem; /* h3 태그의 폰트 크기를 1.25rem으로 설정 */
}
h4 {
  font-size: 0.875rem;  /* h4 태그의 폰트 크기를 0.875rem으로 설정 */
}
p {
  margin-bottom: 1.25rem;  /* 단락의 아래 마진을 1.25rem으로 설정 */
  color: var(--clr-grey-5); /* 단락의 색상을 CSS 변수 --clr-grey-5로 설정 */
}

/* 
미디어 쿼리를 사용한 반응형 스타일  
화면 너비가 800px 이상일 때 적용됨 
*/
@media screen and (min-width: 800px) {
  h1 {
    font-size: 4rem; /*  h1의 폰트 크기를 4rem으로 조정 */
  }
  h2 {
    font-size: 2.5rem; /* 화면 너비가 800px 이상일 때 h2의 폰트 크기를 2.5rem으로 조정 */
  }
  h3 {
    font-size: 1.75rem; /* 화면 너비가 800px 이상일 때 h3의 폰트 크기를 1.75rem으로 조정 */
  }
  h4 {
    font-size: 1rem;/* 화면 너비가 800px 이상일 때 h4의 폰트 크기를 1rem으로 조정 */
  }
  body {
    font-size: 1rem;   /* 화면 너비가 800px 이상일 때 본문의 기본 폰트 크기를 1rem으로 설정 */
  }
  h1,
  h2,
  h3,
  h4 {
    line-height: 1; /* 화면 너비가 800px 이상일 때 h1, h2, h3, h4의 라인 높이를 1로 설정 */
  }
}

/* .section {
  padding: 5rem 0;
}

.section-center {
  width: 90vw;
  margin: 0 auto;
  max-width: 1170px;
} */

/* 
@media screen and (min-width: 992px) {
  .section-center {
    width: 95vw;
  }
} */
main {
  min-height: 100vh; /* 최소 높이를 뷰포트 높이의 100%로 설정하여 화면을 꽉 채움 */
  display: grid;  /* CSS 그리드 레이아웃 사용 */
  place-items: center;  /* 그리드 아이템을 중앙 정렬 */
}

/*
=============== 
Navbar 
===============
*/
nav {
  background: var(--clr-white); /* 배경색을 흰색으로 설정 */
  box-shadow: var(--light-shadow); /* 상자 그림자 효과 적용 */
}
.nav-header {
  display: flex; /* 플렉스박스 레이아웃 사용 */
  align-items: center; /* 아이템들을 세로축 중앙에 정렬 */
  justify-content: space-between; /* 아이템들을 양 끝으로 정렬 */
  padding: 1rem; /* 패딩으로 내부 여백 제공 */
}
.nav-toggle {
  font-size: 1.5rem; /* 폰트 크기 설정 */
  color: var(--clr-primary-5); /* 아이콘 색상 설정 */
  background: transparent; /* 배경색 투명 */
  border-color: transparent; /* 테두리 색상 투명 */
  transition: var(--transition); /* 전환 효과 적용 */
  cursor: pointer; /* 마우스 오버 시 커서를 포인터로 변경 */
}
.nav-toggle:hover {
  color: var(--clr-primary-1); /* 호버시(마우스를 올려놓았을 때) 아이콘 색상 변경 */
  transform: rotate(90deg); /* 호버시(마우스를 올려놓았을 때) 아이콘을 90도 회전 */
}
.logo {
  height: 40px; /* 로고 이미지 높이 설정 */
}
.links a {
  color: var(--clr-grey-3); /* 링크의 기본 색상을 설정합니다. */
  font-size: 1rem; /* 링크의 글꼴 크기를 1rem으로 설정합니다. */
  text-transform: capitalize; /* 링크 텍스트의 각 단어의 첫 글자를 대문자로 변환합니다. */
  letter-spacing: var(--spacing); /* 링크 텍스트의 글자 사이 간격을 설정합니다. */
  display: block; /* 링크를 블록 요소로 만들어 줄 바꿈을 추가하고, 너비를 부모 요소에 맞춥니다. */
  padding: 0.5rem 1rem; /* 링크 주변에 상하 0.5rem, 좌우 1rem의 여백을 추가합니다. */
  transition: var(--transition); /* 링크 스타일 변경에 애니메이션 효과를 적용합니다. */
}

.links a:hover {
  background: var(--clr-primary-8); /* 마우스를 링크 위에 올려놓을 때 배경 색상을 변경합니다. */
  color: var(--clr-primary-5); /* 마우스를 링크 위에 올려놓을 때 텍스트 색상을 변경합니다. */
  padding-left: 1.5rem; /* 마우스를 링크 위에 올려놓을 때 왼쪽 여백을 1.5rem으로 증가시킵니다. */
}

.social-icons {
  display: none; /* 소셜 아이콘을 기본적으로 숨깁니다. */
}

.links {
  height: 0; /* 링크 목록의 초기 높이를 0으로 설정해 숨깁니다. */
  overflow: hidden; /* 내용이 높이를 넘어가도 숨깁니다. */
  transition: var(--transition); /* 높이 변경에 애니메이션 효과를 적용합니다. */
}

.show-links {
  height: 10rem; /* 이 클래스가 추가되면 링크 목록의 높이를 10rem으로 설정해 링크 목록을 표시합니다. */
}

@media screen and (min-width: 800px) {
  .nav-center {
    max-width: 1170px; /* 내비게이션 중앙 정렬을 위한 최대 너비 설정 */
    margin: 0 auto; /* 좌우 마진을 자동으로 설정하여 중앙에 위치 */
    display: flex; /* 플렉스박스 모델 적용으로 내부 요소를 유연하게 배치 */
    align-items: center; /* 세로 방향으로 내부 요소를 중앙 정렬 */
    justify-content: space-between; /* 내부 요소를 양 끝에 정렬하고 사이에 공간을 둠 */
    padding: 1rem; /* 패딩으로 내부 여백 추가 */
  }
  .nav-header {
    padding: 0; /* 네비게이션 헤더의 패딩을 제거 */
  }
  .nav-toggle {
    display: none; /* 네비게이션 토글 버튼을 숨김 (큰 화면에서는 필요 없음) */
  }
  .links {
    height: auto; /* 링크 섹션의 높이를 자동으로 설정 */
    display: flex; /* 링크들을 플렉스박스 아이템으로 배치 */
  }
  .links a {
    padding: 0; /* 링크의 패딩 제거 */
    margin: 0 0.5rem; /* 링크 사이의 수평 마진 설정 */
  }
  .links a:hover {
    padding: 0; /* 호버 시 링크의 패딩 변경 없음 */
    background: transparent; /* 호버 시 배경색을 투명하게 설정 */
  }
  .social-icons {
    display: flex; /* 소셜 아이콘을 플렉스박스 아이템으로 배치 */
  }
  .social-icons a {
    margin: 0 0.5rem; /* 소셜 아이콘 사이의 마진 설정 */
    color: var(--clr-primary-5); /* 기본 색상 설정 */
    transition: var(--transition); /* 색상 변경 시 전환 효과 적용 */
  }
  .social-icons a:hover {
    color: var(--clr-primary-7); /* 호버 시 색상 변경 */
  }
}

 

 

결과 

 

화면을 줄였다가 늘리고, 햄버거 메뉴를 클릭해보세요.