float을 clear하는 4가지 방법.
CSS 속성 가운데 float 속성은 자기 자신의 위치를 주변의 콘텐츠로부터 상대적으로 배치하는 속성입니다. float은 사전적 의미로 ‘뜨다, 띄우다, 뜨는 물건, 부유물’ 이라는 의미가 담겨져 있습니다. float은 높이가 가변적인 다단 컬럼 형태의 CSS 레이아웃을 위하여 반드시 요구되는 속성으로서 처음 CSS 배치기법을 익힐 때 가장 이해하기 어려운 속성중의 하나 입니다. float 속성이 부여된 엘리먼트는 좌측이나 우측으로 배치되면서 주변 콘텐츠의 배치에도 영향을 미친다는 사실은 어렵지 않게 학습되나 ‘float 된 엘리먼트가 부모 엘리먼트의 높이에 영향을 주지 않는다는 사실’은 몇 번의 경험 또는 선배들의 조언으로 깨닫게 되는 것이지요.
오늘은 float 속성을 이해하고 다단 컬럼형 레이아웃을 시도할 때 주변 엘리먼트들이 원하는 상태로 배치될 수 있도록 이것에 대응하거나 clear 하는 방법에 대하여 공유하고자 합니다. clear 속성은 float이 더이상 주변 엘리먼트의 배치에 영향을 미치지 않도록 해제시키는 속성입니다. 만약 Internet Explorer 브라우저를 사용하여 학습을 시도하신다면 일단 멈추시고 표준계열 브라우저에서 먼저 시도해 보세요. CSS 표준 렌더링을 엄격하게 준수하는 Opera와 Safari를 권장합니다. Internet Explorer와 Firefox 브라우저는 float, clear 속성에 관한 버그를 포함하고 있으므로 float과 clear의 표준 렌더링이 어떻게 구현되는지를 학습할 때 도움이 되지 않습니다. 하지만 버그를 해결하는 방법도 소개되어 있으니 안심하세요.
오늘 글의 핵심은 ‘float된 자식 엘리먼트의 높이를 부모 엘리먼트에 반영하도록 대응하는 방법’ 이라고 한마디로 설명할 수 있겠습니다. 부모 떠난 자식을 다시 부모의 품 안으로 돌아오도록 하려면 어떻게 해야 하는지 한번 살펴 보시죠.
float에 아무런 대응도 하지 않은 상태
#container는 부모 엘리먼트이며 #lnb와 #content는 자식 엘리먼트로서 현재 float된 상태 입니다. 아래 예제는 float에 아무런 대응을 하지 않으면 자식 엘리먼트가 부모 엘리먼트의 높이에 영향을 주지 않는다는 사실을 보여주고 있습니다. #container의 높이가 자식 엘리먼트의 높이를 반영하지 않고 있다는 사실에 주목해 주세요. float에 아무런 대응도 하지 않은 상태의 예제가 준비되어 있습니다.

float에 float으로 대응하는 방법
자식 엘리먼트의 높이를 부모에게 반영하는 방법으로 부모에게도 float 속성을 부여하는 방법이 있습니다. 부모에게 float 속성을 부여하게 되면 부모엘리먼트는 자식 엘리먼트의 높이를 반영합니다. 하지만 부모 엘리먼트의 너비는 float된 두 자식의 너비를 담을만큼만 작게 줄어든다는 사실에 주목해 주세요. 부모의 너비가 브라우저 크기에 따라 가변적이어야 하는 경우에 적용하기 어려운 단점이 있습니다. 또한 조상 엘리먼트들이 겹겹이 존재하는 경우 자식의 높이를 조상 엘리먼트에게 각각 전달하기 위하여 조상 엘리먼트들을 모두 float 시켜야 하므로 일반적으로 사용하는것을 권장하지 않습니다. float에 float으로 대응하는 방법 예제.

float에 overflow 속성으로 대응하는 방법
자식 엘리먼트의 높이를 부모에게 반영하는 방법으로 부모 엘리먼트에 overflow:auto 또는 overflow:hidden 속성을 부여하는 방법이 있습니다. overflow:auto 속성은 자식의 너비가 가변적이고 부모의 너비보다 커지는 상황이 발생할 때 가로 스크롤바를 유발하기 때문에 일반적으로 권장하는 방식이 아닙니다. overflow:hidden 속성은 그러한 상황에서 가로 스크롤바를 유발하지는 않지만 자식의 너비가 넘치는 경우 넘치는 부분이 잘리기 때문에 이 역시 완전하게 안전한 방법은 아닙니다. float에 overflow 속성으로 대응하는 방법 예제.

