2.9 CSS3 Float

요소 정렬을 위한 레이아웃의 핵심

float 속성은 주로 layout을 구성하기 위해 사용되는 핵심 기술이다. layout의 가장 큰 목적은 1개 이상의 요소를 원하는 위치에 정렬시키는 것이다.

CSS Grid Layout example

float 속성은 본래 다음 예제와 같이 이미지 주위를 텍스트로 감싸기 위해 만들어진 것이다.

<!DOCTYPE html>
<html>
<head>
  <style>
    img {
      float: left;
      margin-right: 10px;
    }
  </style>
</head>
<body>
  <img src="http://poiemaweb.com/img/doug.jpg">
  <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</body>
</html>

float 속성은 해당 요소를 떠 있게(부유하게) 한다. 여기서 떠 있다(float)는 의미는 요소가 기본 레이아웃 흐름에서 벗어나 요소의 모서리가 페이지의 왼쪽이나 오른쪽에 이동하는 것이다. float 속성을 사용할 때 요소의 위치를 고정시키는 position 속성의 absolute를 사용하면 안된다.

속성값 Description
none 요소를 떠 있게 하지 않는다. (기본값)
right 요소를 오른쪽으로 이동시킨다
left 요소를 왼쪽으로 이동시킨다.

css float

1. 정렬

float 속성을 사용하지 않은 블록 요소들은 수직으로 정렬된다. float:left; 속성을 사용하면 왼쪽부터 정렬되고, float:right; 속성을 사용하면 오른쪽부터 정렬된다.

오른쪽 정렬의 경우, 먼저 기술된 요소가 가장 오른쪽에 출력되므로 출력 순서가 역순이 된다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      color: white;
      font-weight: bold;
      font-size: 50px;
      border-radius: 6px;
      width: 200px;
      height: 200px;
      margin: 10px;
      padding: 10px;
    }
    .d1 {
      /*float: left;*/
      float: right;
      background: red;
    }
    .d2 {
      /*float: left;*/
      float: right;
      background: orange;
    }
  </style>
</head>
<body>
  <div class="d1"> 1 </div>
  <div class="d2"> 2 </div>
</body>
</html>

float 속성은 좌측, 우측 정렬만 할 수 있다. 중앙 정렬은 margin 속성을 사용해야 한다.

div {
  width: 960px;
  margin: 0 auto;
}

width 속성의 기본값은 auto이므로 width 속성값을 지정하지 않은 block 요소는 기본적으로 width: auto가 되며 부모 요소의 가로폭을 가득 채운다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      color: white;
      font-weight: bold;
      font-size: 30px;
      line-height: 50px;
      height: 50px;
      margin: 0 10px;
      padding: 10px;
    }
    .d1 {
      background: red;
    }
    .d2 {
      background: orange;
    }
  </style>
</head>
<body>
  <div class="d1"> div </div>
  <div class="d2"> div </div>
</body>
</html>

block 요소에 float 속성이 선언되면 width가 inline 요소와 같이 content에 맞게 최소화되고 다음 요소 위에 떠 있게(부유하게) 된다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      color: white;
      font-weight: bold;
      font-size: 30px;
      line-height: 50px;
      height: 50px;
      margin: 0 10px;
      padding: 10px;
    }
    .d1 {
      float: left;
      background: red;
    }
    .d2 {
      background: orange;
    }
  </style>
</head>
<body>
  <div class="d1"> float: left; </div>
  <div class="d2"> div </div>
</body>
</html>

2. float 속성 관련 문제 해결 방법

2.1 float 속성 요소와 float 속성이 선언되지 않은 요소간 margin이 사라지는 문제

위 예제를 보면 두 요소는 차례대로 정렬된 것처럼 보이지만 사실은 float 속성이 선언된 요소가 다른 요소 위에 떠 있는(부유하고 있는) 상태이다. 따라서 두 요소간의 margin은 제대로 표현되지 않는다.

이것은 두번째 요소에 float 속성을 선언하지 않았기 때문에 발생하는 박스 모델 상의 문제이다. 이 문제를 해결하는 가장 쉬운 방법은 float 속성을 선언하지 않은 요소(.d2)에 overflow: hidden 속성을 선언하는 것이다.

overflow: hidden 속성은 자식 요소가 부모 요소의 영역보다 클 경우 넘치는 부분을 안보이게 해주는 역할을 하는데 여기서는 float 속성이 없어서 제대로 표현되지 못하는 요소를 제대로 출력해준다.

<!DOCTYPE html>
<html>
<head>
  <style>
    div {
      color: white;
      font-weight: bold;
      font-size: 30px;
      line-height: 50px;
      height: 50px;
      margin: 0 10px;
      padding: 10px;
    }
    .d1 {
      float: left;
      background: red;
    }
    .d2 {
      overflow: hidden;
      background: orange;
    }
  </style>
</head>
<body>
  <div class="d1"> float: left; </div>
  <div class="d2"> div </div>
</body>
</html>

두번째 요소에도 float 속성을 선언하면 overflow: hidden 속성은 선언하지 않아도 되지만 너비가 최소화된다.

2.2 float 속성을 가진 자식 요소를 포함하는 부모 요소의 높이가 정상적으로 반영되지 않는 문제

