A LIST Apart: For People Who Make Websites

CSS 플로트 기초

by Noah Stokes

플로트 속성은 웹 디자이너/개발자의 유용하고 강력한 도구입니다. 하지만 플로트가 어떻게 동작하는지 완전히 이해하지 못하고 쓴다면 많은 혼란과 절망감을 느끼게 할 수도 있습니다. 게다가 옛날에는 플로트 때문에 지저분한 브라우저 버그가 생기기도 했으니, 플로트란 말만 들어도 질색을 하는 건 어쩌면 당연한 일입니다. 자, 일단 차분하게 마음을 가라앉히시죠. 플로트가 어떻게 동작하는지 정확히 알려 드리고, 일단 이걸 숙달하면 놀랄 만큼 쓸모 있다는 걸 보여 드리겠습니다.

The float property is a valuable and powerful asset to any web designer/developer working with HTML and CSS. Tragically, it can also cause frustration and confusion if you don’t fully understand how it works. Also, in the past, it’s been linked to some pretty nasty browser bugs so it's normal to get nervous about using the float property in your CSS rule sets. Let’s calm those nerves and ease that frustration. I’ll show you exactly what the float property does to your elements and how incredibly useful it can be once you master it.

이미지 좌우로 텍스트가 멋지게 배치된 잡지들을 볼 때마다 플로트를 보고 있는 겁니다. HTML과 CSS의 세계에서는, 플로트 속성이 들어간 이미지 주위로 텍스트가 흐릅니다. 매일 보는 잡지나 신문과 마찬가지죠. 이미지는 float 속성을 쓰는 한가지 예일 뿐입니다. 플로트 속성을 사용해서 2단 레이아웃을 만들 수도 있습니다. 사실, HTML의 거의 모든 요소에 플로트를 쓸 수 있습니다. position 속성의 기초와 플로트를 이해하면, 어떤 레이아웃이든 자신감 있게 만들 수 있을 겁니다.

We see floats in the print world every time we pick up a magazine article with an image on the left or right with text flowing nicely around it. In the world of HTML/CSS, text will wrap around an image with the float property applied to it, much like in a magazine layout. Images are just one of the many use cases for the float property: we can also achieve the popular two-column layout using floats. In fact, you can float just about any element in your HTML. By learning and understanding float property basics, along with position property basics, you will be able to achieve any layout with confidence.

정의

먼저 플로트의 정의부터 시작하도록 하죠. W3C에 따르면:

Let’s start with the definition of a float. According to the W3C:

플로트는 현재 행의 왼쪽이나 오른쪽으로 밀려나는 박스입니다. 플로트의 가장 흥미로운 특징은, 다른 컨텐츠가 그 주위로 흐른다는 겁니다. (clear 속성으로 이걸 막을 수 있습니다.) 주위 컨텐츠는 왼쪽으로 플로트된 박스의 오른쪽을 따라, 또는 오른쪽으로 플로트된 박스의 왼쪽을 따라 흘러내립니다.

A float is a box that is shifted to the left or right on the current line. The most interesting characteristic of a float (or “floated” or “floating” box) is that content may flow along its side (or be prohibited from doing so by the “clear” property). Content flows down the right side of a left-floated box and down the left side of a right-floated box.

플로트 속성에는 네가지 값을 쓸 수 있습니다: left, right, inherit, none. 값을 보기만 해도 무슨 뜻인지 쉽게 알 수 있습니다. 예를 들어, 요소에 float: left를 지정하면 그 요소는 부모 요소의 왼쪽 끝으로 갑니다. float: right;도 마찬가지로, 부모 요소의 오른쪽 끝으로 갑니다. inherit는 부모 요소의 float속성을 물려받는다는 뜻입니다. none은 이 요소가 플로트되지 않는다는 뜻이고, 기본값입니다.

The float property has four values that we can apply to it: left, right, inherit, and none. Each value is pretty self explanatory. For example, if you assign float: left to an element, it will move to the left-most boundary of its parent element. The same idea applies if you were to assign float: right; to an element. That element would be sent off to the right-most boundary of its parent element. The inherit value tells an element to inherit the float value of its parent element. The value none is the default value and tells an element not to float at all.

