java-school logo

주요 엘리먼트 배치

이번 글은 CSS 포지셔닝을 다룬다. CSS 포지셔닝이란 CSS를 사용하여 웹사이트의 화면을 구성하는 기법을 말한다. 따라서 HTML과 CSS에 대한 기본적인 이해가 필요하다.

화면구성할 때 중요하게 쓰이는 CSS 속성은 float과 margin이다. 여기서 소개하는 방법의 특별한 점은 margin 값에 음수를 사용한다는 데 있다. 이제부터 margin에 음수값을 지정하는 기법을 '음수 마진'이라고 부르겠다. 음수 마진은 화면구성에 필요한 엘리먼트의 수를 최소화할 수 있다.

음수 마진 기법 이해하기

float이 적용된 엘리먼트 다음의 엘리먼트

float이 적용된 엘리먼트 다음의 정상적인 엘리먼트는 float이 적용된 엘리먼트의 존재를 인식하지 못하고 자신의 상자 영역을 확보한다. 하지만 float이 적용된 엘리먼트의 영역은 침범하지 않는다.

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		background-color: #66f;
	}
	#B {
		background-color: #ddd;
	}
</style>

A float:left

clear 프로퍼티

clear 프로퍼티 값은 left, right, both가 있다. 정확한 의미는 다음 예제로 확인하자.

A에 float: left, B에 float: right 프로퍼티 적용한다.

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		background-color: #66f;
	}
	#B {
		float: right;
		width: 100px;
		background-color: #ddd;
	}
	#C {
		background-color: #f66;
	}
</style>

A float:left,B float:right

C에 clear: left; 를 추가한다.

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		background-color: #66f;
	}
	#B {
		float: right;
		width: 100px;
		background-color: #ddd;
	}
	#C {
		clear: left;
		background-color: #f66;
	}
</style>

A float:left,B float:right,C clear:left

C의 clear 프로퍼티를 clear: right; 로 수정한다.

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		background-color: #66f;
	}
	#B {
		float: right;
		width: 100px;
		background-color: #ddd;
	}
	#C {
		clear: right;
		background-color: #f66;
	}
</style>

A float:left,B float:right,C clear:right

C의 clear 프로퍼티를 clear: both; 로 수정한다.

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		background-color: #66f;
	}
	#B {
		float: right;
		width: 100px;
		background-color: #ddd;
	}
	#C {
		clear: both;
		background-color: #f66;
	}
</style>

A float:left,B float:right,C clear:both

음수 마진

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		background-color: #66f;
	}
	#B {
		float: left;
		width: 100px;
		background-color: #ddd;
	}
</style>
A float:left,B float:left

A의 margin-left에 음수값을 적용하면 그 값만큼 A가 왼쪽으로 움직인다. 이때 B도 따라 움직인다.

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		margin-left: -50px;
		background-color: #66f;
	}
	#B {
		float: left;
		width: 100px;
		background-color: #ddd;
	}
</style>
A float:left;margin-left: -50px;,B float:left

A의 margin-right에 음수값을 적용하면 그 값만큼 B를 끌어당긴다. 이때 B의 콘텐츠가 A 콘텐츠를 덮는다.

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		margin-right: -50px;
		background-color: #66f;
	}
	#B {
		float: left;
		width: 100px;
		background-color: #ddd;
	}
</style>
A float:left;margin-right: -50px;,B float:left

3열 포지셔닝

A, B, C 모두는 float: left; 이다. 음수 마진이 적용하지 않는 한 서로 간의 영역을 침범하지 않는다.

<style type="text/css">
	#A {
		float: left;
		width: 100px;
		background-color: #66f;
	}
	#B {
		float: left;
		width: 100px;
		background-color: #ddd;
	}
	#C {
		float: left;
		width: 100px;
		background-color: #f66;
	}
</style>

A float:left;B float:left,C float:left

A의 width를 width: 100%; 로 수정한다.

