Home | Experience | Guestbook | Admin | About
 
실제 웹페이지를 디자인하고 또 레이아웃을 설계하다 보면 가장 많은 난제에 부딛히는 문제가 바로 스타일 float, clear, display 속성과 관련된 연관문제이다. 과거 Table개체를 이용하여 모든것을 처리할때, 사실 테이블의 많은 배려로 인해 이러한 레이아웃설계에 대한 고민은 심각하게 하지 않았다. 하지만 테이블이 가지는 페이지로딩등 지나친 남용이 가져다 주는 문제를 알게되면서 테이블이 사용되어야 할 용도와 그외 기본적으로 컨테이너 역할을 수행하는 div 개체가 사용되어야할 롤을 구분하게 되면서 이제 기본적인 레이아웃들도 다 div로 처리한다.
하지만 div로 대변되는 블럭엘리먼트는 수평정렬을 할때 참으로 곤란한 현상을 많이 겪게된다.

우선 블럭엘리먼트는 기본적으로 수직으로 디스플레이된다. (linline은 라인으로 수평이지만 레이아웃을 얘기할때 inline이 수평이라고 논하기는 다소 애매하다.) 그래서 수평으로 레이아웃을 구현하려면 float 속성을 사용해야하는데 이때 지원되는 옵션은 left, right 두가지 뿐이다.
center는 존재하지 않는다. center를 구현하는 방법은 그리어렵지 않다.(position:relative, absolute margin을 이용, 혹은 순수 margin만 이용)
아무튼 leftright 그리고 또 추가적으로 지원되는 초기상태로 되돌리는 clear 그리고 블럭엘리먼트를 시각적으로 표시하는데 필요한 block, inline-block 이러한 조합으로 수평, 수직등 전체 레이아웃을 구성해야 한다.

물론 position을 이용하여 절대적으로 위치를 셋팅하는 방법이 있다.
하지만 positionHTML이 아닌 좀더 프로그래밍적인 좌표개념(Flash, JAVA...)으로 접근하는것으로 position을 이용하여 처리하게되면 부모엘리먼트가 자식의 변경된 영역을 감지하지 못하는 현상이 발생함으로 오버플로우가 발생하는 레이아웃설계를 논할때는 배제해야 한다.
(물론 inline-block으로 강제조정하는 방법이 있지만 IE8에서 치명적인 버그가 발생되어서 그리 추천하고 싶진않다.)

각설하고, 아무튼 이렇게 floatclear를 활용해서 사용하면서 발생하는 한가지 심각한 문제를 우리는 겪게된다.
이문제를 아직 겪지못한 분들도 계시겠지만, 템플릿을 직접 이리저리 고민하고 구성해보다면 반드시 나타나는 현상이다.
아무튼 이러한 시나리오를 기반으로 이문제를 설명하기 위해 다음의 상황을 만들고 여기서 발생하는 연출문제에 대해 이 내용을 다루고 검토해 보려고 한다.
내가 블로그를 운영하고 있다고 가정하자. 그리고 맨처음 사용했던 블로그 레이아웃은 컨텐츠 영역이 왼쪽, 그리고 메뉴구성요소영역이 오른쪽인 노멀한 2단 레이아웃을 사용해왔다.
그리고 당시에 왼쪽 컨텐츠 영역에 여러 포스팅을 남기면서 해당 포스트안에 직접 HTML코딩을 만들어서 사용을 해왔거나 혹은 웹게시물을 위지윅으로 직접가져와서 내용을 구성해왔다. 그런데 이제 시간이 좀 지나서...레이아웃을 이번엔 반대로 바꿔서 사용하기로 했다고 하자.
즉, 이번엔 메뉴구성요소는 왼쪽, 컨텐츠가 보여지는 영역은 오른쪽에 배치된 역시 스탠다드한 2단레이아웃이다.



이 두개의 요소를 가지고 왼쪽에는 메뉴영역, 오른쪽에는 컨텐츠 영역이 나오도록 아래에 레아아웃처리 코드를 간단하게 구성했다.

 F   ? 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div style='width:500px; border:5px solid #000000;'>
	<div style='float:left; width:200px; height:300px; background-color:#333333;  '>
		Menu Area
	</div>
	<div style='margin:0px 0px 0px 200px; background-color:#666666; '>
		Content Area
		<div>
			<div>
				<div>
					<div style='height:100px; background-color:#444444;'>
						Element1
					</div>
					<div style='clear:left; height:100px; background-color:#ff0000;'>
						Element2
					</div>
				</div>
			</div>
		</div>
		</div>
	</div>
</div>