위에서 언급했던 잡지 같은 간단한 예제와 그 마크업입니다:

Here is a simple example like the magazine reference above, Example A and the corresponding markup:

img {
  float: right;
  margin: 10px;
}

플로트의 원리

그다지 복잡하지 않으면서도, 꽤 괜찮지 않습니까? 어린애 장난 같다고요? 아, 뭐, 좋습니다. 앨리스의 이상한 나라로 떠나기 전에, 잠시 숨을 돌리면서 여기서 어떤 일이 왜 일어난 것인지 찬찬히 살펴보는 게 좋겠습니다.

HTML은 몇 가지 규칙에 따라 표현됩니다. 그중에서도, 지금 얘기할 건 일반적 흐름(normal flow)입니다. 일반적 흐름에서는, 각각의 블럭 요소(div, p, h1 등)는 서로의 위에.. 아니, 위에서 아래로 쌓입니다. 플로트된 요소는 일단 이런 일반적인 흐름을 따르다가, 흐름에서 빠져나와서는 부모 요소의 오른쪽 또는 왼쪽 끝에 달라붙습니다. 다른 말로 하면, 부모 요소의 폭이 플로트된 요소들이 모두 들어갈 만큼 충분하기만 하다면 위로 쌓이는 게 아니라 옆으로 쌓인다는 거죠. 웹사이트를 만들고 싶다면, 플로트의 이런 특징을 꼭 기억하고 있어야 합니다.

Nothing too complex, but still pretty cool right? Child’s play you say. Ok, well before we get into the part where floats usher in a world of bacon-loving unicorns, let’s back up for a second to talk about what’s actually happening here. In the web world, our HTML is bound by some rules, in particular, the normal flow. In the normal flow, each block element (div, p, h1, etc.) stacks on top of each other vertically, from the top of the viewport down. Floated elements are first laid out according to the normal flow, then taken out of the normal flow and sent as far to the right or left (depending on which value is applied) of the parent element. In other words, they go from stacking on top of each other to sitting next to each other, given that there is enough room in the parent element for each floated element to sit. This behavior is crucial to remember as you build your websites.

그럼 다른 예제를 보죠. 예제 B 에는 플로트 속성이 없는 블럭이 3개 있습니다:

Let’s look at a few more examples. In Example B, there are three blocks without the float property applied:

.block {
  width: 200px;
  height: 200px;
}

블럭들이 서로의 위에 쌓인 걸 보셨나요? 이것이 일반적 흐름의 기본 개념입니다. 예제 C는 똑같은 것이지만, 이번에는 3개의 블럭 모두 플로트가 적용되어 있습니다.

Notice how they stack on top of each other? This is the basic concept of normal flow. Here is the same example again, but this time the blocks are all floated in Example C:

.block {
  float: left;
  width: 200px;
  height: 200px;
}

이제 블럭들이 옆으로 늘어서 있습니다. 아, 좋군요. 이제 어떤 원리인지 알겠습니다. 그런데, 아까 말했던 "부모 요소의 폭이 플로트된 요소들이 모두 들어갈 만큼 충분하기만 하다면 위로 쌓이는 게 아니라 옆으로 쌓인다."는 어떻게 됐느냐고요? 아, 그런 질문을 할 줄은 몰랐습니다. 그럼 이제 마지막 예제에서 블럭을 5개로 늘려 봅시다. 플로트된 요소들의 부모 요소는 문서의 body 입니다. 브라우저 창(그에 따라, 부모 요소인 body)의 크기에 따라 블럭이 두 번째 줄로 떨어진 걸 눈여겨보세요. 블럭들이 전부 옆으로 늘어설 공간이 충분치 않아서 이렇게 된 거죠. 브라우저 창의 크기를 늘려 보면, 블럭들이 다시 배치되는 걸 볼 수 있습니다. 예제 D에서 직접 한번 해보세요.

