본문으로 바로가기

float 레이아웃 문제 해결

category 웹코딩/CSS 2013. 12. 13. 19:43

float를 이용한 레이아웃을 작성할때, 부모 요소가 자식 요소의 크기를 반영하지 못하는 문제가 생깁니다. float가 적용된 요소는 문서의 흐름에서 제외되어 둥둥 떠 다니는 레이어처럼 떠있게 되는데 float 되지 않은 다른 블럭 요소들이 다른 층에 떠 있게 되어서 자식의 높이가 부모에게 전달되지 못하게 되는 것입니다.

FLOAT 레이아웃

일단 float 레이아웃의 기본적인 형태를 예로 들어 본다.

header
nav
content


위에서 전체를 감싸는 컨테이너가 자식 요소들의 높이를 반영하지 못하고 자신의 높이만큼만 보여주고 있다.


아래가 원래 의도한 레이아웃으로 부모 컨테이너가 자식 요소들을 제대로 반영하고 있다.

header
nav
content

기본 구조는 아래와 같다.

<style>
.pull-left { float: left }
.pull-right { float: right }
</style>

<div class="container">
  <div>header</div>
  <div class="pull-left">nav</div>
  <div class="pull-right">content</div>
</div>

이 문제를 해결하는 방법을 아래에서 설명하고 있으며 자신의 상황에 맞게 이를 잘 활용하도록 하자.

부모 요소에 float 속성을 부여

.container { float: left }

float된 요소들끼리는 서로 어울리기 때문에 부모 요소에도 flaot 속성을 부여 한다. 하지만 이 방법은 결국 현재 문서의 모든 블럭에 불필요한 float 속성을 부여하도록 만든다. 왜냐하면 모든 블럭들이 같은 층에 떠 있어야만 서로의 영역을 침범하지 않기 때문입니다. 만약 하나의 블럭이라도 float 되지 않았다면 이 상자는 float된 다른 상자와 겹칠 것이므로 이런 방법은 절대로 권장하지 않는다.

부모 요소에 overflow 속성을 부여

.container { overflow: hidden }

overflow 속성을 변경 한다. 모든 요소는 overflow 속성의 기본 값을 지니고 있는데 기본 값은 visible 이다. 이 값을 visible이 아닌 다른 값으로 변경해 주면 된다. 다른 값으로는 auto, scroll, hidden 이 있다. 이 방법은 자식 블럭이 부모 블럭을 넘칠 때 스크롤이 발생하거나 숨김 현상이 발생하기 때문에 가장 안전한 방법은 아니다. 자식 요소 가운데 부모 상자의 바깥쪽으로 펼쳐지는 레이어 .layer { position:absolute } 를 넣어야 한다면 절대로 이 방법을 사용할 수 없을 것이다. 향후 이런 레이어를 띄우는 상황이 절대로 발생하지 않으리라고 누구도 장담할 수는 없기 때문에 이 방법 역시 권장하는 방법은 아니다.

빈 요소에 clear 속성을 부여

.clear { clear: both }

clear 속성은 float된 요소의 흐름을 끊고 자기 자신은 float된 요소로부터 줄 바꿈 처리하는 속성이다. float된 요소의 아래쪽에 내용 없는 블럭 <div class="clear"></div>을 하나 추가한 다음 clear 속성을 추가하면 비로소 float된 자식 요소들의 높이가 부모에게 반영이 되는데 clear 속성의 값으로는 left, right, both가 있다. 이 방법은 아무 의미 없는 빈 요소를 추가해야 하기 때문에 역시 권장하는 방법은 아니다.

가상 선택자 :after 를 사용하는 방법

.container:after { content:""; clear:both; display:block; }

가상 선택자란 실제로는 존재하지 않는 요소나 특수한 상황에서만 발생하는 동적인 요소를 CSS 명령으로 제어하는 기법이다. 가상 선택자는 다시 '가상 클래스 선택자'와 '가상 요소 선택자'로 구분할 수 있는데, 가상 클래스 선택자(:link, :visited, :hover, :active, :focus, :first-child)는 특정 요소에 마치 동적으로 class를 부여한 것과 같은 이치로 이용할 수 있다. 가상 요소 선택자(:first-line, :first-letter, :before, :after)는 실제로 존재하지 않는 요소를 마치 존재하는 것처럼 이용하는 기법이다. :after 라는 가상 요소 선택자는 content 라는 속성을 이용해서 .container 블럭이 끝나기 직전 content 속성의 값 "*" 을 화면에 출력할 수 있다. 이렇게 생성된 요소에 clear:both 속성을 부여하면 자식의 높이를 부모에게 전달할 수 있는데 실제로 HTML 코드에는 빈 요소가 존재하지 않기 때문에 가장 이상적인 방법이라고 할 수 있다.

IE 6~7 브라우저는 가상 요소 선택자를 지원하지 않는다.

IE 전용 확장 zoom 속성을 이용하여 IE 6~7 문제 해결

.container { *zoom: 1; }

IE 6~7 브라우저는 가상 요소 선택자 :after를 지원하지 않지만 CSS hack을 이용하여 자식의 높이를 부모에게 전달 할 수 있다. zoom:1 속성은 IE 전용 확장 속성으로써 본래의 존재 목적은 IE 브라우저에서 웹 문서를 자유롭게 'zoom in / zoom out' 하는 것이다. 이 속성을 부여하게 되면 요소는 IE 브라우저에서만 존재하는 hasLayout 이라는 개념의 속성을 갖게 되는데 이 속성이 IE 브라우저에서 float 문제를 해결하는 trigger로 작용을 하고 다른 브라우저에는 영향을 미치지 않게 된다. zoom 속성 앞에 '*'을 붙이는 이유는 현재는 존재하지 않지만 향후 zoom과 동일한 이름을 지닌 속성이 표준으로 등장하거나 다른 웹 브라우저에서 CSS 확장 속성으로 등장하더라도 이 코드를 무시하도록 만드는 'hack'을 사용한 것입니다. 속성 앞에 공백 없이 '*'을 붙이면 해당 속성은 IE 6~7 브라우저에서만 작용하게 된다.

:after를 사용하고 IE6~7의 문제를 해결하는 것은 아래와 같다.

.container { *zoom:1; }
.container:after { content: ""; clear: both; display: block; }

출처 : 유니버설 디자인을 위한 실전 UI(HTML/CSS)개발 가이드

부트스트랩(Bootstrap) clearfix

부트스트랩에서 제공하는 clearfix는 IE8 이상에서 무리없이 작동한다. 최근에는 IE6~7을 고려치 않으니 이 방법을 쓰는것도 나쁘지 않으며 위에서 소개한 코드와 별반 다를게 없다.

.clearfix:before,.clearfix:after { content: " "; display: table; }
.clearfix:after { clear:both; }

float된 자식을 감싸는 부모 요소에 .clearfix를 부여한다.


'웹코딩 > CSS' 카테고리의 다른 글

Placeholder 포커스시 감추기  (3) 2015.05.23
CSS 가운데(중앙) 정렬  (20) 2015.04.15
전체화면 배경고정 - FullScreenBackground  (20) 2013.01.02
opacity 와 rgba (Transparent)  (4) 2012.12.31
웹폰트(@font-face) 온라인 서비스  (1) 2012.12.30