본문 바로가기
웹 프로그래밍/프론트엔드

[HTML/CSS] 1차 메뉴 바 만들기 : 마우스를 인식해 보자

by me_in_sk 2023. 5. 13.
반응형

 

 

오늘은 기초적인 1차 메뉴를 만들어 보자. 이번에 만들 메뉴는 마우스를 인식하면 메뉴 요소가 반응을 하는 기능을 포함한 깔끔한 느낌의 메뉴이다. 메뉴 바는 다양한 부류의 정보를 담고 있는 메뉴들의 이름을 핵심 단어를 통해 지정함으로써 처음 이용하는 사용자에게도 해당 메뉴에 담겨있는 정보들의 내용을 짐작할 수 있게 만들어 준다. 따라 다양한 사이트에서 사용되고 있는 메뉴 바는 사이트에 처음 접속한 사용자에게 찾고자 하는 정보를 찾아갈 수 있도록 내비게이션 역할을 해줄 수 있으며, 사이트 관리자는 보다 체계적으로 사이트를 운용할 수 있게 된다.

 

 

우선 완성된 이미지를 보자

마우스-커서를-인식한-메뉴
마우스 커서를 인식한 'Study' 메뉴

 

상단의 중앙에는 사이트의 로고를, 그 하단에는 메뉴들이 존재하게 되며, 마우스 포인터를 'Study' 메뉴에 올려두게 되면 해당 메뉴의 글자의 색이 변하며 밑줄이 생기게 된다.

 

 

기본 마크업부터 살펴보자

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">

<header>
  <h1 class="logo-bar con-min-width">
    <div class="text-align-center con">
      <a href="#" class="logo-bar__logo">
        <span class="ico-1"><i class="fa-solid fa-plane"></i></span>
        <span>
          <span>me-</span><span>in</span><span>-journey</span>
        </span>
      </a>
    </div>
  </h1>

  <h2 class="menu-bar con-min-width">
    <div class="con">
      <nav class="menu-bar__menu-box-1 text-align-center">
        <ul class="inline-grid">
          <li><a href="#" class="block">Home</a></li>
          <li><a href="#" class="block">Read</a></li>
          <li><a href="#" class="block">Write</a></li>
          <li><a href="#" class="block">About</a></li>
          <li><a href="#" class="block">SNS</a></li>
          <li><a href="#" class="block">Study</a></li>
          <li><a href="#" class="block">Exit</a></li>
        </ul>
      </nav>
    </div>
  </h2>
</header>

 

위의 HTML 코드를 아무런 CSS 작업 없이 출력한다면 아래와 같은 모습을 보인다.

기본-마크업-메뉴
<li>에 의해 메뉴 앞에 붙은 ●과 <a>에 의해 메뉴의 색과 밑줄이 생겼다

 

완성된 메뉴 바의 모습을 만들기 위해서는 우선 노멀라이즈 과정을 통해, 태그의 기본 옵션 중 내가 원하지 않는 옵션들을 제거해 주어야 내가 원하는 형태로 만들어 나가기 수월해진다.

/* 노멀라이즈 시작 */
body, ul, li {
  margin: 0;
  padding: 0;
  list-style: none;		/* 해당 태그의 list-style을 none으로 하는 것으로 ●을 제거한다 */
}

a {
  color: inherit;		/* 부모 엘리먼트의 값을 물려받는다 */
  text-decoration: none;	/* 해당 태그의 text-decoration을 none으로 하는 것으로 밑줄을 제거한다 */
}
/* 노멀라이즈 끝 */

 

위의 노멀라이즈를 적용해 보자

단순화-메뉴
필요하지 않은 태그의 요소가 제거되었다

 

다음으로, 메인 로고와 메뉴 목록들을 가운데로 가져오는 작업을 해준다. 이 과정은 해당 요소들의 부모 태그에 con과 con-min-width 등의 속성을 만들어 처리함으로써 해당 사이트의 다른 요소에서도 사용할 수 있게끔 라이브러리를 만들어 관리해 주면 좀 더 체계적으로 코드를 작성해 나가는 것에 있어 유리하다. 하지만, 여기서는 과정의 설명을 위해 라이브러리 생성을 생략하고 포스팅의 마지막에 라이브러리를 정리하도록 하겠다.

 

  • con-min-width : 사이트의 최소 너비 결정 ( 지정 값 이상으로 축소 시 스크롤바 생성 후 너비는 고정 )
  • con : 가운데 정렬 및 실질적으로 사용할 너비 결정