Now the blocks are sitting side by side. Great, we’ve got that figured out. But what about that part where I said “given there is enough room in the parent element for each floated element to sit?” I thought you’d never ask. Let’s take our last example and increase the box count five fold. The parent element in this example is the body of our document. Notice that depending on the size of your browser window (and subsequently the parent element body), the blocks drop to a second row, because there is not enough room for all of them to sit side by side. As you resize your browser window to allow more room, you’ll see the blocks rearrange themselves. Try it for yourself, in Example D.

교통정리: clear

float 속성에는 clear라는 사촌이 있습니다. 이 두 속성은 서로 보완하는 관계에요. 기억하고 있겠지만, 플로트된 요소는 먼저 노멀 플로우를 따라서 움직이다가 그걸 벗어나죠. 따라서, 플로트된 요소 뒤에 있는 내용은 반대로 행동하게 되죠. 아, 이제부터 꼬이기 시작하겠군요. 일단 예제를 봅시다. 예제 E에서는, 두 개의 블럭(파란색과 분홍색)을 플로트시키고, 그 바로 다음에는 플로트시키지 않은 두 개의 블럭(녹색과 오렌지색)이 있습니다. 예제 E의 마크업과 CSS입니다:

The float property has a step-brother, clear. The two complement each other in a way that should make you a happy coder. As you may recall, a floated element is first laid out according to the normal flow, then removed from the normal flow. This means that every element that follows a floated element will behave contrary to what you expect. This is where I suspect we might start to get into trouble. Let’s look at a quick example with our blocks again. In Example E, I am going to float two blocks (pink and blue) and directly after those, not float two more blocks (green and orange). Here is the HTML and CSS for Example E:

