[CSS]flex만으로 menu bar 만들기_1
flex
- 웹 페이지에서 공통적인 상단의 Header Menu bar 를 만들 때 사용할 수 있는 방법은 다양하다. table 을 이용하거나 display:inline-block 를 사용하거나 float:left, float:right 그리고 position:relative, position:absolute 를 사용하여 만들 수 있다. 각각의 css들은 작업을 진행 할 때 장 단점이 존재하기 때문에 기초작업을 제대로 하지 않았다면 나중에 수정할 때 상당한 시간이 소요될 수 있다. 이번에는 이 다양한 css 속성중에 javascript를 사용하지 않고 오직 flex 만을 사용해서 다양한 Menu bar 만드는 법을 포스팅 해보겠습니다.
왜 flex 를 사용하는가?
- 왜 flex를 사용하는가…? 퍼블리싱 공부를 한 후 직장을 구할 때 한 회사에서 면접관이 던진 질문도 이러했습니다. “flex는 왜 사용하신거죠?” 사실 이때 뭐라고 정확한 확답은 하지 못했습니다… 다만 개인적으로 css 공부를 할 때 display:inline-block 만 사용해서 홈페이지 모작을 해보고 position 속성만을 사용해서도 작업해보고 했지만 flex를 사용했을 때가 가장 쉽고 편했습니다. 전 이게 flex를 사용하는 가장 큰 이유라고 생각됩니다…
display:inline-block??
- flex를 사용하기 전에 flex를 선언하는 법을 알아보겠습니다. 일반적으로 float이나 display:inlin-block 를 사용 할 때 각각의 엘리먼트에 부가적으로 padding과 line-height, vertical-align 등 일일이 잡아주어야 하는 설정이 많았습니다.
<style>
html,body,a{margin:0; padding:0;}
ul,ol,li,a {padding:0; margin:0; list-style:none; text-decoration:none;}
.menu_1 ul {width:600px; font-size:0; border:1px solid blue;}
.menu_1 ul li {display:inline-block; padding:10px; border:1px solid #222222; text-align:center; font-size:16px; width:calc(490px/5);}
</style>
<nav class="menu_1">
<ul>
<li>menu_1</li>
<li>menu_2</li>
<li>menu_3</li>
<li>menu_4</li>
<li>menu_5</li>
</ul>
</nav>
See the Pen display:inline-block by 김기태 (@kkt9102) on CodePen.
- 먼저 dispaly:inline-block 을 이용하여 menu bar 의 기초를 잡은 모습입니다. display:inline-block 으로 ul > li 요소들을 한줄로 정렬은 했지만 각 li 요소들 사이의 여백이 생깁니다. 그 다음으로 여백을 없애주기 위해 ul 에다 font-size:0 을 주고 그 자식요소인 li에는 다시 font-size:16px 을 주어서 li 요소 안의 텍스트들에게 크기를 지정해줬습니다. 그리고 텍스트들을 가운데로 정렬하기 위해 li 에 text-align:center 속성을 주고 적당한 간격을 주기 위해 padding:10px 도 추가해줍니다. 그리고 각 li 요소들을 일정한 크기로 만들어 주기 위해 width값을 추가해준 모습입니다. width값을 지정해 줄 때 주의할 점이 있는데 border나 padding,margin 이 있다면 각 값들을 계산해서 width값을 주어야 합니다. 위의 코드에선 일부로 ul의 width 값을 600px 로 지정해주고 li의 width:calc(490px/5) 를 사용하여 일괄로 적용해줬습니다.
- 위와같이 display:inline-block 를 사용하여 menu bar 를 만드는 방법은 손이 많이가는 방법입니다. 또한 메뉴의 텍스트 길이가 위의 코드처럼 일정하지 않기 때문에 일부로 width값을 크게 잡거나 각각의 요소들의 크기를 지정해주어야하며 반응형을 고려한다면 더더욱 손이 많이가는 방법이 됩니다.
float:left??
- 다음으로 알아볼 방법은 아직까지도 사용되고 있는 float 입니다.
<style>
html,body,a{margin:0; padding:0;}
ul,ol,li,a {padding:0; margin:0; list-style:none; text-decoration:none;}
.menu_1 ul {width:600px; border:1px solid blue;}
.menu_1 ul li {float:left; padding:10px 30px; border:1px solid #222222; text-align:center; font-size:16px; height:30px; line-height:30px;}
.menu_1 ul li:last-child::after {content:''; clear:both; display:block;}
</style>
<nav class="menu_1">
<ul>
<li>menu_1</li>
<li>menu_2</li>
<li>menu_3</li>
<li>menu_4</li>
<li>menu_5</li>
</ul>
</nav>
See the Pen float by 김기태 (@kkt9102) on CodePen.
- float 을 사용했을 떄는 비교적으로 display:inline-block 를 사용했을 때 보다 간단하게 만들어진 코드를 볼 수 있습니다. 하지만 float 속성도 만약에 menu 자체의 높이를 변경하거나 width를 변경, 혹은 menu item 의 추가 혹은 삭제 시 익숙하지 않은 작업자에게는 시간이 소요되고 css 코드가 길어질 수록 clear:both 를 까먹고 선언해주지 않아 화면에서 파괴되는(?) 모습을 볼 수 있습니다.
position:relative/position:absolute??
- 다음은 position 을 사용하여 menu bar 의 기초를 잡은 코드입니다.
<style>
html,body,a{margin:0; padding:0;}
ul,ol,li,a {padding:0; margin:0; list-style:none; text-decoration:none;}
.menu_1 ul {positon:relative; border:1px solid blue; width:500px; height:55px;}
.menu_1 ul li {position:absolute; padding:10px 0; border:1px solid #222222; text-align:center; font-size:16px; width:100px; height:30px; line-height:30px;}
.menu_1 ul li:first-child {left:0;}
.menu_1 ul li:nth-child(2) {left:100px;}
.menu_1 ul li:nth-child(3) {left:200px;}
.menu_1 ul li:nth-child(4) {left:300px;}
.menu_1 ul li:last-child {left:400px;}
</style>
<nav class="menu_1">
<ul>
<li>menu_1</li>
<li>menu_2</li>
<li>menu_3</li>
<li>menu_4</li>
<li>menu_5</li>
</ul>
</nav>
See the Pen flex by 김기태 (@kkt9102) on CodePen.
- position을 사용하여 menu bar 기초를 잡은 모습입니다. 먼저 li 요소들의 부모인 ul에 position:relative 를 주어 absolute 를 가둘 영역을 지정해주고 width와 height를 지정해줍니다. 그 다음으로 li 요소 전체에 position:absolute 를 준 후 각각 요소들의 위치를 지정해줍니다. position을 사용하여 menu bar 기초를 잡을 때도 이래저래 신경써야 할 부분이 많습니다. 또한 반응형 작업때에는 각 요소들의 위치를 일일이 신경써주어야하는 번거로움도 있습니다.
- 일반적으로 menu bar 를 잡을 때 사용되는 몇가지 방법들을 예시로 보여드렸습니다만 해당 방법들이 무조건 틀리고 flex 가 무조건 정답이지는 않습니다. css는 다양한 방법으로 접근할 수 있기 때문입니다..
flex
- 이번에는 이번 포스팅의 목적인 flex 를 사용하여 menu bar 기초를 잡은 코드를 보겠습니다.
<style>
html,body,a{margin:0; padding:0;}
ul,ol,li,a {padding:0; margin:0; list-style:none; text-decoration:none;}
.menu_1 ul {display:flex; align-items:center; border:1px solid blue; width:500px;}
.menu_1 ul li {padding:10px 0; border:1px solid #222222; text-align:center; font-size:16px; flex-basis:100px;}
</style>
<nav class="menu_1">
<ul>
<li>menu_1</li>
<li>menu_2</li>
<li>menu_3</li>
<li>menu_4</li>
<li>menu_5</li>
</ul>
</nav>
See the Pen flex by 김기태 (@kkt9102) on CodePen.
- flex를 사용하여 menu bar 의 기초를 잡은 모습입니다. css 코드가 다른 방법에 비해 많이 줄은 모습입니다. 또 다른 방법과는 다르게 li 요소들에게 css 를 지정해주는 것이 아닌 부모 요소인 ul 에 display 속성을 지정해주는 것이 다릅니다.
flex의 장점
- display:flex 를 사용하면 몇가지 장점이 있는데 먼저 flex 를 선언한 요소의 자식들은 자동적으로 부모의 넓이에 맞춰서 정렬이 된다는 점 입니다.
- 위와 같이 ul에 display:flex 를 속성을 지정해준 형태입니다. 이와같이 flex 는 부모의 넓이 안에서 자식 요소들을 한줄로 나열시켜줍니다.
justify-content를 사용하여 정렬하기
- flex 를 사용하여 자식 요소들을 한줄로 만들어 준 후 다음으로는 자식 요소들을 정렬하는 방법입니다. 이 떄 쓰이는 css는 justify-content 입니다.
justify-content:center; /* 자식 요소들을 가운데로 정렬 */
justify-content:flex-start; /* 자식 요소들을 부모의 left 에 정렬 */
justify-content:flex-end; /* 자식 요소들을 부모의 right 에 정렬 */
justify-content:space-around; /* 자식 요소들의 좌,우 간격을 동일하게 배치 */
justify-content:space-between; /* 자식 요소들 중 첫번째와 마지막 요소를 부모의 left와 right에 붙인 후 나머지 여백을 동일하게 배치*/
justify-content:space-evenly; /* 자식 요소들을 부모의 넓이 안에서 동일한 간격으로 배치 */
- justify-content:center
- justify-content:flex-start;
- justify-content:flex-end
- justify-content:space-around
- justify-content:space-between
- justify-content:space-evenly
- 위와같이 flex를 사용하여 자식요소들을 정렬할 수 있습니다. 단 주의점은 space-evenly의 경우 IE에서는 지원하지 않기 때문에 주의가 필요합니다.
Comments