WEB Developer

16. 기본 탐색 스타일링 및 반응형 웹사이트 설정

Clark Shim 2024. 3. 19. 23:01

header에 대한 기본 스타일링을 하기 위하여 header와 div에 id를 설정

 
 <header id="main-header">
 
 <div id="logo"><a href="/">IVE</a></div>
 

 

모바일에서 사용을 위해 반응형으로 만들어주기 위해 네비게이션 바에도 햄버거 버튼을 만들어줌

 
  <button id="mobile-menu-btn">
    <span></span>
    <span></span>
    <span></span>
  </button>
 

 

모바일 메뉴의 각 메뉴 기능을 추가로 구성하게 되면 복잡해짐으로 

 
 <aside>
   <nav>
   
   </nav>
 </aside>
 

 

기본 메뉴를 <nav> ~~ </nav> 사이에 구성을 직접하지 않고 nav-items.ejs를 별도로 만들어 include 구성함

 
 <ul>
    <% if (!locals.isAdmin) { %>
    <li><a href="/">Shop</a></li>
    <li><a href="/cart">Cart</a></li>    
    <% } %>

    <% if (locals.isAuth && !locals.isAdmin) { %>
    <li><a href="/orders">Orders</a></li>
    <% } %>
   
    <% if (locals.isAdmin) { %>
    <li><a href="/admin/products">Manage Products</a></li>
    <li><a href="/admin/orders">Manage Orders</a></li>
    <% } %>

    <% if (!locals.isAuth) { %>
    <li><a href="/signup">Signup</a></li>
    <li><a href="/login">Login</a></li>
    <% } %>

    <% if (locals.isAuth) { %>
    <li>
      <form action="/logout" method="POST">
        <input type="hidden" name="_csrf" value="<%= locals.csrfToken %>">
        <button>Logout</button>
      </form>        
    </li>
    <% } %>
 </ul>
 

 

스타일링을 위하여 navigation.css를 만들어 CSS 작성

 
 #main-header {
    width: 100%;
    max-width: 60rem;
    height: 5rem;
    margin: 0 auto;
    padding: 0 var(--space-6);
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid var(--color-primary-500);
    background-color: var(--color-gray-500);
 }
 

 

해당 CSS 적용 후 메뉴 화면은 다음과 같다

navigation.css는 전체 페이지에 적용이 되어야 하므로 head.ejs에 bass.css를 포함하고 있는 곳에 해당 CSS 등록

 
 <!DOCTYPE html>
 <html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%= pageTitle %></title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link rel="stylesheet" href="/styles/base.css">
    <link rel="stylesheet" href="/styles/navigation.css">
 

 

다시 navigation css로 가서 logo에 대한 CSS 적용

 

새로 만든 nav-items.ejs는 header와는 다른 ejs 이기 때문에 main-header의 항목으로 정의할 수 없음

따라서 별도의 class를 지정하여 만들어줌

 
 <ul class="nav-items">
    <% if (!locals.isAdmin) { %>
    <li><a href="/">Shop</a></li>
    <li><a href="/cart">Cart</a></li>    
    <% } %>
 

 

navigation.css 에서 mobile button인 햄버거 버튼 스탈링을 위하여 다음과 같이 정의

 
 #mobile-menu-btn {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    border: none;
    cursor: pointer;
    width: 2.25rem;
    height: 2.25rem;
 }
 

 

mobile-menu-btn 적용 후 화면은 다음과 같다  span에 대한 styling을 추가로 해야 함.

 

mobile-menu-btn에 transparant 설정과 span을 추가로 적용

 

 
 #mobile-menu-btn {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    border: none;
    cursor: pointer;
    width: 2.25rem;
    height: 2.25rem;
    background-color: transparent;
    padding: 0;
 }

 #mobile-menu-btn span {
    width: 2.25rem;
    height: 0.24rem;
    background-color: var(--color-gray-100);
 }
 

 

다음과 같이 햄버거 버튼이 만들어짐

 

 

 

메뉴 각 항목의 공간을 떨어뜨리기 위해 nav-ltems li 에 margin을 적용한다.

 
 .nav-items li {
    margin: 0 var(--space-2);
 }
 

 

화면은 다음과 같다

 

 

이제 Desktop 장치와 모바일 장치를 분리하기 위해 기본 메뉴가 보일때와 햄버거 버튼이 보일 때를 분리할 수 있도록 반응형 사이트를 구성한다.

 

이를 위해서는 데스크탑에서만 적용되는 미디어 쿼리를 추가한다.

@media (min-width: 48rem) {
    #mobile-menu-btn {
        display: none;
    }
}

 

즉 width가 48rem 이상이면 햄버거 버튼이 보이지 않는다.

 

네비게이션 항목과 호버 스타일을 조정하기 위하여 다음과 같이 정의

 
    .nav-items a {
        padding: var(--space-2) var(--space-4);
        border-radius: var(--border-radius-small);
    }

    .nav-items a:hover,
    .nav-items a:active {
        background-color: var(--color-primary-500-bg);
    }
 

 