<style type="text/css">
	#A {
		float: left;
		width: 100%;
		background-color: #66f;
	}
	#B {
		float: left;
		width: 100px;
		background-color: #ddd;
	}
	#C {
		float: left;
		width: 100px;
		background-color: #f66;
	}
</style>

A float:left;width:100%,B float:left,C float:left

A 아래 B와 C가 있는 듯하지만, A, B, C는 나란히 있다고 봐야 한다.

A의 width가 100%이고, 여기에 margin-right: -100%; 를 추가하면 B, C는 A의 왼쪽에 겹치게 된다.

<style type="text/css">
	#A {
		float: left;
		width: 100%;
		margin-right: -100%;
		background-color: #66f;
	}
	#B {
		float: left;
		width: 100px;
		background-color: #ddd;
	}
	#C {
		float: left;
		width: 100px;
		background-color: #f66;
	}
</style>

A float:left;width:100%;margin-right:-100%;,B float:left,C float:left

A의 margin-right: -100%; 를 지우고 B에 margin-left: -100%; 를 추가한다. 그러면 B는 A의 왼쪽에 겹치고 C는 원래 B자리로 이동한다.

<style type="text/css">
	#A {
		float: left;
		width: 100%;
		background-color: #66f;
	}
	#B {
		float: left;
		width: 100px;
		margin-left: -100%;
		background-color: #ddd;
	}
	#C {
		float: left;
		width: 100px;
		background-color: #f66;
	}
</style>

A float:left;width:100%;margin-right:-100%;,B float:left,C float:left

원래 C의 넓이만큼 C에 margin-left: -100px; 를 주면 C는 A의 오른쪽에 겹쳐 위치하게 된다.

<style type="text/css">
	#A {
		float: left;
		width: 100%;
		background-color: #66f;
	}
	#B {
		float: left;
		width: 100px;
		margin-left: -100%;	
		background-color: #ddd;
	}
	#C {
		float: left;
		width: 100px;
		margin-left: -100px;
		background-color: #f66;
	}
</style>

A float:left;width:100%;margin-right:-100%;,B float:left,C float:left

고정크기를 가지는 3열(Column) 레이아웃

고정넓이를 가진 3열 레이아웃을 실습 레이아웃으로 선택했다. 화면은 header, man-menu, sidebar, content, extra, footer로 구성된다.

위에서 언급한 주요 엘리먼트의 크기를 아래와 같이 지정한다.

header

넓이: 1000px 높이: 48px

main-menu

넓이: 1000px 높이: 35px

sidebar

넓이: 175px 높이: 내용에 따라 변함

content

넓이: 720px 높이: 내용에 따라 변함

extra

넓이: 205px 높이: 내용에 따라 변함

footer

넓이: 1000px 높이: 70px

디폴트 HTML 문서 템플릿 작성

아래를 복사하여 사용하고 있는 에디터에 붙여넣는다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="keywords" />
<meta name="Description" content="description" />
<title>title</title>
<link rel="stylesheet" href="css/screen.css" type="text/css" />
</head>
<body>

</body>
</html>

생성한 파일을 index.html 이름으로 도큐먼트 베이스에 저장한다. 이클립스를 사용한다면 DocType(Document Type)별로 제공되는 HTML 문서 템플릿을 선택하여 작성할 수 있다. 이클립스가 제공하는 디폴트 문서 템플릿이 마음에 들지 않는다면 템플릿을 수정할 수도 있다.

이제 페이지의 주요 구성요소를 입력할 차례이다. index.html 파일의 body 엘리먼트 사이에 다음 내용을 붙여넣는다.

<div id="wrap">

	<div id="header">header</div>
	
	<div id="main-menu">main-menu</div>
	
	<div id="container">
		<div id="content">content</div>
	</div>
	
	<div id="sidebar">sidebar</div>
	
	<div id="extra">extra</div>
	
	<div id="footer">footer</div>
	
</div>