/* 사이트의 최소 너비 결정 */
.con-min-width {
  min-width: 1200px;
  padding: 0 10px;
  border: 10px solid blue;  /* con-min-width 영역을 파란 상자로 표시 */
}

/* 사이트의 모든 요소에 사용될 수 있는 값은 별도로 라이브러리로 정리할 수 있다. */
/* 사이트의 중앙에 위치하도록 결정 */
.con {
  margin-left: auto;
  margin-right: auto;
}

/* 해당 값은 해당 요소에서만 사용되는 값이므로 별도로 정리한다 */
.con {
  width: 700px;
  border: 10px solid red;	/* con 영역을 빨간 상자로 표시 */
}

 

위의 속성들을 적용해 보자

 

중앙-메뉴
con 속성에 의해 1200px의 사이트 너비 중 700px의 con 영역이 사이트 중앙에 위치하였다

 

하지만, 우리가 원하는 것은 로고와 메뉴 모두 가운데에 위치하는 것이다. con의 영역은 어디까지나 우리가 사용할 영역일 뿐, 실질적으로 표시가 되는 문자열 등은 여전히 con 내에서는 좌측에 정렬 것을 확인할 수 있다. 따라서 우리는 con 내부에서 따로 문자열 들을 가운데로 정렬시켜 줄 필요가 있다.

이에 부모 태그의 속성 text-align의 값을 center로 지정한다면, 자식 엘리먼트에 들어있는 문자열들은 가운데로 정렬된다. 이때, text-align 속성은 자식의 display 값이 inline이거나 inline-block일 때만 정렬이 되므로, display의 값을 기본적으로 block으로 갖는 <li>태그의 display 속성을 우선 변경시켜 줄 필요가 있다.

 

/* <li>의 display 값은 기본적으로 block의 형태이므로 inline-block 값으로 바꿔준다 */
.menu-bar__menu-box-1 > ul > li {
  display: inline-block;
}

/* inline-block 형태는 text-align을 통해 정렬이 가능하다 */
.menu-bar__menu-box-1 > ul {
  text-align: center;
}

/* <a>와 <span>의 display 값은 기본적으로 inline의 형태이므로 text-align을 통해 정렬이 가능하다 */
.logo-bar > div {
  text-align: center;
}

 

위의 속성들을 적용해 보자

가운데-정렬-메뉴
con 내부에서 문자열들이 가운데로 정렬된 모습

 

위의 과정에서 block의 형태이던 <li>태그를 inline-block으로 변경해 주었기 때문에 메뉴의 요소들이 한 줄에 표시가 된다.

이제 어느 정도 틀이 잡혔으니 로고와 메뉴의 크기를 조절해 보자. 이때, 나중에 마우스 포인터가 메뉴를 인식하는 범위를 확장하기 위해서 inline의 형태인 <a>를 block의 형태로 만들어 줄 필요가 있다. 이후 padding 속성을 이용해 영역을 확장해 준다.

 

/* 메뉴의 영역이 부족해 너비를 1000px로 확장 */
.con {
  width: 1000px;
}

.logo-bar > div > .logo-bar__logo {
  font-size: 5rem;
}

.menu-bar__menu-box-1 > ul > li > a {
  display: block;
  font-size: 2rem;
  padding: 10px 30px;	/* (위/아래) 10px, (좌/우) 30px 영역 확장 */
}

 

위의 속성들을 적용해 보자

크기-조절-메뉴
아래의 메뉴 요소들은 block의 형태를 가진다

 

마지막으로, 마우스 포인터를 인식하는 기능과 원하는 데코레이션을 추가하면 목표로 하는 1차 메뉴의 모습에 가까워진다. 우선 hover 기능을 통해 마우스 포인터를 인식하면 메뉴 문자열의 색을 변경시키고 밑줄을 추가하고, 로고에 밑줄을 추가해 주겠다. 이때 hover는 가능한 부모의 엘리먼트에 적용을 시켜주는 것이 좋다.

 

/* hover는 가능한 부모의 엘리먼트에 적용해 주는 것이 좋다 */
.menu-bar__menu-box-1 > ul > li:hover > a {
  color: red;
  text-decoration: underline;
}

.logo-bar > div > .logo-bar__logo {
  font-size: 5rem;
  text-decoration: underline;
}

 

위의 속성을 적용해 보자

마우스-인식-메뉴
불필요한 파란/빨간 상자는 제거하고 'Study' 메뉴가 마우스를 인식한 모습

 

 