float을 빈 엘리먼트로 clear 하는 방법
이 방법은 #container 영역이 끝나기 직전 빈 엘리먼트를 넣고 빈 엘리먼트에 clear:both 속성을 부여하여 부모가 자식의 높이를 인식하도록 하는 방법입니다. 하지만 의미 없는 빈 엘리먼트를 사용하기 때문에 이 역시 권장되는 방법은 아닙니다. float을 빈 엘리먼트로 clear 하는 방법 예제. 예제에서는 .clear 라는 빈 엘리먼트를 가시적으로 보이도록 하였지만 실무에서는 보통 .clear {clear:both; height:0; overflow:hidden;} 처리하여 .clear 라는 빈 엘리먼트가 스스로 높이를 갖지 않도록 하고 보이지 않도록 처리 합니다.

float을 가상 선택자 :after로 clear 하는 방법
가장 탁월하다고 생각하는 방법 입니다. 우선 ‘가상 선택자‘라는 개념을 이해하셔야 하기 때문에 약간 상세히 설명드리겠습니다. 여러분들이 익히 알고 계시는 :link, :visited, :hover, :active, :focus는 모두 가상 선택자 입니다. ‘가상 선택자’는 다시 ‘가상 클래스‘와 ‘가상 엘리먼트‘로 구분할 수 있는데요. ‘가상 클래스‘는 특정 엘리먼트에 대하여 아무런 class를 부여하지 않았지만 마치 역동적으로 class를 변경한것과 같은 효과를 낼 수 있는 것들로서 이미 존재하는 엘리먼트에 조합해서 사용할 수 있습니다. :link, :visited, :hover, :active, :focus, :first-child가 가상 클래스에 해당됩니다. 한편 ‘가상 엘리먼트‘란, 존재하지 않는 엘리먼트를 가상으로 생성해내는 선택자로서 :first-line, :first-letter, :before, :after가 있습니다. 심지어 :before와 :after는 HTML문서상에 존재하지 않는 콘텐츠를 출력시키기도 합니다. Hello World Collection이라는 웹 사이트에 신현석님이 ‘Hello World’라는 메시지를 어떻게 출력했는지 살펴보시면 재미있고 이해하기도 쉽죠. 이렇게 가상의 엘리먼트를 생성 #container:after {content:" "} 시킨 다음 display:block; clear:both 처리를 추가하게 되면 의미 없는 빈 엘리먼트를 사용하지 않으면서도 가상 엘리먼트를 이용하여 깔끔하게 float이 clear됩니다. float을 가상 선택자 :after로 clear 하는 방법 예제.

