CSS 이야기: position, float, display 속성간의 관계

CSS의 관점에서, HTML 문서는 크고 작은 여러 개의 사각형 박스로 구성됩니다. 그 중에는 요소에 의해서 만들어지는 박스도 있고, 자동적으로 만들어지는 박스(익명(anonymous) 박스)도 있지만, 근본적으로 “박스”라는 것에는 차이가 없습니다.

CSS를 지원하는 사용자 에이전트는 이렇게 만들어진 박스를 배치함으로써 문서의 레이아웃을 표현합니다. 이 과정에서 각각의 박스는 어떤 방식으로 배치될 것인지에 따라 크게 다음과 같이 세 가지로 분류됩니다.

  • 일반적인 흐름(normal flow)으로 배치되는 박스
  • 떠있는(float) 상태로 배치되는 박스
  • 절대적인 위치(absolute position)로 배치되는 박스

이 세 가지 배치 방식은 CSS의 근간인 시각적인 서식 모델의 핵심입니다. 이 글에서는 먼저 각각의 배치 방식을 간단히 알아보고, 배치 방식을 결정짓는 position. float 속성과 박스 유형을 결정짓는 display 속성이 어떻게 상호 작용하는지를 정리해보겠습니다.

display 속성 값에 따라 만들어지는 block, inline, run-in 박스 등에 대해서는 이 글에서 다루지 않습니다.

일반적인 흐름(normal flow)으로 배치되는 박스

일반적인 흐름이란 순차적으로 박스가 배치되는 것을 말합니다. 예를 들어서 블록 박스의 경우에는 포함 블록(containing block) 상단부터 시작해서 순서대로 하나씩 수직으로 배치됩니다. 두 박스간의 간격은 margin 속성으로 조절되며, 두 마진이 닿을 경우에는 서로 병합됩니다.

이 배치 방식이 적용되려면 position 속성이 static(기본 값)이나 relative여야 하고, float 속성이 none(기본 값)이어야 합니다. 만약 positionstatic이라면 해당 박스의 top, bottom, left, right 속성은 완전히 무시됩니다. relative가 지정된 박스도 일반적인 흐름에 따라 배치되지만, 배치된 위치를 기준으로 top 등의 속성에 따라 상대적으로 위치가 다시 조정됩니다(offset). 이렇게 박스에 offset이 발생하더라도 이어지는 박스는 offset이 없는 것처럼 배치되기 때문에 전체적인 흐름에는 영향을 주지 않습니다.

CSS 2.1에서는 position:relativetbody, thead, tfoot, tr, colgroup, col, td, th, caption 요소에 지정했을 때의 효과에 대해서는 정의하지 않습니다. 따라서 tdrelative를 지정하면 사용자 에이전트에 따라서 서로 다른 결과가 발생할 수 있습니다.

떠있는(float) 상태로 배치되는 박스

float된 박스는 일반적인 흐름으로 배치되었을 때의 위치를 기준으로 포함 블록이나 float된 다른 박스에 닿을 때까지 오른쪽이나 왼쪽으로 이동합니다. 그리고 나서는 일반적인 흐름에서 벗어나서 말 그대로 “떠있는” 상태가 되기 때문에 구조상으로 해당 요소 앞, 뒤에 있는 블록 박스(normal flow)는 float된 박스가 존재하지 않는 것처럼 배치됩니다. 인라인 박스는 블록 박스와는 달리 float된 요소 주위로 흐르듯이 배치됩니다.

한 가지 예로, 아래 소스에서 빨간색 보더가 지정된 p 요소의 블록 박스는 float된 요소의 영향을 받지 않지만, 인라인 박스는 영향을 받아서 오른쪽으로 밀려나는 것을 볼 수 있습니다.

<div style="padding:10px; background:#eee;">
	<p style="float:left; background:blue; color:#fff;">float 된 요소</p>
	<p style="padding:10px; border:1px solid red;"><span style="background:orange;">주위를 흐르는 인라인 박스</span></p>
</div>

float 된 요소

주위를 흐르는 인라인 박스

이 배치 방식이 적용되려면 우선 position 속성이 absolutefixed가 아니고 float 속성이 none이 아니어야 합니다. absolutefixed 값은 float 보다 우선해서 박스를 다음에 설명할 절대적인 위치로 배치되도록 만들기 때문입니다. 또한, float된 박스는 display 속성을 inline으로 지정하더라도 실제 적용되는 산출 값(computed value)은 block이 됩니다.

float된 요소에 display:inline을 지정하는 것은 흔히 발생하는 인터넷 익스플로러의 float 버그를 해결하는 CSS 핵(hack)입니다. 위와 같은 이유로 이 핵은 표준을 따르는 사용자 에이전트에는 아무런 영향도 미치지 않습니다.

절대적인 위치(absolute position)로 배치되는 박스