<div class="block pink float"></div>
<div class="block blue float"></div>
<div class="block green"></div>
<div class="block orange"></div> 
.block {
  width: 200px;
  height: 200px;
}
.float { float: left; }
.pink { background: #ee3e64; }
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #E2A741; }

녹색 블럭이 마음에 드십.. 잠깐만요. 어디 갔지? 아, 분홍색 블럭 바로 아래 있군요. 분홍색 블럭과 파란색 블럭은 모두 우리가 예상한 것 처럼 플로트되어서, 옆으로 늘어섰네요. 하지만 이 두 요소가 일반적인 흐름에서는 벗어났으므로, 녹색 블럭과 오렌지색 블럭은 분홍색과 파란색이 없었던 것처럼 동작합니다. 그래서 녹색 블럭이 분홍색 블럭의 아래로 들어간 겁니다. 그럼 녹색 블럭이 다시 보이게 하려면 어떻게 해야 할까요? clear 속성을 쓰면 됩니다.

How do you like that green block? Oh wait, where is it? It’s there, right underneath the pink block. The pink and blue blocks are both floated and behaving as we would expect, sitting side by side. Since they’re removed from the normal flow however, the green and orange blocks act as if they’re not even there. That is why our green block is hidden undereath our pink block. So how do we make our green block show up again? Enter the clear property.

clear 속성에는 다섯 가지 값을 쓸 수 있습니다: left, right, both, inherit, none. left 값을 쓰면 이 요소의 위쪽 끝이 float: left 속성을 쓴 어떤 요소보다 아래에 있어야 한다는 뜻입니다. right도 마찬가지입니다: 요소는 float: right 속성을 쓴 어떤 요소보다 아래에 있어야 합니다. both를 쓰면, 이 요소는 어느 쪽으로든 플로트된 요소의 아래에 있게 됩니다. inherit 값을 지정하면 부모 요소로부터 clear 속성을 물려받고, none 은 아무것도 지정하지 않는 것이며, 기본값입니다. 새로 알게 된 것들을 되새기면서, 예제 E2를 살펴봅시다. 이번에는 녹색 블럭에 clear 속성을 주어서 플로트 속성의 영향을 없앱니다. 코드를 약간 수정해서 이렇게 만듭니다:

The clear property has five values available: left, right, both, inherit, and none. Assigning a value of left says the top edge of this element must sit below any element that has the float: left property applied to it. The same concept applies for the right value—the element must sit beneath any element that has the float: right property applied to it. Using the both value tells our element that its top edge must sit below any element floated either left or right. The inherit value takes on the clear property from its parent element, while the default value none behaves as you would expect. Arming ourselves with this knowledge, let's look at Example E2. This time we’ll clear our two floats by applying the clear property to our green block. Our slightly modified code looks like this:

<div class="block pink float"></div>
<div class="block blue float"></div>
<div class="block green clear"></div>
<div class="block orange"></div>
.block {
  width: 200px;
  height: 200px;
}

.float { float: left; }
.clear { clear: left; }
.pink { background: #ee3e64; }
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #E2A741; }

녹색 블럭에 clear: left 를 지정했으니, 비록 분홍색 블럭이 문서의 일반적인 흐름에서 벗어나 있더라도 그냥 그 자리에 있는 것으로 간주하고 그 밑으로 들어가라고 지시한 겁니다. clear는 대단히 강력한 속성입니다. 지금 본 것처럼 플로트되지 않은 요소를 문서의 일반적인 흐름으로 돌려놓아서, 예측할 수 있는 방향으로 움직이게끔 합니다. floatclear 속성을 제대로 이해하면 HTML과 CSS를 작성할 때 정말 창의적인 방법을 쓸 수 있게 됩니다.

By assigning a clear: left property value to our green block, we’ve told it to act as if the pink block is in the normal flow of our document, even though it has been removed, and to sit below it. This is an immensely powerful property; as you can see, it helps bring our non-floated elements back into the normal flow, a behavior that we tend to expect by default. That said, knowing and understanding both the float and clear property really starts to open some creative doors when you write your HTML and CSS.

레이아웃에 플로트 사용하기

이제 레이아웃을 다뤄봅시다. 레이아웃이야말로 float 속성이 진가를 드러내는 곳입니다. 다양한 방법으로 전통적인 2단 레이아웃을 만들 수 있는데, 그러한 방법 대부분은 한두 개의 요소를 플로트시키는겁니다. 이제 간단한 예제를 하나 보겠습니다: 2단 레이아웃의 웹사이트인데 왼쪽은 컨텐츠 영역이며 오른쪽에 내비게이션이 있고, 헤더와 푸터가 있습니다. 기사들에는 플로트와 연관된 속성만 쓸 예정입니다. 예제 F를 보세요:

Let’s cover layouts. This is where the float property is incredibly useful. We can achieve the traditional two-column layout in a variety of ways; most of them use one or two floated elements. Let’s take a look at a simple example: a two-column website with the content area on the left, navigation on the right, and a header and footer area to cap it off. For the sake of this article, we’re only going to look at the code related to the floated elements. Here’s Example F:

#container {
  width: 960px;
  margin: 0 auto;
}

#content {
  float: left;
  width: 660px;
  background: #fff;
}

#navigation {
  float: right;
  width: 300px;
  background: #eee;
}

#footer {
  clear: both;
  background: #aaa;
  padding: 10px;
}

자, 뒤에서 무슨 일이 벌어지고 있는지 살펴봅시다. 플로트된 요소들을 담은 부모 요소를 #container라고 합시다. 컨테이너가 없다면, 플로트된 요소들은 좌우로 너무 심하게 치우쳐서, 브라우저 창에 달라붙어 버릴 겁니다. #content는 왼쪽으로, #navigation은 오른쪽으로 플로트시켜서 2단 레이아웃을 만들었습니다. 두 요소의 너비를 합치면 부모 요소 안에 딱 맞게끔 너비를 지정했습니다. 마지막으로 #footer인데, 이 요소에 clear 속성을 지정했습니다. 앞에서 살펴본 것처럼, clear 속성을 지정하면 플로트된 요소 뒤의 요소가 문서의 일반적 흐름으로 돌아옵니다. 여기서는 both 값을 지정해서 #footer#content#navigation 모두의 아래에 있게 만들었습니다.

