본문으로 바로 이동 페이지 설정으로 이동 메뉴로 이동
페이지 설정
  • 어떠한 의견도 좋습니다. 웨버스터디가 더 나은 모습이 되도록 의견을 보내주세요.

다단 레이아웃 만들기

최초 작성일
최종 수정일
이번 시간에는...
float 속성을 이용해, 실제로 CSS 다단 레이아웃을 만들어 봅니다. 이를 통해서 기본 HTML 문서를 제작할 때, 기본 레이아웃을 어떻게 잡는지 알아보고, 중급 쳅터에서 다뤘던 스타일 속성들을 다시 한 번 살펴 봅니다.

이번 시간에는 이 CSS 중급 챕터의 마지막으로, 이번 챕터에서 다룬 것을 토대로 다단 레이아웃을 만들어 보도록 하겠습니다.

2단으로 구성된 레이아웃 페이지
만들고자하는 다단 레이아웃 예시

이와 같은 레이아웃을 만들어 볼 것입니다. 만들기 전에 이 레이아웃의 구역을 어떻게 나눌 것인지 먼저 그려보도록 하죠.

레이아웃의 구조도, 헤더와 푸터, 콘테이너를 나눈뒤, 콘테이너 안에서 네비와 콘텐트를 다시 나눔
만들고자하는 다단 레이아웃의 기본 구조

네 일단 전체를 frame으로 감쌌고요, 그 다음으로 가로로 가장 크게 세 가지 구역 (header, container, footer)로 나눴습니다. 그리고 그 중 container 안에 두 개의 구역 (nav, content)로 나눈 것을 알 수 있습니다. 왜 처음부터 네 개의 구역(header, nav, content, footer)으로 나누지 않고, 굳이 container로 감쌌을까요?

그것은 nav와 content가 float:left로 배치될 것이기 때문입니다. 사실 꼭 container로 감싸지 않고 바로 float:left 처리를 해도 저 레이아웃을 만들 수 있습니다. 하지만, float처리가 된 요소들은 한번 감싸주는 것이 추후에 관리하거나 할 때 좋습니다. 나중에 이와 같이 감싸서 정리하지 않은 채 float 속성을 여러 번 중첩되게 쓰다 보면, 의도치 않은 깨짐을 맞닥뜨리게 될 것입니다. 특히 나중에 위치를 옮기거나 다른 요소를 추가해야 하는 등의 수정이 필요할 때, 정리되지 않은 float은 작업하기 어렵습니다.

이를 토대로 HTML을 마크 업 해보도록 하죠.

일단 모두 아까 구역을 나눈 이름으로 클래스 이름을 주었고, 메뉴는 ul,li로 처리했습니다. 보통 네비게이션 메뉴는 ul로 처리합니다. 또한, 페이지의 로고를 의미 없는 요소인 div로 처리했는데요, 보통 이 회사명칭이 들어간 로고를 h1 요소로 하기도 합니다. 사실 페이지의 가장 큰 제목을 회사명칭으로 할 지는 의견이 분분합니다. 다만 회사 로고를 h1 요소로 표현하든 안하든, 본문의 대제목은 꼭 h1 요소를 쓰는 것이 좋습니다. 대부분 회사 로고가 본문의 제목보다 먼저 나오기 때문에 문제가 되지 않습니다만, 혹시라도 본문 제목보다 나중에 오면서 h1을 사용한다면, 문서 개요에 영향을 미칠 수 있으니, 주의 하시기 바랍니다.

그렇다면, 이제부터 요소 하나하나 스타일을 주도록 하겠습니다. 이번 페이지에선 특별히 초기화 스타일은 주지 않도록 하고, body 부터 스타일을 적용하도록 하죠.

일단 body 요소에 글자 서체나 크기, 줄 높이를 지정함으로써, 페이지 전체의 글씨 스타일을 적용하였습니다. (대부분의 요소들이 font 속성은 상속된다는 것을 알고 계실 것입니다.) 그 다음 div.frame에 너비를 800px로 주고, 테두리를 준 뒤, margin: 0 auto를 이용해서 가운데 정렬을 시켰습니다.

그 다음으로 header 영역을 주겠습니다.

div.header에 안 여백과 배경을 주고, 로고를 가운데 정렬하기 위해 text-align: center를 주었습니다. 그리고 margin-bottom으로 아래 div.container와의 간격을 주었고요.