절대적인 위치로 배치되는 박스는 앞서 float된 박스가 일반적인 흐름에서의 위치를 기준으로 왼쪽이나 오른쪽으로 이동하는 것과는 달리 아예 일반적인 흐름에서 완전히 벗어나기 때문에 구조상의 앞, 뒤 요소에 아무런 영향을 미치지 않습니다. 절대 위치로 배치되는 박스에 유일하게 영향을 주는 것은 오직 그 자신의 포함 블록이며, 이 포함 블록을 기준으로 top, bottom, left, right 값에 따라 위치가 결정됩니다.

절대 위치로 배치되는 박스의 포함 블록은 일반적인 흐름에서의 포함 블록과는 다른 의미를 갖습니다. 즉, 일반적인 흐름에서는 가장 가까운 블록 레벨이나 inline-block, th, td 조상 요소 박스가 포함 블록를 형성하지만, 절대 위치 방식에서는 position이 지정된(positioned) 가장 가까운 조상 박스가 포함 블록이 되며 반드시 블록 레벨일 필요도 없습니다. 참고로 CSS 2.1에서 “위치가 지정된”이라는 표현은 position 속성 값이 static이 아닌 모든 경우에 해당합니다(absolute, fixed, relative).

이 배치 방식이 적용되려면 position 속성 값이 absolutefixed여야 합니다.

† 위에 설명한 “절대 위치 방식”에서의 포함 블록 정의는 position 속성이 absolute일 때에만 적용됩니다. positionfixed일 때의 포함 블록은 “연속적인(continuous)” 미디어에서는 “뷰포트(viewport)”, 페이지로 구분되는(paged) 미디어에서는 “페이지 영역”을 기준으로 만들어집니다.

오류 지적해주신 정찬명님. 고맙습니다~ ^^

position, float, display 속성간의 관계

앞서 설명했던 내용을 정리해보겠습니다. 우선 요소의 배치 방식에 가장 큰 영향을 미치는 CSS 속성은 position입니다. display 속성은 요소가 어떻게 표현되는지를 결정하지만(심지어 보이거나 보이지 않게도 하지만) 근본적으로 배치 방식에는 영향을 주지 못합니다. positionabsolutefixed이면 절대 위치로 박스가 배치되고, static이나 relative이면 일반적인 배치나 떠있는 배치가 적용됩니다. 절대 위치로 배치되면 float 속성의 산출 값은 어떤 값을 지정하든 상관 없이 none으로 평가되고. display 속성은 아래 표에 따라 변환되어 적용됩니다.

지정한 값 산출 값
inline-table table
inline, run-in, table-row-group, table-column, table-column-group,
table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block
block
기타 지정한 값

† 문서의 시조(root) 요소에 지정된 display 값도 위 표에 따라 결정됩니다.

일반적인 배치와 떠있는 배치 중 어느 쪽이 적용되는지는 float 속성에 따라 결정됩니다. floatleftright이면 떠있는 배치 방식이 적용되고, 이 때 display 속성 값은 위 표에 따라 변환되어 적용됩니다.

display 속성 값은 요소의 표현 방식을 결정합니다. block 요소를 inline 요소처럼 표현할 수도 있고, 그 반대도 가능합니다. 하지만 앞서 알아본 것처럼 absolute 속성이나 float 속성 값에 따라서 지정한 값과는 다르게 적용될 수도 있다는 점에 주의해야 합니다.

positionfloat 속성이 display보다 우선하지만, 예외적으로 displaynone일 때에는 positionfloat이 적용되지 않습니다. 당연한 얘기지만 박스 자체가 만들어지지 않기 때문입니다.

마치며

간단하게 position, float, display 속성이 어떻게 관련되어 있는지 정리하려고 했는데 또 글이 길어졌네요. 한동안 글을 쓰지 않다가 갑자기 뭔가를 쓰려고 하니 어색하기도 하고, 무엇보다 이렇게 마음 내키는대로 주제를 정해서 글을 쓰는 것에 한계를 느낍니다. 이 글만 해도 CSS의 박스 모델과 포함 블록, 블록 서식과 인라인 서식 등을 먼저 설명해야 하는데 그런 체계 없이 쓰려다 보니 설명을 많이 생략하게 되거든요.

그래서 새해를 맞아서 처음부터 조금씩 정리해볼 생각입니다. CSS 2.1 소개Conformance, 속성 값 처리 방식등은 다루었으니, 박스 모델부터 시작해볼 생각입니다.

그리고 언제나 그렇듯이 글 내용에 오류가 있다면 꼭 알려주시기 바랍니다. 한동안 잠수 아닌 잠수 상태라서 댓글에 제대로 피드백을 못드렸는데 이제 수면 위로 올라왔습니다. ^^