Ok, let’s talk about what’s going on here. Our containing parent is aptly called #container. This holds our floated elements in place. If we didn’t have it, our floated elements would shoot out to the far left and right of the viewport (our browser window). Next, we have #content and then #navigation. These are our floated elements. We sent #content to the left, and #navigation to the right, to achieve our two-column layout. I’ve defined a width for each, so that they fill our entire parent container. Finally, we have the #footer, on which we’ve set the clear property. As we know from before, this clear property brings the elements following any floated elements back into the normal flow. In this case the #footer has the value both assigned to it, causing our #footer to sit below both the #content and #navigation elements.

clear 속성을 깜박 잊었다면 어떻게 됐을까요? 예제 G를 한번 보세요.

What would have happened had we forgotten to assign the clear property to our footer? Take a look in Example G.

#footer#navigation 아래로 들어갔습니다. 이렇게 된 이유는, #navigation 아래에 #footer가 들어갈 만한 공간이 있고, #footer는 문서의 일반적인 흐름을 따르고 있으므로 이렇게 되는게 맞습니다. 이렇게 되는 게 맞다곤 해도, 이런 걸 바라는 건 아니지요? floatclear가 상호작용하는 것을 살펴봐야겠습니다.

Our #footer has slid up underneath the #navigation. This is happening because there is room underneath the #navigation for the #footer to fill, and given the normal flow that we work within, this is actually the correct behavior. But it’s definitely not what we’re looking for, is it? You can start to see the interaction between the float and clear property and how they complement each other so well.

당신이 나처럼 결벽증 비슷한 면이 있다면, 예제 F에서 #content#navigation의 높이가 서로 다른걸 눈치챘을 겁니다. 이런 현상을 고칠 방법이 몇 가지 있지만, 그러한 것은 이 글의 범위를 벗어납니다. Dan Cederholm이 쓴 가짜 컬럼을 꼭 읽어보세요. 내용과 무관하게 똑같은 높이로 보이게 만드는 법을 설명합니다.

If you have obsessive compulsive disorder, like I do, you may notice that back in Example F there are unequal heights on #content and #navigation; there are several ways to address that, but that’s out of this article’s scope. I highly suggest reading Faux Columns by Dan Cederholm to learn how to make the heights appear to be the same, no matter what the content.

플로트를 가장 먼저

여태까지는 골치 아플 일이 없는 간단한 예제만 해봤습니다. 하지만 플로트로 작업할 때는 몇 가지 염두에 둘 주의사항이 있습니다. 놀랍게도, 주의사항 중 가장 큰 건 CSS가 아니라 HTML에 관한 문제입니다. 플로트를 지정한 요소를 HTML 어디에 놓느냐에 따라 결과는 상당히 많이 달라질 수 있습니다. 예제 H를 봐주세요.

So far we’ve seen some pretty straightforward examples that don’t create many headaches. There are, however, some gotchas that we have to watch for when working with the float property. Surprisingly one of the biggest gotchas is not with the CSS but rather with the HTML itself. Where you place your floated element in your HTML can cause different results. Take a look at Example H.

조그만 박스 안에 오른쪽으로 플로트된 이미지가 있고, 그걸 둘러싼 텍스트가 있습니다. CSS는 단순합니다:

Here we have a nice small-ish box that has an image floated on the right and some text surrounding it. Our CSS is basic:

#container {
  width: 280px;
  margin: 0 auto;
  padding: 10px;
  background: #aaa;
  border: 1px solid #999;
}

img {
  float: right;
}

부모 요소인 #container는 좀 좁지만 플로트된 img는 담을 수 있는 정도입니다. HTML은 이렇습니다:

Our parent element, #container has a narrow width keeping our floated element, the img, within its bounds. Our HTML looks like so:

<div id="container">
  <img src="image.gif" />
  <p>This is some text contained within a
small-ish box. I'm using it as an example
of how placing your floated elements in different
orders in your HTML can affect your layouts. For
example, take a look at this great photo
placeholder that should be sitting on the right.</p>
</div>

