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

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

by me_in_sk 2023. 5. 14.
반응형

 

 

체계적인 메뉴 바를 만들려면 어떻게 해야 할까? 정답은 없지만, 오늘은 유지 및 보수가 편하고, 체계적으로 관리할 수 있는 방법으로 inline-grid 속성을 이용하여 보자. 여기서 inline-grid의 속성을 그대로 사용해도 좋지만, 오늘은 연습을 위해 좀 더 가시적으로 이해하며 코딩하기 위해서 inline-grid 속성을 따로 만들어서 사용하여 보자. 완성된 코드는 포스팅의 마지막에 정리해 두었다.

 

 

이번 포스팅은 지난 포스팅에서 이어지는 내용이니 아래의 지난 포스팅을 참고해 주기 바란다.

 

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

 

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

오늘은 기초적인 1차 메뉴를 만들어 보자. 이번에 만들 메뉴는 마우스를 인식하면 메뉴 요소가 반응을 하는 기능을 포함한 깔끔한 느낌의 메뉴이다. 메뉴 바는 다양한 부류의 정보를 담고 있는

me-in-journey.com


문제점이-드러난-메뉴
지난 포스팅에서 문제가 된 메뉴 바

 

위와 같이 만든 메뉴의 문제점은 크게 3가지였다.

 

  • 메뉴마다 사이사이에 불필요한 공백이 생긴다.
  • 메뉴의 영역이 문자열의 길이에 영향을 받아 넓이가 달라진다.
  • 메뉴의 넓이가 변함에 따라 정해진 너비를 벗어나 넘칠 수 있다.

 

 

위의 문제를 해결하려면 어떻게 해야 할까? 이를 위해서는 우선 문제의 원인을 알아볼 필요가 있다. 먼저 메뉴 사이사이에 공백이 생기는 이유를 알아보자. 아래는 메뉴의 항목들이 HTML에서 나열되어있는 모습이다. 사실 아래의 코드에는 나오지 않지만, 우리는 메뉴 바를 가로로 구성하기 위해 <li>태그를 inline-block의 형태로 바꿔주었다. 이 때문에 block의 형태였으면 빈틈없이 채워졌을 공간에 white-space에 의해 공백 문자가 생긴 것이다.

 

<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>

 

 

그러면 다시 <li>태그를 block 값으로 바꿔줘야 하는 걸까? 만약 그렇다면 메뉴들의 항목을 가로로 정렬할 수 없을 것이다. 다행스럽게도 위의 문제는 아래의 코드처럼 주석을 통하여 white-space가 생길 틈을 주지 않는 것으로 문자 간에 생기는 공백 문자를 제거하는 것만으로도 해결할 수 있었다. 

 

<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>

 

위의 코드를 적용한 모습

공백-제거-메뉴
공백을 주석 처리를 통해 제거한 메뉴

 

그러면 첫 번째 문제는 해결한 걸까? 물론 아래와 같이 해결한다면 간단하게 해결을 할 수 있지만, 메뉴의 항목이 10개가 된다면? 20개가 된다면? 그 수가 적다면 문제가 없지만, 그게 아니라면 일일이 공백에 주석을 넣어주는 것은 비효율적인 해결 방법이 될 수 있다. 이를 해결하는 것은 공백 문자의 이름에 있다. 공백 문자도 엄연한 문자라는 것. 즉, 아래의 코드와 같이 글자의 크기를 0으로 설정해 준다면 공백 문자로 인해 생기는 공백을 0으로 만들 수 있다.

/* 공백 문자가 생기는 <li>들의 부모 엘리먼트에 작업을 해준다. */
.inline-grid {
  font-size: 0;
}

 

 

계속해서 두 번째 문제인 문자열의 길이에 따라 넓이가 달라지는 이유에 대해 알아보자.

.menu-bar__menu-box-1 > ul > li > a {
  display: block;
  font-size: 1.9rem;
  font-weight: bold;
  padding: 10px 0;		/* 위와 아래로만 padding이 걸려있다. ∴너비에 영향을 주지 않는다. */
  text-align: center;
}

 