위에서 wrap과 container는 설명하지 않은 엘리먼트이다. 이 엘리먼트는 견고한 포지셔닝을 위해서 필요한 여분의 엘리먼트이다. wrap은 문서의 모든 div를 포함한다. container는 여기에서 설명하는 3열을 배치하는 데 필요하다. 되도록 이런 여분의 엘리먼트는 그 수를 최소화해야 한다.

실습하고 있는 포지셔닝에서는 본문을 담는 content가 서브 메뉴를 담는 sidebar보다 먼저 나온다. 웹페이지에서 본문이 가장 중요하고 내용도 자주 바뀌므로 먼저 나오면 유지보수에 유리하다.

도큐먼트 베이스에 css 서브 디렉토리를 만들고 아래 내용으로 screen.css 파일을 만든다.

@CHARSET "UTF-8";
@import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css);
/*** The Essential Code ***/
html, body {
	margin: 0;
	padding: 0;
	background-color: #FFF;
	font-family: "Noto Sans KR", "Liberation Sans", Helvetica, "돋움", dotum, sans-serif;
	font-size: 1em;
}
#wrap {
	margin: 0 auto;
	padding: 0;
	width: 1000px;
}
#header {
	width: 1000px;
	height: 48px;
}
#main-menu {
	width: 1000px;
	height: 35px;
}
#container {
	width: 100%;
}
#content {
        
}
#sidebar {
	width: 175px;
}
#extra {
	width: 205px; 
}
#footer {
	width: 1000px;
	height: 70px;
}
/*** Just for Looks ***/
#header, #footer {
	font-size: large;
	text-align: center;
	background: #999;
}
#main-menu {
	font-size: large;
	text-align: center;
	background: #DAEAAA;
}
#content {
	font-size: large;
	text-align: center;
	background: #DDD;
	height: 100px;
}
#sidebar {
	font-size: large;
	text-align: center;
	background: #66F;
	height: 100px;
}
#extra {
	font-size: large;
	text-align: center;
	background: #F66;
	height: 100px;
}

CSS 문서의 내용은 다음과 같은 형식의 반복이다.

Selector {
	Property(속성): value(속성값);
	..
	.
}

Selector 종류는 Type, Descendant, Class, id, Child, attribute가 있다. 다음은 각 셀렉터의 모습이다.

/* Type Selector */
body {

}
/* Descendant Selector */
ul strong {

}
/* Class Selector */
.redwine {

}
/* id Selector */
#header {

}
/* Child Selector */
body > p {

}
/* attribute Selector */
input[type="text"] {

}

CSS 파일에서 id 셀렉터(Selector)를 정의할 때는 id 앞에 #을 붙인다.
id는 HTML 문서에서 엘리먼트에 유일성을 부여한다.
그러므로 id 값은 HTML 문서에서 단 한 번만 나타나야 하는 엘리먼트에 사용한다.
index.html에서 wrap, header, main-menu, container, content, sidebar, extra, footer가 그런 엘리먼트이다. 반면, Class 셀렉터를 정의할 때는 클래스 이름앞에 .(도트)를 붙인다.
Class는 id와 달리 HTML 문서에서 반복되어 나타날 수 있다.

div.redwinediv .redwine
div.redwine은 HTML 문서에서 <div class="redwine">에 적용된다.
div .redwine은 div 엘리먼트에 포함되어 있는 엘리먼트 중에서 class 속성값이 redwine인 엘리먼트에 적용된다.

지금까지 작성한 페이지를 웹브라우저로 확인한다.
웹서버가 동작하지 않아도 된다. 탐색기에서 작성한 index.html를 더블클릭하여 화면이 아래와 같이 보이는지 테스트한다.

예제보기 1

screen.css 설명

완성 전 코드이지만 지금까지의 CSS 파일의 내용을 살펴보자.
screen.css 파일이 완성되면 화면 구성도 완성된다.
HTML 문서의 내용은 바뀌지 않는다.

html, body