상기 예제로부터 가상 엘리먼트가 스스로 높이를 갖지 않고 화면에 보이지 않도록 처리 하려면 아래와 같이 처리 합니다.
#container:after {content:""; display:block; clear:both;}
하지만 Internet Explorer는 :before, :after 가상 엘리먼트 선택자를 지원하지 않기 때문에 다음과 같은 Hack이 필요합니다.
#container {*zoom:1;} /* IE5.5~7 브라우저 대응 Hack */
#container:after {content:" "; display:block; clear:both;} /* 표준계열 브라우저에 대응하는 float 해제용 가상 엘리먼트의 생성 */
IE 5~7 브라우저는 hasLayout이라는 고유한 성질을 갖게 되면 float을 해제하는 트리거로 작용하는 성질이 있고 zoom:1 속성이 hayLayout 이라는 성질을 갖도록 하기 때문에 IE 5~7 브라우저 고유의 특징을 이용한 해결방법 입니다.
float을 display:inline-block 으로 clear 하는 방법
float된 자식요소들의 높이를 부모에게 전달하는 방법으로써 부모 요소에 display:inline-block 속성을 부여하는 방법도 있습니다. [코멘트 해주신 김영환님 감사합니다] inline-block 속성이 부여된 요소는 float된 자식의 높이만큼 늘어납니다. [CSS 2.1 관련 설명 코멘트 해주신 연홍석님 감사합니다] 모든 브라우저가 동일하게 float을 해제하는 방향으로 작용합니다. 단, 표준계열 브라우저들은 부모 요소의 너비가 자식의 너비만큼 알맞게 줄어들지만 IE 6~7 브라우저는 100%의 너비를 갖게 되는 특징이 있습니다. 또한 inline-block 속성을 갖게 된 요소는 인라인 요소와 마찬가지로 박스가 끝나는 지점에 약 4px 정도의 공백을 갖게 되므로 이점 유념하시는게 좋겠습니다.
참조
- Cascading Style Sheets, level 2 CSS2 Specification – http://www.w3.org/TR/REC-CSS2/
- CSS2 규격 한글 번역문 – http://trio.co.kr/webrefer/css2/cover.html
- CSS 2.1 Visual formatting model details – http://www.w3.org/TR/CSS21/visudet.html#block-root-margin
- YAML > How Floats Work – http://www.yaml.de/en/documentation/basics/how-floats-work.html
- 신현석 > CSS Floating and Clearing – http://hyeonseok.com/soojung/web/2005/03/07/123.html
처음으로 글남겨요~
8월에 생산성본부에서 교육받고 강사님께 메일보냈었는데 ^^;;(프레임기반 제품때문에 고민이라고 했던…) 저희 프레임 다빼고 신제품 만들고 있어요,,,괴롭다는 ㅠㅠ
display:inline-block; 저도 어쩌다가 알게되서 사용하고는 있었는데
맞는건지는 모르고 그냥 되길래 쓰고있었어요 ㅎ ^^;;;
항상 여기와서 도움만 받고갑니다..
유미영님, 프레임 없는 더 좋은 제품 만드시는 거잖아요. ^^ 많은분들이 더 좋은 제품을 만나게 되겠네요. 힘내세요! 뽜이링!
와..와..;ㅂ; 세세하면서도 한 눈에 들어오는 설명! ㅠㅠ 감사합니다!
즐겨찾기에 등록해놓고 생각날때마다 와서 볼까합니다!
안녕하세요 이런좋은 곳이 있었다니 뒤늦게 안것이 아쉽습니다.
좋은정보 감사드립니다.
손병익님 반갑습니다. 자주 들러 주시고 다르거나 더 좋은 의견 있으면 언제든 말씀 주세요. ^^
궁금한것이 하나있는데요…
width 값을 넣어주면 정상적으로 컨텐츠와 네비게이션이 위치되던데…
width 값을 주면 뭔가 문제가 발생이 되나요?
@익명
아마도 IE 6~7 브라우저에서 그런 현상을 보시는 것 같은데요.
표준에 따른 렌더링 방식은 아닙니다.
IE 6~7 브라우저는 width 값을 부여하면 hasLayout 이라고 하는 IE 전용 속성이 발생하는데 이게 영향을 미치는 것 같습니다.
다른 표준계열 브라우저들은 width 값을 부여한다고 해서 float과 관련하여 어떤 변화가 발생하지는 않습니다.
아~~ 확인해 보니까 그렇군요 ^^!
미처 다른 브라우져에서 확인을 안하고 질문을 드렸네요 ^^:
꽃피는 4월입니다. ^^
질문하나 드리려고 왔습니다 ^^:
다름이아니라 작업을 하다보니 궁금해서요…
container:after를 왜 사용해야하는 지는 알겠는데요…
웹 접근성 연구소 페이지를 뜯어보니까..
container부분이 가상엘리먼트를 사용하지 않았는데도 잘 나오더라고요..
그래서 그대로 따라해 보았는데 저는 위 예제처럼 컨테이너가 높이값을 갖지 못하는 문제가 발생하더라고요..
가끔 웹 사이트들을 보면 가상엘리먼트나 display:inline-block를 사용하지 않아도 별 문제 없는 사이트들이 보이더라고요..
그래서 더 헷갈리는거 같은데요…
궁금한것인즉…자식을 갖는 부모의 높이값이 적용이 안되는것이 정상적인것 인가요?
참 질문을 하려니 말이 제대로 안나오네요 ^^:
더 쉽게 질문 하자면 …. 가상엘리먼트나 위에 예시들처럼 float해제 방법을 사용하지 않아도 부모의 높이값이 제대로 나오는 경우는 그저 운이 좋아서 그런것인가 해서요…
@윤군
웹 접근성 연구소에는 :after 라는 가상 선택자가 사용되지 않았음에도 불구하고 float이 해제되는 효과가 발생했는데 이걸 어떻게 이해해야 하는지 설명해 달라는 질문으로 해석 됩니다.
말씀하신 대로 웹 접근성 연구소는 :after 라는 가상 선택자가 사용되지 않았지만 대신 다음과 같은 코드가 #Contents 영역에 사용 되었습니다.
#Contents { min-height:390px; width:952px; }
사실 float이 clear 된 것 처럼 보이지만 clear 되지는 않았고 마치 clear 된 것처럼 보이도록 min-height를 사용 했습니다. 표준계열 브라우저(FF, SF, CR, OP)와 IE 7~8 브라우저는 min-height 속성을 지원하기 때문에 높이값이 반영 되었죠. 이런 코드는 콘텐츠의 높이가 가변적으로 변하는 영역에는 사용할 수 없는 단점이 있습니다. 내부 자식 콘텐츠 영역의 높이가 늘어날 때 마다 min-height를 늘려줘야 하니까요.
문제는 IE6 인데요. IE6는 부모에 width 값만 주어도 자식의 float을 해제해 버리는 버그가 있는데 이것을 이용한 것입니다. width 값이 들어가 있죠. 이것을 빼 보시면 IE6에서 깨지는 것을 확인할 수 있습니다. 이 코드는 width 값이 가변적인 상황에서는 사용할 수 없는 단점이 있는 것입니다.
즉, 웹 접근성 연구소는 콘텐츠의 너비와 높이가 고정되었다는 특징을 이용해서 이 상황에만 맞는 float clear 효과를 구현한 것입니다. 핵을 사용하지 않았다는 점에서 칭찬할만한 일이지만 너비와 높이가 가변적인 상황에서는 사용할 수 없는 코드 입니다.
아~
ㅎㅎ 속시원하네요…지식을 하나하나 얻다보면 이것저것 답답한게 많은데
친절히 설명해주셔서 감사합니다.
정말이지 복 받으실거예요^^~~
오늘도 고맙습니다.
항상 좋은 정보 많이 얻어가고 있습니다. ^^
테스트 중에 문제가 좀 있는 것 같더라구요.
after 라는 가상 엘리먼트가 적용되는 대상이 어떻게 되나요?
스타일을 아래와 같이 주고
#box {
float: none;
*height: 1%;
padding: 0 5px;
}
#box:after {
content: “”;
clear: left;
display: block;
}
#box {
*zoom: 1;
}
.list, .list li {
float: left;
}
아래와 같이 태그를 주면 float이 제어되지 않는 것 같더라구요.
[div id="#box"]
[ul class="list"]
[li]1[/li]
[li]2[/li]
[li]3[/li]
[li]4[/li]
[li]5[/li]
[/ul]
[/div]
after는 div에 제한적인건지요? 이 방법으로 게시판의 리스트를 만들어 보려는데
float이 제어되지 않고 빈 div 엘리먼트로 클리어 해주면 되더라구요. 혹시 제가 잘못한
것이 있는지요? ^^;
[div id="#box"] 는 [div id="box"] 입니다. 오타가 있었네요. ^^
-_-;;; 이런….
해결됐습니다. 드림위버는 after 라는 가상 엘리먼트를 출력하지 못하네요.
브라우저로 보면 되네요. 질문을 삭제하려 했지만 삭제기능이 없어 댓글로
남깁니다.
하드코딩하는데 레이아웃 잡을 땐 가끔 드림위버를 쓰는데 안되는 줄 알고
몇시간을 헤맸네요… 드림위버의 문제였습니다. 앞으로는 하던대로 Coda로
코딩해야겠네요.
@닭발은세개
해결되셨다니 다행입니다. ^^ 정확히 말하면 드림위버의 위지윅 모드 렌더링이 CSS 표준에 따라 출력되지 않는 현상인거겠죠.
공공쪽 표준화 작업중 궁금한것이 있써서 질문드려요
정찬명님 글을 참고하여
저도 가상선택자를 이용해서 클리어를 시켰썼습니다..
근데 요즘 *zoom:1; 이런핵을 사용하면 http://validator.kldp.org/ 여기에
마구마구 걸리는데… ㅠㅠ
모 공공쪽이다보니 유효성 검사 다 통과해야하고
클리어는 시켜야게꼬,,,
오똑캐야 하나요?? ㅠㅠ
@마포레이서
CSS 유효성까지 충족하라는 지침이 영 제 마음에 들지는 않지만 통과 하시려면 어쩔 수 없이 핵을 별도 파일로 분리하신 다음 IE 조건부 주석으로 감싸서 링크 하셔야겠네요.
조건부 주석(Conditional Comment)으로 제 블로그 또는 검색엔진에서 찾아보시면 사용법을 금방 찾을 수 있으실껍니다.
ㅇ ㅏ 그것도 알고는 있었지만 혹시 다른방법이 없나해서 혹시나해서 저만 모르구있나해서요ㅠ
(왕따느끼는 1인 ㅠㅠ )
참 ~ 누구를위한 표준화이며 호환성 이며
항상 여기와서 위로는 받지만 ..
ㅇ ㅏ~~ 님금님 귀는 당나귀기~~~
훔 밥뿌실텐데 빠른시간 답변 주셔서 감사합뉘다 .
수고하셔요 =3=3=3=
@마포레이서
저는 *zoom:1 대신에 height:100% 사용합니다.
@김무건
ㅇ ㅏ 감사합뉘다
와우. >ㅁ< 푸터에 사이드바를 넣고 float 정렬하다가 다 튀어나와서 깜놀했지 뭐에요.
덕분에 깔끔하게 해결했습니다. 감사드려요.
아직 생초보라 많은 부분 부족하군요;;
@레이
float으로 레이아웃 잡는데 성공하셨다면 이미 생초보라 부르기 어렵습니다. ㅎㅎ
지금까지 의미없는 빈 엘리먼트를 삽입하여 clear하다가
덕분에 이제야 가상선택자(:after)를 알게되었네요.
감사합니다.
float, clear, display…
제가 제일 못하는 것 세 개 ㅠㅠㅠ
아직도 어렵네요
다시 한 번 찬찬히 읽어봐야 겠어요
정보 감사합니다 ^*^
display: inline-block를 사용할 경우 표준브라우저에서는 +3px의 우측 마진을 가지고 있습니다.
핵을 사용(css 2.0 셀렉터를 사용하여 우측마진을 주시면 6, 7을 포함하는 구형 IE브라우저에는 해당되지 않는 inline-block을 만들 수 있습니다.
/ 예를들면
ul li span { display: inline-block;}
ul li > span { margin-right: -3px;}
이 경우 셀렉터가 적용되는 브라우저가 여백을 갖지 않게 하여 width를 통한 inline-block요소간의 크로스브라우징 레이아웃을 가능하게 합니다.
P.S. 다른 버그를 찾다가 이 글을 보게됐는데요, IE6의 경우 clear: both 이후에 padding-top 을 하게 되면 이 padding을 두배로 계산하는 버그도 있더라구요. 어찌된건지 찾아보고 있습니다만… 혹시 아신다면 shoolovu앳naver.com으로 메일 한번 주시면 감사하겠습니다 ㅜㅜㅜㅜ
안녕하세요. 책보고 공부하다 블로그에 포스팅 했었는데 여기 더 자세한 글이 있었네요. 참고하기 위해 링크 걸겠습니다.
링크퍼갑니다 :)
그물고기의 생각…
div 태그에서 float 에 대한 정리…
이것 때문에 속 썩었는데 어쩜 글도 잘 쓰시고
정말 설명이 쏙쏙 와 닿았네요.
너무너무 감사드려요.
큰절 드려요!!!
크으으으은절……꾸벅..
우와.. 너무 감사합니다.. css스타일을 잘 몰라 힘들었는데
박스정렬이 이것으로 잘 되네요.. 자주 보고 갑니다 많은 정보 부탁드려요~
현재 우리 회사에서 일하시는 퍼블리셔분들은 빈 엘리먼트를 추가하여 float을 clear하는 방법을 많이 쓰시더라구요..
그 방법이 최적의 방법이 아니라는 것을 어느정도 인지한다고 해도 막상 가상선택자가 아직 익숙치않아 그런것이라 생각됩니다.
찬명님의 이 글을 함께 보면 좋을 것 같아요 ^^
좋은 글 잘 보고 갑니다.
정말 필요한 정보였는데 감사합니다. 학생이라 하나 더 배우고 가네요!
[...] float를 clar하는 4가지 방법 바로가기 [...]
죄솝합니다.. 스크랩 해가면서 글을 못남겼네요.. ㅡㅡ;
핑계지만 댓글쓰는곳을 못찾았다는 …
아무튼 너무 도움이 되는 자료고요, 담아갈께요..
float을 display:inline-block 으로 clear 하는 방법,
이것 덕분에 바로 해결되었어요~ 감사합니다!!!
@이햐
display:inline-block 요소는 우측에 4px 공백 발생하는것 유념 하시구요. ^^
하나 명심해야 할 것은
ELEMENT:after 를 쓰실때
ELEMENT 대상이 되는 DIV에는 float 속성이 있어선 안됩니다.
Float 이 설정되어있지 않는 DIV에 :after 를 걸어주세요