댓글 12개가 달렸습니다. 태그: , , ,

  1. 다다에 | 2009-01-12 13:19

    항상 감사히 잘 읽고 있습니다. 감사^^

  2. wystan | 2009-01-13 00:52

    찾아주셔서 고맙습니다~ ^^

  3. 정찬명 | 2009-01-13 04:36

    잘 읽었습니다. { position:fixed } 값이 부여되면 위치값이 지정된 가장 가까운 부모로부터 위치를 결정하지 않고 브라우저의 뷰포트(viewport)로부터 위치를 계산하는 특징이 있다는 점이 absolute와 다른 점인데 이 부분 설명이 곁들여지면 좋을것 같습니다. ^^

  4. 봄눈 | 2009-01-13 09:11

    회사 옮기신 이후에 너무 바쁘셔서 포스팅이 잘 안되시는게 아닐까 하고 괜히 걱정했네요~!
    2009년 첫 포스팅 너무 멋지십니다^^
    전 언제쯤 이런 분석적인 글을 써보나요 ㅎ 앞으로도 좋은 글 부탁드립니다~

  5. wystan | 2009-01-14 01:34

    정찬명님~

    오류 지적해주셔서 고맙습니다. 역시 예리하세요~ ^^
    관련해서 내용 업데이트했습니다.

    그리고 요즘 당구 80으로 올리라는 얘기를 많이 듣는데 언제쯤 심사받을 수 있을까요? ^^;

  6. wystan | 2009-01-14 02:03

    봄눈님~

    사실 분석한 것은 별로 없고, 그냥 자료 모아서 정리했는데 과찬이십니다. ^^
    오히려 봄눈님 글이 분석적이라고 생각해요. 특히 “업무 프로세스” 관련 글은 저로서는 쓰기 어렵거든요.
    댓글을 안 남겨서 그렇지 많이 배우고 있습니다.

    그나저나 동네도 가까운데 또 언제 점심 같이 먹어요~~

  7. 가즈랑 | 2009-01-18 03:22

    텍스트패턴으로 블로그를 다시 만들면서 정말 많은 도움이 되었습니다. 특히 공개해주신 테마는 공부하는데 많은 도움이 됐구요. 아 참고로 저는 워드프레스로 시작했다가 넘어왔습니다. wystan님의 글들도 영향이 많이 있었고요. 지금도 조금씩 수정하고 있는데,이곳에 있는 태그기능은 어떤 플러그인으로 사용하고 계신가요? 내장 기능인 txp:keywords를 쓰고 싶은데 좀 부족한 거 같고, 플러그인은 좀 오래되서 작동하지 않는 것도 있고 말이죠. 어떻게 해결하셨는지 알고 싶습니다~

    사실 이번에 TXP공부하면서 처음 들렀는데 좋은 글들이 참 많네요. 앞으로 더 많이 들르겠습니다. ^^

  8. wystan | 2009-01-27 02:07

    가즈랑집 정말 멋지네요~
    테마와 포스팅, 어느 곳에서든 “우아함”이 느껴집니다. 부러울 만큼이요.
    멋진 블로그 만드시는데 도움이 되었다니 기쁩니다.

    쉽게 권하지는 못하지만 텍스트패턴만큼 좋은 블로깅 툴은 없다고 생각합니다. 특히 Textile에 익숙해지면 글 쓰는 게 정말 편하거든요. 상대적으로 워드프레스보다 훨씬 빠르고요.

    말씀하신 태그 기능은 tru_tags 플러그인을 쓰고 있습니다. 꽤 오랜 시간이 흘렀는데도 제작자가 잘 관리하고 있네요.

    찾아주셔서 고맙습니다. 텍스트패턴 사용자가 늘어서 참 좋네요~ ^^

  9. cindij | 2009-05-22 14:12

    wgstan님 글 도움많이 받습니다. – 일반적인 흐름(normal flow)으로 배치되는 박스에서 – relative가 지정된 박스도 일반적인 흐름에 따라 배치되지만, 배치된 위치를 기준으로 top 등의 속성에 따라 상대적으로 위치가 다시 조정됩니다(offset). 이렇게 박스에 offset이 발생하더라도 이어지는 박스는 offset이 없는 것처럼 배치되기 때문에 전체적인 흐름에는 영향을 주지 않습니다.
    -> 이부분에 offset용어가 좀 어려운데 무슨 뜻인지요? 해당 박스가 없는것으로 인식한다는 건지요?

  10. urbug2 | 2009-09-08 01:42

    모르는것 때문에 검색하다 우연히 들어 왔습니다.
    많이 얻어 가네요. 고맙습니다. ^^

  11. SOLMATE | 2010-01-05 11:56

    오늘 처음 알게 되었는데. 유익한 사이트 같네요.^^ 퍼갈꼐요.

  12. 정미애 | 2011-06-24 10:16

    CSS 이야기: position, float, display 속성간의 관계

댓글이 닫혔습니다.