CSS float 주의점과 몇 패턴들


CSS float

[CSS 목록 보기]

float 프로퍼티는 한 줄에 여러 HTML 요소들을 배열할 때 사용한다. float 을 적용할 때 조심할 점은 영역을 분리해줘야 한다는 것이다. 영역분리는 overflow 프로퍼티 로 구현할 수도 있고, clear 프로퍼티로 구현할 수 있다. 기본예제에서부터 단계별로 알아보자.

1. float: left

아래와 같이 HTML 요소(div)들을 옆으로 나란히 배열하고 싶을 때가 있다.

1
2
3
4

이를 구현하기 위해 다양한 방법(float, flex, table, li)들이 있지만, 이번 포스트에서는 float에 대해서 알아보자. 사용 방법이 굉장히 간단하므로 바로 예제를 들어보자. 아래 코드에서 float: left; (line 3)를 눈여겨보자. 이 부분이 없다면 div는 display 기본속성값이 block이기 때문에 한 줄에 나열되지 않고, 수직방향으로 쌓이게 된다. 하지만 해당 div에 float을 적용하면 한 줄에 떠있게 (=float) 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
  div.box {
    float: left;
    width: 30px; height: 30px;
    border: 1px solid rgb(20, 20, 20);
    background-color: rgb(200, 0, 0);
    margin: 0 10px;
    color: white;
    line-height: 100px;
    text-align: center;
  }
</style>
 
<div id=“box_container”>
  <div class=“box”>1</div>
  <div class=“box”>2</div>
  <div class=“box”>3</div>
  <div class=“box”>4</div>
</div>
cs

참고로 화면의 크기가 작아져서 한 줄에 HTML 요소를 다 넣지 못하게 되면, 그 부분부터 다음줄로 내려가서 표시하게 된다.

1
2
3
4
5
6
7
8
9
10

2. float: right

반대로 오른쪽으로 정렬하고 싶다면 float: right를 사용하면 된다. 위에 제시된 예제에서 float 프로퍼티만 바꿔서 표시(line 3)해보자. 주의 할 점은 박스들이 오른쪽에서 왼쪽 방향으로 쌓인다는 점이다. 즉, 숫자를 보면 4 3 2 1 순으로 나열된다. 1 2 3 4 순이 아니라는 점을 조심하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
  div.box {
    float: right;
    width: 100px; height: 100px;
    border: 1px solid rgb(20, 20, 20);
    background-color: rgb(200, 0, 0);
    margin: 0 10px;
    color: white;
    line-height: 100px;
    text-align: center;
  }
</style>
 
<div id=“box_container”>
  <div class=“box”>1</div>
  <div class=“box”>2</div>
  <div class=“box”>3</div>
  <div class=“box”>4</div>
</div>
cs

결과:

1
2
3
4


3. 마지막으로 주의할 점: 패턴으로 기억하자.

float의 사용방법은 아주 간단하지만, 주의할 점이 하나 있다. 바로 영역분리가 필요하다는 것이다. 여기서는 영역분리를 overflow로 구현할 건데, 부모 HTML요소에 overflow: hidden으로 설정해주면 된다. 그렇지 않으면 뒤에 따라오는 HTML요소도 덩달아 같은 열에 위치하게 된다. 참고로 부모 요소의 display는 block 또는 inline-block이어야 한다.

예제를 보자. 이해하기 쉽게 하기위해, 따라 오는 HTML요소( line 22. div#main )의 백그라운드에 색깔-회색( line 13 )을 입혔다. 결과를 보면, 레드박스 4, 3, 2, 1이 오른쪽으로 잘 정렬되어 있지만, 다음에 따라 오는 HTML 요소 div#main는 기대와 다르게 같은 열에 위치하게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<style>
  div.box {
    float: right;
    width: 30px; height: 30px;
    border: 1px solid rgb(20, 20, 20);
    background-color: rgb(200, 0, 0);
    margin: 0 10px;
    color: white;
    line-height: 30px;
    text-align: center;
  }
  div#main {
    background-color: rgb(20, 20, 30, 0.2);
  }