아래와 같이 각 메뉴의 간격이 넓어지고 hovering 시에 별도 표시가 달라짐

 

모바일로 볼 경우 다음과 같이 나옴

 

#main-header에서 position을 다음과 같이 고정 시킨다.

 
 #main-header {
    position: fixed;
    top: 0;
    left: 0;
 

 

 

Login이 미끄러졌으므로 

main 에서 margin-top을 정의

 
 main {
    margin-top: 6rem;   
 }
 

 

 

이는 position: fixed로 #main-header가 구성되어 문서 플로우에서 제외되기 때문에 내용이 아래로 미루어지는 것임

 

해당 규칙을 모바일쪽에도 적용하지만 magin-top은 0으로 설정

 

이제 PC의 메뉴는 큰 화면에서 보이고 작은 화면에서 안보이도록 설정 한다

 

 
 #main-header nav {
    display: none;
 }

을 정정하고 @media에서는

 

 
  #main-header nav {
     display: block;
 }
 

으로 구성함

 

그럼 다음과 같이 화면이 나온다.

모바일 화면
PC 화면

 

모바일 메뉴를 위한 스타일링은 다음과 같이 한다.

#mobile-menu{
    position: fixed;
    top: 5rem;
    left: 0;
    height: calc(100vh - 5rem);
    width: 100%;
    background-color: var(--color-gray-700);
    display: flex;
    flex-direction: center;
}

 

화면은 다음과 같다.

 

추가 nav 작업을 하면

#mobile-menu nav {
    height: 20rem;
    width: 90%;
    margin: var(--space-4) auto;
}

 

 

추가적으로 .nav-items 스타일링을 아래와 같이 하면

.nav-items {
    height: 100%;
    display: flex;  
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
}

 

 

모바일 메뉴 글씨 크기를 키우기 위하여 다음과 같이 정의

#mobile-menu .nav-items a,
#mobile-menu .nave-items button {
    font-size: 1.75rem;
}

 

 

.nav-items에서 flex-direction이 column 이므로 

.nav-items {
    height: 100%;
    display: flex;  
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
}

 

아래의 메뉴가 오른쪽에 뭉쳐 있음

 

이를 위하여 @margin에서 flex-direction: row로 설정을 해

 
    .nav-items {
        flex-direction: row;
    }
 

 

 

이제 로그아웃 버튼을 스타일링 한다

 

위의 모습을 변경하기 위하여 아래와 같이 정의

 
 .nav-items button {
    cursor: pointer;
    font: inherit;
    border: 1px solid var(--color-primary-500);
    border-radius: var(--border-radius-small);
    background-color: transparent;
    color: var(--color-primary-500);
    padding: var(--space-2) var(-space-4);
 }

 

 

최종 CSS 코드는 다음과 같음

더보기
main {
    margin-top: 6rem;
  }
 
  #main-header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    max-width: 60rem;
    height: 5rem;
    margin: 0 auto;
    padding: 0 var(--space-6);
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid var(--color-primary-500);
    background-color: var(--color-gray-500);
  }
 
  #logo a {
    font-weight: bold;
    font-size: 2rem;
  }
 
  #main-header nav {
    display: none;
  }
 
  .nav-items {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
  }
 
  .nav-items li {
    margin: 0 var(--space-2);
  }
 
  .nav-items button {
    cursor: pointer;
    font: inherit;
    border: 1px solid var(--color-primary-100);
    border-radius: var(--border-radius-small);
    background-color: transparent;
    padding: var(--space-2) var(--space-4);
  }
 
  #mobile-menu-btn {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    border: none;
    cursor: pointer;
    width: 2.25rem;
    height: 2.25rem;
    background-color: transparent;
    padding: 0;
  }
 
  #mobile-menu-btn span {
    width: 2.25rem;
    height: 0.2rem;
    background-color: var(--color-gray-100);
  }
 
  #mobile-menu {
    position: fixed;
    top: 5rem;
    left: 0;
    height: calc(100vh - 5rem);
    width: 100%;
    background-color: var(--color-gray-700);
    display: flex;
    flex-direction: column;
    align-items: center;
  }
 
  #mobile-menu nav {
    height: 20rem;
    width: 90%;
    margin: var(--space-4) auto;
  }
 
  #mobile-menu .nav-items a,
  #mobile-menu .nav-items button {
    font-size: 1.75rem;
    color: var(--color-primary-100);
  }
 
  @media (min-width: 48rem) {
    main {
      margin-top: 0;
    }
 
    #main-header {
      position: static;
    }
 
    #main-header nav {
      display: block;
    }
 
    .nav-items button {
      color: var(--color-primary-500);
      border-color: var(--color-primary-500);
    }
   
    #mobile-menu-btn {
      display: none;
    }
 
    #mobile-menu {
      display: none;
    }
 
    .nav-items {
      flex-direction: row;
    }
 
    .nav-items a {
      padding: var(--space-2) var(--space-4);
      border-radius: var(--border-radius-small);
    }
 
    .nav-items a:hover,
    .nav-items a:active {
      background-color: var(--color-primary-500-bg);
    }
  }