위의 코드는 <a>의 영역을 구성하는 요소들이다. 너비에 영향을 주지 않고 있는 padding 속성을 제외한다면, 영역의 넓이를 결정하는 속성이 글자의 크기뿐이고, 나머지 넓이는 block의 특징에 의해 공이 자동으로 채워지는 구조이다. 결국 글자의 크기 하나하나가 넓이에 영향을 미치기 때문에 글자의 수가 넓이에 영향을 주게 되는 것이다. 이를 해결하기 위해서 필요한 방법은 간단하다. 문자열을 담고 있는 <a> 엘리먼트의 부모 엘리먼트에 넓이를 지정한 다음 그 안에 <a>를 넣어주기만 하면 된다. 이는 마지막 문제였던, 정해진 너비를 벗어나는 문제도 해결할 수 있게 된다. 부모가 고정된 너비의 한계를 정해 줌으로써 자식 엘리먼트의 이탈을 방지할 수 있게 되는 것이다. 이번 포스팅에서는 이를 inline-grid의 개념을 이용하여 해결해 보려 한다.

 

.inline-grid > * {
  font-size: 1rem;
  display: inline-block;
  vertical-align: top;
  box-sizing: border-box;
}

/* 파란 상자로 부모 엘리먼트의 크기 확인 */
.menu-bar__menu-box-1 > .inline-grid {
  border: 10px solid blue;
}

.menu-bar__menu-box-1 > ul > li {
  width: calc(100% / 7);	/* 메뉴가 7개이니 전체 너비를 7로 나눈다 */
}

 

위의 속성을 적용해 보자

정돈한-메뉴
부모 엘리먼트인 inline-grid의 내부를 꽉 채운 메뉴들

 

쨔쟌-! 이번에는 정말로 정돈된 모습의 메뉴를 만들 수 있었다. 메뉴 항목들의 글자 수가 달라도, 총 너비를 항목 수만큼 나눠서 너비를 분배했기 때문에 모든 메뉴의 넓이가 동일하며, 너비가 지정되어 있어 항목이 넘치는 일도 방지할 수 있다. 이로써 두 번째 문제와 세 번째 문제도 해결이 되는 것과 동시에, 지정된 너비를 모두 활용하고 있는 모습을 볼 수 있다. 

 

마지막으로 불필요한 요소들을 제거하고, 메뉴의 너비를 변수로 통제하는 등의 다듬는 작업을 해주면 원하는 메뉴 바를 만들 수 있게 된다. 이에 완성된 메뉴 바의 이미지와 코드들을 남기며 이번 포스팅을 마치도록 하겠다. 다음은 드롭다운 기능을 수행하는 새로운 메뉴바에 대하여 포스팅하는 시간을 가지도록 하겠다.

메뉴-완성
완성된 메뉴 바의 모습

 

HTML

<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>

 

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;
}

.block {
  display: block;
}

.text-align-center {
  text-align: center;
}

.inline-grid {
  font-size: 0;
}

.inline-grid > * {
  font-size: 1rem;
  display: inline-block;
  vertical-align: top;
  box-sizing: border-box;
}
/* 라이브러리 끝 */

/* 커스텀 시작 */
:root {
  --site-width: 1200px;
}

.con-min-width {
  min-width: var(--site-width);
  padding: 0 10px;
}

.con {
  width: var(--site-width);
}

/* 로고바 시작 */
.logo-bar > .con {
  padding-top: 60px;
}

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

.logo-bar__logo > span:last-child > span:nth-child(2) {
  color: red;
}
/* 로고바 끝 */

/* 메뉴바 시작 */
.menu-bar > .con {
  padding-top: 60px;
}

.menu-bar__menu-box-1 > ul > li {
  width: calc(100% / 7);
}

.menu-bar__menu-box-1 > ul > li > a {
  font-size: 1.9rem;
  font-weight: bold;
  padding: 10px 0;
  text-align: center;
}

.menu-bar__menu-box-1 > ul > li:hover > a {
  color: red;
  text-decoration: underline;
}
/* 메뉴바 끝 */

/* 커스텀 끝 */
반응형

댓글