그런데 이게 왠일인가...레이아웃에 적용했더니 중간쯤에 공백이 발생하는 문제가 나타났다.
원인파악을 하기위해 소스를 보니..소스중간에 clear:left라는 스타일속성이 발견되었고, 한군데가 아니라 여기저기 많이 발생되었다. 또 웹에 게시된 기사거리나 이런것들을 통째로 가져온경우도 많아서...HTML를 일일이 수정하기란 여간 벅찬일이 아니다.
왜 전에는 문제가 없던 녀석이 이제와서.... 그 이유는 이전에는 Content AreaHTML배치에서 왼쪽에 우선 존재했기 때문에 이런문제가 밸생하지 않았던 것이다. 사실개인적으로 clear float 이러한 문제는 같은 계층안에서만 발생했으면 좋겠는데... 왜 HTML에서..아니 CSS에서는 영역이 전혀 다른 엘리먼트에 까지 영향을 미치는지 이해를 못하겠다. 나중에라도 그러한 설정이 가능한 css속성이 나와주면 좋겠지만...

MenuArea의 float:left와 ContentArea의 어딘가에 존재할 clear:left가 우연히 만나게 되면서 발생하는 공백문제

아무튼 이문제를 해결하기 위해서는 레이아웃을 수정해야한다.
당장 떠오르는 가장간단한 방법은 바로 왼쪽 메뉴영역의 블럭요소에 position:absolute를 주는 방법이다. 즉, clear의 영향을 전혀 받지 않도록 독립시키는 것이다. 하지만 이건 또다른 문제가 발생한다. 위에서 설명했다 시피... 오버플로우로 변경된 사항을 부모에게 반영해야하는 레이아웃 특성상 왼쪽 메뉴요소를 독립시켜버리면 왼쪽높이값이 컨텐츠요소보다 더 길어졌을때 이때 컷팅되어 높이값이 반영되지 않는다.
(상위 Wrapper입장을 가진 부모엘리먼트에서는 용인될수 없는 문제...)

따라서 이제 이방법은 불가능하고 다음방법을 적용해야한다. 이제 오늘 정말 하고 싶었던 얘기인 inline-block을 이용하여 이문제를 해결하는 방법이다. 인라인블럭과 관련한 장점에 대해서는 이전에도 몇번 포스팅을 했었고 정말 중요한 기능을 하는 표시속성이다. (하지만 IE8에서 이부분과 관련된 이벤트갱신버그가 나타나는데... 아래처리방법은 그 문제도 일단 우회된다.)
바로 ContentArea 요소의 바로 하위에 임의의 div를 추가하고 style속성을 inline-block으로 처리하는것이다. 이렇게되면 이엘리먼트 하위에 등장하는 모든 엘리먼트에서 가지는 float,clear 속성은 바로 자신에게 까지만 영향이 미치도록 흡수된다.
간단한 방법이다. 하지만 좀더 완벽성을 보안하기 위해 width:100%도 추가해준다. 이것은 inline-block이 인라인 우선으로 적용하고 만약 블럭엘리먼트가 있다면 블럭으로 표시하는 방식이라서 width가 보여지는 내용대로 짤리게된다.(물론 상관은없지만..배경색상이나 이런게 적용되었다면) 그래서 width:100%를 추가해서 이문제를 해결하고....
중요한건 언제나 말썽인 IE6에서는 ContentArea 요소에도 동일하게 inline-block을 해줘야 한다는것이다. 따라서 _display:inline-block으로 ie6이하 전용으로 css속성을 적용해서 마무리하면된다.

 F   ? 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div style='width:500px; border:5px solid #000000;'>
	<div style='float:left; width:200px; height:300px; background-color:#333333;  '>
		Menu Area
	</div>
	<div style='margin:0px 0px 0px 200px; background-color:#666666; _display:inline-block; '>
		<div style='display:inline-block; width:100%;'>
		Content Area
		<div>
			<div>
				<div>
					<div style='height:100px; background-color:#444444;'>
						Element1
					</div>
					<div style='clear:left; height:100px; background-color:#ff0000;'>
						Element2
					</div>
				</div>
			</div>
		</div>
		</div>
	</div>
	<div style='clear:left;'></div>
</div>

위의 문제를 해결하기 위해 수정된 최종코드 (검정색배경이 필요한 코드이고 붉은색 배경에 ie6을 위해 추가로 지정된 속성이다.)


완벽히 수정된 레이아웃

아무튼 비슷한 문제로 고민하는 사람들은 꼭 적용해보길 바란다.
EDIT | DELETE
LINK • SUMMARY