아래 예제를 보면 float 속성이 선언된 두개의 자식 요소를 포함하는 부모 요소의 높이가 정상적인 값을 가지지 못하는 문제가 발생한다. float 요소는 일반적인 흐름 상에 존재하지 않기 때문에 float 요소의 높이를 알 수 없기 때문인데 이 문제는 부모 요소 이후에 위치하는 요소의 정렬에 문제를 발생시킨다.

<!DOCTYPE html>
<html>
<head>
  <style>
    .wrap {
      color: white;
      text-align: center;
      padding: 10px;
      background-color: #def0c2;
    }
    .d1 {
      float: left;
      width: 49%;
      margin-right: 2%;
      padding: 20px 0;
      background-color: #59b1f6;
    }
    .d2 {
      float: left;
      width: 49%;
      padding: 20px 0;
      background-color: #ffb5b4;
    }
  </style>
</head>
<body>
  <div class="wrap">
    <div class="d1">dv1</div>
    <div class="d2">dv2</div>
  </div>
  <div style="background:red;padding:10px;color:white;">dv3</div>
</body>
</html>

이 문제를 해결하는 가장 쉬운 방법은 float 속성을 가진 요소의 부모 요소(wrap)에 overflow: hidden 속성을 선언하는 것이다.

.wrap {
  color: white;
  text-align: center;
  padding: 10px;
  background-color: #def0c2;
  overflow: hidden;
}

다른 방법으로 부모 요소에 float 속성을 부여하는 방법도 있다. 하지만 부모 요소의 너비는 float된 두개의 자식요소의 컨텐츠를 표현할 수 있는 만큼만으로 작게 줄어들게 된다. 권장할 수 있는 방법은 아니다.

wrap 영역이 끝나기 직전 빈 요소를 만들고 clear:both 속성을 부여하는 방법도 가능하다. 하지만 의미 없는 빈 요소를 사용하여야 하기 때문에 이 방법 역시 권장할 수 있는 방법은 아니다.

<!DOCTYPE html>
<html>
<head>
  <style>
    .wrap {
      color: white;
      text-align: center;
      padding: 10px;
      background-color: #def0c2;
      /*overflow: hidden;*/
    }
    .d1 {
      float: left;
      width: 49%;
      margin-right: 2%;
      padding: 20px 0;
      background-color: #59b1f6;
    }
    .d2 {
      float: left;
      width: 49%;
      padding: 20px 0;
      background-color: #ffb5b4;
    }
    .clear {
      height: 0;
      clear: both;
    }
  </style>
</head>
<body>
  <div class="wrap">
    <div class="d1">dv1</div>
    <div class="d2">dv2</div>
    <div class="clear"></div>
  </div>
  <div style="background:red; padding:10px; color:white;">dv3</div>
</body>
</html>

overflow: hidden;과 함께 많이 사용되는 방법은 ::after 가상 요소 선택자를 이용하는 것이다. 가상 요소 선택자는 CSS2 문법(:after)과 CSS3 문법(::after)이 있는데 IE8까지 지원하는 CSS2 문법을 사용하는 편이 좋다. 부모 요소에 clearfix 클래스만 추가하면 되기 때문에 가장 깔끔하고 간편하므로 이 방법을 사용하는 것을 추천한다.

<!DOCTYPE html>
<html>
<head>
  <style>
    .wrap {
      color: white;
      text-align: center;
      padding: 10px;
      background-color: #def0c2;
      /*overflow: hidden;*/
    }
    .clearfix:after {
      content: "";
      display: block;
      clear: both;
    }
    .d1 {
      float: left;
      width: 49%;
      margin-right: 2%;
      padding: 20px 0;
      background-color: #59b1f6;
    }
    .d2 {
      float: left;
      width: 49%;
      padding: 20px 0;
      background-color: #ffb5b4;
    }
  </style>
</head>
<body>
  <div class="wrap clearfix">
    <div class="d1">dv1</div>
    <div class="d2">dv2</div>
  </div>
  <div style="background:red;padding:10px;color:white;">dv3</div>
</body>
</html>

또 다른 방법은 float 속성 대신 display: inline-block;을 설정하는 것이다. 주의해야야 점은 inline-block 속성 요소를 연속 사용하는 경우, 좌우에 정의하지 않은 space(4px)가 자동 지정되는 것이다.

<!DOCTYPE html>
<html>
<head>
  <style>
    .wrap {
      color: white;
      text-align: center;
      padding: 10px;
      background-color: #def0c2;
      /*overflow: hidden;*/
    }
    .d1 {
      /*float: left;*/
      display: inline-block;
      width: 49%;
      /*margin-right: 2%;*/
      padding: 20px 0;
      background-color: #59b1f6;
    }
    .d2 {
      /*float: left;*/
      display: inline-block;
      width: 49%;
      padding: 20px 0;
      background-color: #ffb5b4;
    }
  </style>
</head>
<body>
  <div class="wrap">
    <div class="d1">dv1</div>
    <div class="d2">dv2</div>
  </div>
  <div style="background:red;padding:10px;color:white;">dv3</div>
</body>
</html>

2. Layout Examples

2.1 2-Column Layout Example

2-column-layout

2.2 3-Column Layout Example

3-column-layout

Reference

Back to top
Close