그 다음 div.logo에 준 스타일을 보면, 일단 글씨 크기와 굵기, 색상과 배경을 주었습니다. 그리고 원래 블록요소이기 때문에 배경색이 한 행 전체에 들어가게 됩니다. 그렇기 때문에 인라인과 블록의 속성을 가진 display: inline-block으로 적용시켜 안에 여백까지 주었습니다. (물론 IE7 이하 브라우저를 위해서는 핵이나, 전용 주석을 통해서 추가적인 처리를 해야 합니다.)

그 다음은 div.container입니다. 내부의 div.nav, div.content가 모두 float 처리될 것이기 때문에, overflow:hidden을 통해서 float으로 띄어진 요소를 포함합니다.

이제 div.nav 요소에 스타일을 주도록 하죠.

보면 일단 div.nav 요소를 float:left 처리로 왼쪽으로 띄웠습니다. 그리고 너비와 배경, 글자 색을 주었고, 오른쪽에 위치할 div.content와의 간격을 위해서 margin-right: 50px를 주었습니다.

그 다음 ul.nav-list에 준 스타일을 보면, 가장 먼저 기본 리스트 블릿을 list-style로 없애버렸고, 기본적으로 들어가는 내부, 외부 여백을 조정했습니다. 여기서 보면 padding의 좌우 여백을 0으로 처리했는데요, 이는 a.nav-link 요소의 영역을 좌우 끝까지 붙이기 위함입니다.

그 다음으로 li.nav-item에 외부 여백을 줘서 서로간의 간격을 만들어 줬고요, a.nav-link에 준 스타일을 보면, 원래 인라인 요소를 display:block을 통해서 블록 요소로 만들어 준 것을 알 수 있습니다. 이를 통해서 단지 글자 영역이 아닌, 글자가 위치한 행에 마우스를 올릴 경우에도 링크를 클릭할 수 있습니다. 그리고 아까 ul.nav-list에서 없앤 내부 여백을 a.nav-link에서 처리한 것을 알 수 있습니다.

마지막으로 가상 클래스 선택자 :hover를 통해서 마우스가 해당 메뉴 오버 시에 배경이 파란색으로 변하도록 만들었습니다. 이제 다음으로 div.content의 스타일을 살펴보도록 하죠.

div.content 역시 float;left처리를 하고, 가로 너비를 네비게이션과 나란히 있을 때, 딱 맞을 수 있도록 600px를 주었습니다. 본문 내용에 대한 스타일은 강의 분량이 너무 길어질 수 있으니 굳이 넣진 않도록 하겠습니다.

마지막으로 간단하게 div.footer의 스타일을 주겠습니다.

일단, 이렇게 까지 작업을 하게 되면 대부분의 레이아웃 배치는 적용이 되었습니다. 어쩌면 이것 만으로도 충분히 작업이 다 되었다고도 할 수 있겠습니다.

하지만, 지금까지 작업된 레이아웃과 목표의 이미지와는 조금 차이가 있습니다. 네, 바로 메뉴 부분의 검은 배경이 본문 끝까지 오질 않습니다. 그저, 자신의 내용이 끝나는 부분까지만 배경이 적용되어 있습니다.

왼쪽 네비게이션 영역의 높이값만큼만 배경이 지정됨
배경이 끝까지 내려오지 않는 왼쪽 네비게이션

사실, 이는 매우 당연합니다. float된 요소는 그저 자신의 컨텐츠 만큼의 높이를 가지고 있을 뿐입니다. 그렇다면 이를 구현하기 위해서 메뉴 영역에 높이 값을 주면 어떨까요? 물론 해당 높이 값 만큼 메뉴 영역이 높이를 가질 수 있을 것입니다. 하지만, 우측 본문의 내용의 길이는 정해져 있지 않습니다. 이는 좋은 방법이 아닙니다.

또 다른 방법으로는 무엇이 있을 까요? 또 한가지는 float이 아닌 display:table을 이용한 방법입니다. 메뉴와 본문을 감싸던 div.containerdisplay:table을 주고, 메뉴와 본문 영역을 각각 display:table-cell을 주도록 하는 것 입니다. 다음과 같이요.

이렇게 하면 메뉴와 본문, 두 요소는 나란히 같은 높이 값을 가지게 됩니다. 하지만, 이 CSS 속성은 IE8 이상부터만 지원하기 때문에, IE7 이하에서는 사용할 수 없습니다. 그리고 또한 테이블 방식의 레이아웃은 종종 의외의 버그를 내기도 합니다. 특히 의외의 렌더링이 브라우저마다 달리 나타날 가능성이 있기 때문에, 권장하고 싶은 방법은 아닙니다.