최종적으로 로고의 가운데 문자열인 'in'을 빨간색으로 변경해 보자. 이를 위해 마크업에서 inline 요소의 태그인 <span>을 통해 미리 로고를 분리해 두었다. 이를 이용하여 nth-of-type 기능을 통해 가운데 문자열인 'in'만을 선택하여 색을 변경시켜 보겠다.

 

/* 3개의 span 문자열 중 2번째 span 문자열만을 선택 */
.logo-bar > div > .logo-bar__logo > span > span:nth-of-type(2) {
  color: red;
}

 

위의 속성을 적용해 보자

완성-메뉴
대부분 완성된 1차 메뉴 바

 

쨔쟌-! 드디어 최초에 목표를 했던 완성본에 가까운 1차 메뉴 바를 만들어 보았다. 하지만 위의 과정을 통한 메뉴 바는 여러 가지의 단점들을 갖고 있다. 겉으로 보기에는 멀쩡하기만 한데 무슨 도대체 무슨 단점이 있다는 걸까? 단점을 눈으로 보기 쉽게 다시 상자를 소환해 보겠다.

 

문제의-메뉴
메뉴마다 다른 영역의 크기 및 메뉴 간의 공백

 

위의 이미지를 보면 알 수 있듯이, 메뉴마다 문자열의 길이가 다르면 메뉴의 영역도 달라지는 문제가 발생한다, 또한 메뉴 사이사이에 알 수 없는 공백들이 존재하기도 하고, 심지어는 con의 너비가 충분하지 못하면 메뉴가 넘쳐서 줄 넘김이 발생하기도 한다. 

그렇다면 위의 단점들을 보완하기 위해서는 어떤 방법들이 있을까? 이는 다음 포스팅에서 inline-grid의 속성을 포함해 다양한 방법으로 이러한 문제점 들을 해결해 보겠다. 

 

[HTML/CSS] 1차 메뉴 바 만들기 : inline-grid를 이용하자

 

[HTML/CSS] 1차 메뉴 바 만들기 : inline-grid를 이용하자

체계적인 메뉴 바를 만들려면 어떻게 해야 할까? 정답은 없지만, 오늘은 유지 및 보수가 편하고, 체계적으로 관리할 수 있는 방법으로 inline-grid 속성을 이용하여 보자. 여기서 inline-grid의 속성을

me-in-journey.com


 

위 단계들의 종합 CSS 코드를 남기며 이번 포스팅을 마친다.

/* 폰트 적용 시작 */
@import url('https://fonts.googleapis.com/css2?family=Indie+Flower&display=swap');

html {
  font-family: 'Indie Flower', cursive;
}
/* 폰트 적용 끝 */

/* 노멀라이즈 시작 */
body, ul, li {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}
/* 노멀라이즈 끝 */

/* 라이브러리 시작 */
/*
  사이트의 모든 요소에 사용될 수 있는 값은 별도로 라이브러리로 정리할 수 있다.
  사이트의 중앙에 위치하도록 결정 
*/
.con {
  margin-left: auto;
  margin-right: auto;
}

/* 사이트의 최소 너비 결정 */
.con-min-width {
  min-width: 1200px;
  padding: 0 10px;
}
/* 라이브러리 끝 */

/* 커스텀 시작 */
/* 해당 값은 해당 요소에서만 사용되는 값이므로 별도로 정리한다 */
.con {
  width: 1000px;
}

/* 메뉴바 시작 */
/* <li>의 display 값은 기본적으로 block의 형태이므로 inline-block 값으로 바꿔준다 */
.menu-bar__menu-box-1 > ul > li {
  display: inline-block;
}

/* inline-block 형태는 text-align을 통해 정렬이 가능하다 */
.menu-bar__menu-box-1 > ul {
  text-align: center;
}

/* <a>와 <span>의 display 값은 기본적으로 inline의 형태이므로 text-align을 통해 정렬이 가능하다 */
.logo-bar > div {
  text-align: center;
}

.logo-bar > div > .logo-bar__logo {
  font-size: 5rem;
  text-decoration: underline;
}

.menu-bar__menu-box-1 > ul > li > a {
  display: block;
  font-size: 2rem;
  padding: 10px 30px;
}

.menu-bar__menu-box-1 > ul > li:hover > a {
  color: red;
  text-decoration: underline;
}

.logo-bar > div > .logo-bar__logo > span > span:nth-of-type(2) {
  color: red;
}
/* 메뉴바 끝 */

/* 커스텀 끝 */

위 단계의 최종 CSS 코드

반응형

댓글