원하는 대로 됐습니다. 하지만 이 예제를 아주 조금만 바꾸면 어떻게 될까요? 예제 Iimg 요소를 텍스트 문단 뒤로 이동시켰습니다:

This basic concept gives us the desired result, but what if we took this same example and rearranged the HTML just slightly? In Example I we’ll move the img to come after our paragraph of text:

<div id="container">
  <p>This is some text contained within a
small-ish box. I'm using it as an example
of how placing your floated elements in different
orders in your HTML can affect your layouts. For
example, take a look at this great photo
placeholder that should be sitting on the right.</p>
  <img src="image.gif" />
</div>

바람직하지 못한 결과가 나왔군요. 이미지가 오른쪽으로 플로트된 것은 맞지만, 우리가 원하는 위치인 오른쪽 위는 아닙니다. 더욱 안 좋은 건, 이미지가 마치 컨테이너의 아래쪽에 매달린 것처럼 보인다는 거죠. 어떻게 된 걸까요? 먼저, 이럴 때 가장 잘 맞는 규칙은 플로트를 가장 먼저 입니다. 다시 말해, 마크업을 할 때는 항상 플로트된 요소가 가장 앞에 있도록 하고, 그 요소와 상호작용할 다른 요소(위 예제에서는 문단이죠)가 그 뒤에 있도록 하는 겁니다. 이렇게 하면 대부분 원하는 결과를 얻을 수 있습니다. 둘째, 이미지가 부모 요소의 하단에 매달린 것처럼 보이는 이유는, 소위 붕괴(collapsing)라 부르는 것 때문입니다. 그럼 붕괴가 무엇이고, 이 문제를 어떻게 해결하는 게 최상인지 알아봅시다.

Our results are less than desirable. Our image is floated to the right, but it’s no longer in the top corner where we wanted it, falling instead underneath our paragraph; worse yet, it seems to be sticking out of the bottom of our #container parent element. What is going on? First, a rule that I have found that works nicely for my layouts is float first. That is, in my HTML, I almost always place my floated elements first in the markup, and before any non-floated elements that my float will interact with, such as the paragraph in the example above. Most of the time, this gives the desired result. Second, the reason that the image is seemingly sticking out of the bottom of our #container element has to do with something called collapsing. Let’s talk about what collapsing is and how we can best address it.

콜랩싱

플로트된 요소 a를 포함하는 부모 요소가, a가 플로트되지 않았다면 자연스럽게 늘어났을 크기만큼 늘어나지 않아서, 플로트된 자식 요소를 완전히 감싸지 못하는 현상을 콜랩싱이라 부릅니다. 위의 예제 I에서, 부모 요소인 #container는 플로트된 img요소가 아예 없었던 것처럼 "콜랩스" 되었습니다. ((역주: collapse는 붕괴, 경계를 알아볼 수 없게 됨 등을 뜻합니다. 이를 말하는 적당한 용어가 없어 보통 발음하는 대로 적었습니다.)) 이러한 것은 브라우저 버그가 아니며, 예측할 수 있고 올바른 표현입니다. 플로트된 요소는 처음에 문서의 일반적인 흐름 속에 있다가 빠져나오는 것이므로, #containerimg가 자신의 안에 있는 것으로 간주하지 않고, 없는 것처럼 행동합니다. Eric Meyer가 이에 관한 멋지고 상세한 글을 쓴 것이 있으니 참고하기 바랍니다. 콜랩싱에 관해 좋은 소식은, 이를 해결할 방법이 많이 있다는 겁니다. clear 속성을 응용하는 것이라 짐작하고 있다면, 제대로 짚은 겁니다.

Collapsing is when a parent element that contains any number of floated elements doesn’t expand to completely surround those elements in the way it would if the elements were not floated. In Example I above, our parent element, #container, collapsed as if the floated img element wasn’t even there. This is not a browser bug, but rather an expected and proper behavior. Since floated elements are originally calculated in the normal flow and then removed, the #container element doesn’t consider it within its bounds and therefore acts as if it isn’t even there. As a note, Eric Meyer has a wonderful article on this topic called Containing Floats that goes into much more depth and is a highly useful resource. The good news is, we can remedy this problem in a myriad of ways; if you’re guessing that it has to do with the clear property then you’re on the right track.