html, body {
	margin: 0;
	padding: 0;
	background-color: #FFF;
	font-family: "Noto Sans KR", "Liberation Sans", Helvetica, "돋움", dotum, sans-serif;
	font-size: 1em;
}

위 설정은 html과 body 엘리먼트 모두에 적용된다.
div와는 달리 html과 body 엘리먼트는 거의 모든 웹브라우저에서 디폴트 마진과 패딩을 가지고 있다.
정밀하게 설정된 화면은 이 값 때문에 화면이 깨질 수 있다.
그래서 대부분 웹디자이너는 html과 body의 마진과 패딩을 0으로 설정한 후 디자인을 시작한다.

#wrap

#wrap {
	margin: 0 auto;
	padding: 0;
	width: 1000px;
}

margin에는 4개의 값이 있어야 한다.
만약 값이 하나만 있다면 top right bottom left에 모두 그 값이 지정된다.
값이 2개이면 첫 번째 값이 top과 bottom에 대한 값이고 두 번째 값이 right와 left에 대한 값이다.
값이 3개라면 순서대로 top right bottom에 대한 값이며 left는 right와 같게 설정된다.
값이 4개라면 순서대로 top right bottom left에 대한 값이다.

margin 프로퍼티의 두 번째 값 auto는 해당 엘리먼트를 중앙에 위치시킨다.
margin: 0 auto; 에서 두 번째 값이 auto이므로 wrap은 좌우를 기준으로 중앙으로 이동한다.
속성값 0에는 단위를 생략한다.
div 엘리먼트의 디폴트 margin과 padding 값은 0이다.
wrap은 HTML 문서 내의 모든 엘리먼트를 담아야 하니 1000px 안에 모든 화면을 넣어야 한다.

CSS 파일에서 /*** Essential Code ***/ 부분이 중요하다.
/*** Just for Looks ***/ 부분은 예제를 웹브라우저로 확인할 때 보기 좋게 하기 위한 설정으로, 프로젝트가 진행되면서 없어질 부분이다.

#container

#container {
	width: 100%;
}

container의 width가 100%로 설정되어 있다.
100%라 함은 container의 콘텐츠가 들어갈 수 있는 최대 넓이이다.
container의 마진과 패딩이 0이고 border 역시 설정되어 있지 않기 때문에 100%는 여기서 wrap과 같은 1000px이다.

#content을 중앙에 배치

/*** The Essential Code ***/의 #content에 다음을 추가한다.

#content {
	margin-left: 175px;
	margin-right: 205px;
}

예제보기 2

#container, #sidebar, #extra에 float: left;

#content 왼쪽에 #sidebar를, #content 오른쪽에 #extra를 배치해 보자. /*** The Essential Code ***/부분에서 아래 부분을 수정한다.

#container {
	float: left;
	width: 100%;
}
#content {
	margin-left: 175px;
	margin-right: 205px;
}
#sidebar {
	float: left;
	width: 175px;
}
#extra {
	float: left;
	width: 205px; 
}
#footer {
	clear: both;
	height: 70px;
}

#content를 감싸고 있는 #container에 float 속성을 적용한다. #container 다음부터 나오는 엘리먼트인 #sidebar, #extra도 역시 float 속성을 적용한다. #container, #sidebar, #extra 모두 float:left; 로 설정했으므로 정상적인 흐름 안의 상자처럼 위아래가 아니라 옆으로 인접해 있다고 생각해야 한다. #footer는 clear 프로퍼티를 both로 설정해서 #footer의 위치를 가장 아래에 있도록 한다.

예제보기 3

#sidebar를 #content 왼쪽에 배치

/*** The Essential Code ***/의 #sidebar에 다음을 추가한다.

#sidebar {
	float: left;
	width: 175px;
	margin-left: -1000px;
}

margin-left: -100%;으로 해도 된다.

예제보기 4

#extra를 #content 오른쪽에 배치

#extra에 다음을 추가한다.

#extra {
	float: left;
	width: 205px;
	margin-left: -205px; 
}
예제보기 5 참고