</style>
<div id=“box_container”>
  <div class=“box”>1</div>
  <div class=“box”>2</div>
  <div class=“box”>3</div>
  <div class=“box”>4</div>
</div>
<div id=“main”><p>본문내용을 입력합니다.</p></div>
cs

결과:

1
2
3
4

본문내용을 입력합니다.

이 문제점을 해결하기 위해서, 레드박스의 영역(div#box_container)과 다른 부분의 영역을 구분지을 필요가 있다. 이 때 사용하는 것이 overflow: hidden 이다. 코드를 다음과 같이 고쳐보자. div#box_container 부분(line 16)을 주의 깊게 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<style>
  div.box {
    float: right;
    width: 30px; height: 30px;
    border: 1px solid rgb(20, 20, 20);
    background-color: rgb(200, 0, 0);
    margin: 0 10px;
    color: white;
    line-height: 30px;
    text-align: center;
  }
  div#main {
    background-color: rgb(20, 20, 30, 0.2);
  }
  div#box_container {
    overflow: hidden;
  }
</style>
<div id=“box_container”>
  <div class=“box”>1</div>
  <div class=“box”>2</div>
  <div class=“box”>3</div>
  <div class=“box”>4</div>
</div>
<div id=“main”><p>본문내용을 입력합니다.</p></div>
cs

결과:

1
2
3
4

본문내용을 입력합니다.

정리해보자면, float으로 한 줄 정리를 할 땐, 영역 분리가 필요하고 부모요소에 overflow: hidden으로 구현한다.
일종의 패턴으로 기억하는 것이 좋다. float 사용시 부모요소에 overflow: hidden !!


4. 추가로 하나 더: 다른 방법으로 구현하기 clear: both

영역을 분리해주는 방법으로 overflow: hidden을 많이 사용되기는 하지만, 다른 방식으로도 영역분리 구현이 가능하다. 따라오는 HTML 요소에 clear: both 프로퍼티를 추가함으로써 해결한다. clear 속성은 float특성을 제거할 때 사용한다. 다음 예제를 보면 쉽게 이해할 수 있을 것이다. div#main 안에 clear: both; 프로퍼티(line 14)를 눈여겨 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
  div.box {
    float: right;
    width: 30px; height: 30px;
    border: 1px solid rgb(20, 20, 20);
    background-color: rgb(200, 0, 0);
    margin: 0 10px;
    color: white;
    line-height: 30px;
    text-align: center;
  }
  div#main {
    background-color: rgb(20, 20, 30, 0.2);
    clear: both;
  }
</style>
<div id=“box_container”>
  <div class=“box”>1</div>
  <div class=“box”>2</div>
  <div class=“box”>3</div>
  <div class=“box”>4</div>
</div>
<div id=“main”><p>본문내용을 입력합니다.</p></div>
cs

결과:

1
2
3
4

본문내용을 입력합니다.

코드 발전시키기 #1
사실 위 코드처럼 직접 div#mainclear: both를 직접 입력해도 되지만, HTML 태그의 class를 이용하여 일반화할 수 있다. 앞선 코드 방식의 귀찮은 점은, float이 필요한 HTML요소가 많이 등장하게 되면, float이 끝나는 다음 요소에 clear: both;를 반복 기입해줘야한다는 것이다. 만약 다 기입해줬다고 치더라도, HTML 수정이 필요한 상황이 발생한다면, CSS Style로 돌아가서 해당 부분을 선택자를 찾아가서 수정해야하는 일이 발생한다. 생각만 해도 성가신 작업이 될 것이다.

이 때 사용할 수 있는 것이 클래스 선택자이다.[참고2. 클래스 선택자] 아래 코드(line 15 – 17)처럼 .clear 스타일을 지정 하고, 원하는 HTML 요소에 class=”clear” 추가하는 식으로 문제를 해결할 수 있다. 관리가 한결 쉽고, 가독성이 증가한다. 코딩을 할 때, 중복된 내용을 두 번 이상 반복하는 것은 매우 좋지 않은 습관이다. 흔히 DRY하게 작성하라라고 말한다. Don’t Repeat Yourself!