콜랩싱 문제를 해결하기 위해 가장 널리 쓰이는 방법은, clear 속성을 준 요소 하나를 플로트된 요소 뒤에 붙이는 겁니다. 이렇게 하면 부모 요소가 플로트된 요소 다음에 다시 흐름을 만들게 됩니다. 예제 J는 예제 I와 똑같지만, 이번에는 요소를 하나 추가했습니다:

One of the most common ways to fix a collapsed parent element is to place an element with the clear property after our floated element. This will cause the parent to begin reflowing after the floated element. It may be easier to show this in action. Look at the HTML for Example J which is the same as our previous example, but with one extra element added:

<div id="container">
  <p>This is some text contained within a
small-ish box. I'm using it as an example
of how placing your floated elements in different
orders in your HTML can affect your layouts. For
example, take a look at this great photo
placeholder that should be sitting on the right.</p>
  <img src="image.gif" />
  <div style="clear: right;"></div>
</div>

div를 하나 넣고, 인라인 스타일로 clear: right를 지정했습니다. 이렇게 하면 #container에서 플로트된 이미지의 높이를 다시 계산하고, 그 주위에 흐름을 만듭니다. 이 해결책은 잘 동작하긴 하지만, 군더더기 마크업이 들어가야 하니까 최선이라고 할 수는 없습니다. CSS만으로 전부 다 할 수 있다면 한결 멋지겠지요. 몇 가지 방법이 더 있으니, 바로 살펴봅시다.

By placing a div with an inline style of clear: right we’ve managed to get our #container to clear our floated image by having it recalculate its height now that there’s an element sitting below it. While this solution works, it may not be the most elegant because we had to add extra markup to our document. It would have been sexier to handle this with CSS. There are a few ways to do that, so let’s take a look at one of them right now.

이런 예제를 생각해 봅시다. 플로트된 이미지 세 개를 포함하고 있는 부모 요소가 있습니다. 마크업은 이렇게 됩니다:

Consider this example, a parent element containing three floated images. Our HTML looks like this:

<div id="container">
  <img src="image.gif" />
  <img src="image.gif" />
  <img src="image.gif" />
</div>

CSS는 이렇습니다:

and our CSS looks like this:

#container {
  width: 260px;
  margin: 0 auto;
  padding: 10px 0 10px 10px;
  background: #aaa;
  border: 1px solid #999;
}

img {
  float: left;
  margin: 0 5px 0 0;
}

이걸 실제로 만들어 보면, 부모 요소에 플로트된 이미지가 하나도 들어 있지 않은 걸 보게 될 겁니다. 다시 한 번 말하지만, 이건 제대로 된 겁니다 - 플로트된 요소는 문서의 일반적인 흐름에서 빠져나가고, #container는 자신이 비어 있다고 간주합니다. 예제 K에서 확인해 보세요.

When you look at this in action, you’ll quickly realize that our parent element is not containing our floated images. Again, this is expected because floated elements are removed from the flow, so according to our parent element, #container, it’s empty. Take a look at this in Example K.

자 이제 앞에서 했던 것처럼 군더더기 마크업을 추가하지 않고 CSS만으로 이 문제를 해결해 보겠습니다. 이 방법은 부모 요소가 자기 내부에 플로트된 요소가 있을 때마다 자신을 클리어하는 방법입니다. 이 방법은 overflow 속성의 값을 hidden으로 만듭니다. 기억해 둘 것은, overflow 속성을 원래 이런 의도로 만들어진 요소는 아니며, 내용이 숨어버린다거나 의도하지 않은 스크롤바가 생기는 등의 부작용이 생길 수 있습니다. 여기여기에서 이 방법이 어떻게 고안됐는지, 어떤 점을 유의해야 하는지 더 읽어볼 수 있습니다. 우리 예제에서는 #containeroverflow: hidden을 적용합니다.