대신 다른 방법들을 좀 더 다뤄보죠. 또 하나의 방법은 조금 복잡할 수 있습니다. 일단 전체 영역(div.container)에 검은 배경을 주고, 본문 영역(div.content)에 하얀 배경을 다시 주는 방법입니다.

이렇게 되면 감싸는 전체 영역(div.container)는 본문 영역만큼의 크기를 가질 수 있기 때문에, 마치 메뉴가 본문만큼 늘어나 있는 것과 같은 착시를 불러 일으킬 수 있습니다.

하지만, 이 역시도 치명적인 단점이 있습니다. 바로 전체 감싸는 영역은 메뉴나 본문, 둘 중 하나 더 기다란 요소만큼의 높이를 갖게 됩니다. 즉, 보통 본문이 길 때에는 본문 영역만큼의 높이를 가지겠지만, 만에 하나 본문이 메뉴보다 짧아질 경우 메뉴 만큼의 높이를 가지게 되고, 이 착시의 민 낯이 드러나게 됩니다. 본문 아래의 공백이 검정색으로 노출되는 것이죠. 이 역시 좋은 방법이 아님을 알 수 있습니다.

콘텐츠가 짧아지면서 콘테이너에 적용된 배경색이 깨져보이듯 노출됩니다
배경색의 민낯

마지막으로, 이에 대해 가장 권장하는 방법을 말씀 드리겠습니다. 이 방법은 의외로 간단합니다. 바로 배경 이미지를 이용한 방법입니다. 메뉴의 너비만큼의 크기를 가진 높이 1px 짜리 배경색과 같은 검정 이미지를 만듭니다. 지금 메뉴 너비가 150px이니 150px x 1px 짜리 이미지가 되겠죠.

너비 150픽셀, 높이 1픽셀의 배경샘플
배경 이미지 (높이가 1px 이라 잘 보이진 않습니다)

그 이미지를 감싸는 전체 영역(div.container)의 배경 이미지로 줍니다. 그리고 이미지 반복을 세로로만 반복 시킵니다.

이러면 끝입니다. 아주 간단한 방법이 되겠습니다. 물론 실제 메뉴 영역이 전체영역처럼 늘어난 것은 아닙니다. 그냥 배경 이미지로 그렇게만 보이게 할 뿐입니다.

물론 이 방법이 완전한 방법이라 할 순 없습니다. 일단 색상이나 너비의 수정 등은 CSS 코드 수정이 아닌, 이미지를 수정해야 합니다. 또한 혹시라도 메뉴의 너비를 가변적으로 하고자 하면 이 방법은 쓸 수 없는 방법입니다. 하지만, 보통 레이아웃을 잡으면서, 메뉴의 너비가 가변적인 일은 거의 없습니다. 이 방법은 IE7 이하의 구형 브라우저에서도 잘 나타나기 때문에, 대부분의 업계에서도 많이 사용하는 방법입니다.

레이아웃을 잡는데 어떠한 방법이 정답이다라고 할 순 없습니다. 이번 시간에 알아본 방법은 이러한 레이아웃에 대한 방법을 알아본 것이고, 이 역시 더 좋은 다른 방법이 있을 수 있습니다.

다만, CSS 스타일을 적용할 때, 여러 가지 방법이 있다는 것을 알고, 그러한 방법들에 문제점은 없는지, 또는 더 좋은 방법은 없는지에 대해 고민해보는 것은 여러 분이 앞으로 웹을 제작할 때 매우 중요한 자세입니다.

이번 시간에 다룬 내용은 아래에 예시로 넣어놨습니다. 혹시 이해가 안된 부분이 있었다면, 한번 예시 페이지를 직접 CSS 더비깅 해보시는 것도 좋은 공부가 될 것입니다. 그리고 이것으로 이번 'CSS 중급' 챕터는 마무리를 하겠습니다. 이제 이번 챕터까지의 내용 만으로도, 여러분들은 웬만한 웹 페이지들은 제작할 수 있게 되었습니다. 이제 다음의 'HTML, CSS 고급' 과정을 통해서, 아직 배우지 않았던 선택자들, 폼 요소, 그리고 레이어 스타일 같은 것들을 다루도록 하겠습니다.

다단 레이아웃 예시
/attach/demo/intro-first.html
모바일의 경우 새창열기로 확인 가능합니다.
새창열기

이 글이 유용하셨다면 친구들에게 공유 해주세요.