아래 코드의 맨 마지막 줄(line 25)에 있는 class 부분을 눈여겨 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<style>
  div.box {
    float: right;
    width: 30px; height: 30px;
    border: 1px solid rgb(20, 20, 20);
    background-color: rgb(200, 0, 0);
    margin: 0 10px;
    color: white;
    line-height: 30px;
    text-align: center;
  }
  div#main {
    background-color: rgb(20, 20, 30, 0.2);
  }
  .clear {
    clear: both;
  }
</style>
<div id=“box_container”>
  <div class=“box”>1</div>
  <div class=“box”>2</div>
  <div class=“box”>3</div>
  <div class=“box”>4</div>
</div>
<div id=“main” class=“clear”><p>본문내용을 입력합니다.</p></div>
cs

코드 발전시키키 #2
이미 우아하게 class를 이용하여, float을 사용한 모든 HTML 요소들의 CSS style부분에 중복적으로 clear: both를 하드코딩할 필요가 없어졌다. 하지만 여기서 멈추지 말고, 조금 더 발전시켜 보자.

문제점을 조금 더 생각해보자. 만약 나중에 홈페이지를 고쳐야 할 상황이 와서, 위 코드(line 25) div#main 위에 새로운 div 태그 넣는다고 가정해보자. 그러면 우리는 class=”clear” 부분을 지우고, 새롭게 끼어 넣을 div 태그에 옮겨 적어야 할 것이다. 뭐, 한번쯤은 이런 과정을 할 수 있겠지만, 아주 거대한 홈페이지를 유지/보수 해야한다면, 이러한 과정은 매우 귀찮을 뿐만 아니라 실수하기 쉽다.

따라서 아래 코드 line 24 처럼 종료시키는 요소를 넣을 수 있다.
<div class=”clear”></div>
div 요소는 비어져 있기 때문에 화면에 표시되지 않고, 순전히 clear: both의 명령어 역할만 하게 된다. 이렇게 함으로써 따라 오는 요소(여기서는 div#main, line 26)로부터 clear: both 기능을 독립시킬 수 있고, 수정시 제약을 받지 않게 된다. 코딩의 SOLID 원칙 중에 개방/폐쇄 원칙(O, Open/Closed Principle)에 해당한다. 확장 가능성은 열어 두지만, 수정 가능성은 닫아야 한다는 원칙이다. 즉, 수정이 필요하지 않은 부분은 밖으로 빼내서 독립적으로 위치시킴으로써, 해당 부분의 수정 가능성을 닫을 수 있다. 하나의 HTML 요소에 다 우겨넣는다면, 매번 수정에 영향을 받게 되고, 이러한 복잡한 코드는 관리를 어렵게 만들어 실수를 유발하게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style>
  div.box {
    float: right;
    width: 30px; height: 30px;
    border: 1px solid rgb(20, 20, 20);
    background-color: rgb(200, 0, 0);
    margin: 0 10px;
    color: white;
    line-height: 30px;
    text-align: center;
  }
  div#main {
    background-color: rgb(20, 20, 30, 0.2);
  }
  .clear {
    clear: both;
  }
</style>
<div id=“box_container”>
  <div class=“box”>1</div>
  <div class=“box”>2</div>
  <div class=“box”>3</div>
  <div class=“box”>4</div>
  <div class=“clear”></div>
</div>
<div id=“main”><p>본문내용을 입력합니다.</p></div>
cs


float: center 구현하기

float 프로퍼티는 left와 right를 가질 수 있지만, 아쉽게도 center를 가질 수 없다. 만약 float: center가 있다면 다음과 같은 정렬을 구현할 수 있을 것이다.

1
2
3
4
5
6
7
8

float: center를 구현하는 방법으로 여러가지 방법이 있다. [참고1. float: center 구현]


참고
[1] float: center 구현
[2] 클래스 선택자
[CSS 목록 보기]

Leave a Reply