Now let’s try to remedy this with CSS instead of adding extra HTML markup to our document as we did before. There is a method that allows a parent element to clear itself of any floated elements inside it. It uses a CSS property called overflow with a value of hidden. Note that the overflow property was not intended for this type of use, and could cause some issues such as hiding content or causing unwanted scrollbars to appear. You can read more about how it came to be and some of its caveats here and here. For our example however, we’ll apply the overflow: hidden property to our parent element, #container:

#container {
  overflow: hidden;
  width: 260px;
  margin: 0 auto;
  padding: 10px 0 10px 10px;
  background: #aaa;
  border: 1px solid #999;
}

결과는 예제 L에서 볼 수 있습니다. 괜찮지 않나요? 가상 요소 ::after를 사용한 비슷한 방법도 있습니다. 우리 예제에 적용하면, 이렇게:

Our results are in Example L. Pretty cool right? Another method which gives similar results with fewer caveats uses the pseudo selector :after. Using our example, the code is:

#container:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

#container 다음에 CSS를 이용해서, 비어 있지 않은(이 예제에서는 마침표를 하나 넣었습니다.) 가상 요소를 하나 추가하고, 높이는 0으로, 보이지 않게 만듭니다. 이 방법에 대한 자세한 해설을 Position is Everything에서 볼 수 있습니다.

Here, the CSS is placing a new element after our #container element that has some content in it (in this case, a period), and setting it to be hidden with no height. You can find a very thorough and detailed overview of this technique at Position is Everything.

Eric Meyer 역시, 위에서 언급한 글에서 이 문제를 해결할 세 번째 방법을 설명합니다. CSS 2.1 명세에 따르면:

Finally, Eric Meyer explains a third way to tackle this problem in his article referenced above, Containing Floats. According to the CSS Spec 2.1:

플로트된 요소는 그 자손인 플로트된 요소 전부를 담을 수 있을 만큼 커집니다.

a floated element will expand to contain any floated elements that descend from it.

즉 우리 예제에서는, 컨테이너 요소에 플로트를 적용하면 이미지와 텍스트를 모두 담을 수 있을 만큼 커집니다.

So in this case, floating our container element would cause it to contain our image and paragraph the same way as the methods described above.

이 모든 해결책이 하는 일은 결국 한가지입니다. 부모 요소가 플로트된 자식 요소를 흐름 속에 있는 것으로 인식하게끔 하는 겁니다. 각각의 방법은 그 나름의 장점과 유용함이 있습니다. 이러한 것을 익혀서 상황에 맞게 쓸 줄 알아야 합니다.

Ultimately all of these solutions are doing the same thing. They are making the parent elements respect the flow of their floated children. Each one has its merits and usefulness. You should learn about each and then apply the ones that work best for your given situation.

머리를 쥐어뜯게 하는 것들

플로트와 관련된 브라우저 버그가 몇가지 있습니다. 더블 마진 버그, 3픽셀 텍스트 버그 같을 것 말이죠. 두 가지 모두 이 글의 초점에서는 벗어나지만, 쉬운 해결책이 있으니 오래된 브라우저를 지원해야 하더라도 걱정하지 않아도 됩니다.

Believe it or not there are a few browser bugs that floated elements can bring on, such as the double margin bug and the 3px Text-Jog. Both of these are outside this article’s scope, but rest assured they are both easily remedied if you want to support older browsers.

결론

float 속성을 잘 쓰면 멋진 레이아웃을 자신감 있게 만들 수 있습니다. float가 어떻게 동작하는지, float와 clear가 따르는 원리를 이해하면 그 속성을 효과적으로 쓸 수 있는 단단한 기초를 마련할 수 있습니다.

Using the float property can pad your layout technique toolbox in some very cool and responsive ways. Understanding how they work and the principles by which they behave will give you a solid foundation for using floats effectively.

댓글 (1550)