CSS에서 float 속성을 활용하다가 레이아웃이 모두 무너진 적 있었을 것이다. 나도 초기에 CSS를 공부할 때 float 속성 때문에 많이 애먹었었다. 기껏 float 속성 작성하여 왼쪽으로 정렬시켜놓았더니 부모 요소에 있던 <div> 태그가 자기 멋대로 놀고 있고.. 요즘 공부를 하면서 느낀 것인데, 이러한 사소한 속성 하나하나에도 그 속성의 이름에 담긴 의미를 제대로 이해하면 사용하는데 도움이 많이 된다는 것을 느꼈다.
float의 사전적 의미는 아래와 같다.
뭐가 뜻이 좀 있는 것 같은데, 명사는 제쳐두고 동사만 보자. '(물 위나 공중에서) 떠가다', '(가라앉지 않고 물에)뜨다'의 의미를 가지고 있다. float 속성 또한 이와 다르지 않다. 웹 페이지의 어떤 요소에 float 속성을 추가한다면, 그 요소는 마치 공중에 띄워진 것이라 생각하면 된다.
이해를 위해 바로 코드를 작성하여 확인해보자. 아래는 실습을 위한 HTML 태그와 CSS이다.
<div class = "total">
<div class = "child red"></div>
<div class = "child yellow"></div>
<div class = "child blue"></div>
</div>
* {
box-sizing: border-box;
}
total {
margin: 0 auto;
width: 600px;
background-color: grey;
}
.child {
width: 300px;
height: 200px;
text-align: center;
line-height: 200px;
font-weight: 600;
}
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
.blue {
background-color: blue;
}
위와 같이 코드를 작성하면 웹 브라우저에는 아래와 같이 뜬다.
total 클래스를 가진 div의 배경색을 회색으로 설정하였다. 이는 자식으로 들어온 div 요소들이 부모 요소 내에서 점유하는 공간을 눈으로 직접 확인할 수 있도록 하기 위함이다.
total 클래스를 가진 div는 넓이로 600px를 가지며, 자식 div들은 300px의 넓이를 가진다. total 클래스를 가진 div에는 별도의 height를 주지 않았으나, 이전 block 속성에 대해 작성했던 포스팅에서처럼, 자식 요소들의 height의 합을 그대로 가지게 된다. 따라서 위 그림의 경우, 각 child 속성을 가진 div들은 200px의 height를 가졌으니 total 클래스의 div의 height는 600px이 된다.
그럼 child 클래스를 가진 div 태그에 float 속성을 지정하였을 때 위 <div> 태그들은 어떻게 움직이게 될까. 먼저 float 속성에 줄 수 있는 값을 살펴보자. float 속성에는 크게 left와 right를 줄 수 있는데, left를 값으로 줄 경우 해당 요소는 부모 요소의 width 내에서 가장 왼쪽으로 정렬된다. 예시로, red 클래스에 float:left 속성을 부여해보자.
.red {
background-color: red;
float: left;
}
그럼 웹 브라우저 화면에는 아래와 같이 출력된다.
float 속성을 사용하여 left를 주었으니 빨간색 블럭이 왼쪽으로 정렬된 것은 이해하겠는데, 노란색 블럭은 어디로 갔을까? 노란색 블럭은 바로 빨간색 블럭 바로 아래에 있다. 이를 확인해보고 싶다면 CSS 코드로 red 클래스에 opacity 속성에 0값을 주면 된다.ㅡopacity는 투명도를 지정할 수 있다. 0은 투명, 1은 불투명이다.ㅡ
왜 위와 같은 현상이 일어났을까? 다시 되돌아가서 float의 의미를 곱씹어보자. float의 의미는 '뜬다'였다. '뜬다'라는 의미에 집중한다면 지금 사진 속 빨간색 블럭은 노란색 블럭 위에 떠있는 것이다.
float 속성이 적용된 빨간색 블럭이 현재 공간에서 공중으로 띄워진다고 생각해보자. 그럼 기존에 빨간색 블럭이 차지하고 있던 공간은 비게 되는데, 그 남은 공간을 노란색 블럭이 자동으로 메꿔주게 되는 것이다. 그렇게 되면 부모 요소의 height도 자연스럽게 줄어들게 된다. 그럼 위 상태에서 노란색 블록에 float 속성을 부여해보자.
.yellow {
background-color: yellow;
float: left;
}
아래는 웹 브라우저에 출력되는 화면이다.
노란색 블록에 float 속성으로 left를 줌으로써 빨간색 블럭 바로 옆에 정렬됨을 확인할 수 있다. 그러면 파란색 블록은 어디로 간 것일까? 파란색 블록은 빨간색 블록 밑에 위치해있다.
빨간색 블록을 float 시켰을 때, 빨간색 블록 아래에 노란색 블록이 있었다. 하지만 노란색 블록을 float 시켜 left를 시키니, 노란색 블록은 자연스럽게 빨간색 블록 옆으로 가게 되고, 빨간색 블록 아래 공간은 비어진다. 이 때, 파란색 블록이 빨간색 블록 밑에 들어가는 것이다.
그럼 마지막으로 파란색 블록을 float 시켜 left로 정렬해보자. 그럼 노란색 블록 옆에 위치하게 되지 않겠는가?
.blue {
background-color: blue;
float: left;
}
아래는 웹 브라우저에 출력되는 화면이다.
예상대로 되지 않았다. 파란색 블록에 분명 float:left를 지정해주었건만, 노란색 블록 옆으로 가지 않았다. 이는, 부모 요소의 width를 이미 초과해버렸기 때문에 파란색 블럭이 float 되어도 노란색 박스 옆에 정렬될 수 없기에 빨간색 블럭 아래에 정렬되어버린것이다. 만일 파란색 블럭도 노란색 블럭 옆으로 이동시켜주고 싶다면, 부모 요소의 div 태그의 width를 더 늘려주면 된다.
float 속성을 통해 세 개의 색깔 블럭을 왼쪽 정렬 시켜보았는데, 사실 여태껏 언급하지 않은 문제가 있다. 위 그림과 같이 되어버리면 세 개의 색깔 블록을 자식요소로 담고 있는 부모 요소 <div>는 height가 0이 되어버린다.
개발자 도구 우측을 보자. total 클래스의 div를 선택했는데 height가 0으로 출력되었다. 이는, <div> 태그의 자식 요소들이 모두 float 되어버리면서 <div> 공간이 비어지게 된 것이다. block 요소를 자식으로 가진 부모 태그의 height는 자식 요소들의 height를 모두 더한 값이라고 했다. 그런데 위 같은 경우 자식 요소들이 float 되버려 div 태그를 모두 탈출해버렸으니 <div> 태그 내부에 있는 자식 요소들의 height의 합은 0이 되는 것이다.
float 속성을 지정했더니 레이아웃이 박살났더라 하는 문제는 위 문제였을 가능성이 크다. 내가 겪었던 문제도 그랬다. 그래서 위와 같이 float 속성을 지정하더라도 부모 요소를 그대로 살려두는 방법이 있다. 그것은 CSS를 통한 가상 클래스 생성이다.
여태까지 설명했던 float 속성의 문제를 요약하자면, 자식 요소들이 모두 float이 되어버리면 부모 요소는 자식 요소의 높이를 인지하지 못하기 때문에 결국 부모 요소의 height가 0이 되어 레이아웃이 붕괴된다. 하지만 부모 요소가 float 처리된 자식 요소를 인지할 수 있다면, 문제는 해결된다.
이를 위해 사용하는 것이 clear 속성이다. 특정 요소가 float 처리 되어버리면, 이후에 오는 요소들은 레이아웃을 잡기가 힘들어진다. clear 속성을 사용하면 float 처리된 이전 요소에 의해 이후 요소들이 더 이상 float의 영향에 벗어나게 된다. 실습을 위해 위에서 사용했던 html 코드를 그대로 가져오겠다.
<div class = "total">
<div class = "child red"></div>
<div class = "child yellow"></div>
<div class = "child blue"></div>
</div>
child div들을 자식 요소로 감싸는 부모 태그 total div 뒤에 가상 요소를 넣음으로써 clear 속성을 적용시킬 것이다. 그러기 위해서는 아래와 같은 CSS 코드를 작성하면 된다.
.total::after {
content: '';
display: block;
clear: left;
}
total 클래스가 적용되고 있는 div 뒤에 clear 속성을 부여할 수 있는 가상의 요소를 만들어주는 코드이다. 이 때 주의할 점은, 가상 요소를 설정하기 위해서는 반드시 content 속성을 작성하여야 하며 빈 공백이라도 값을 주어야 한다. 그리고 가상 요소는 반드시 block 속성을 가져야하기 때문에 display 속성으로 block 처리를 해주자.
위와 같이 .total::after 로 설정해주면, HTML 문서에서는 .total 클래스가 적용된 태그 이후에 가상의 요소(element)가 추가된다. 이 곳에 clear 속성을 부여해준다.
여기서 clear 속성의 값으로는 left, both, right인데, left로 지정할 경우, left로 float된 이전 요소들을 인식할 수 있게 된다는 의미이다. 여태까지 작성한 코드는 float이 모두 left였으니 clear 속성을 left라고 지정하면 된다. right의 경우, right로 float된 이전 요소들을 인식할 수 있게 된다는 의미이며, both는 left, right 모두를 자동으로 인식한다는 의미가 된다.
위와 같이 작성하면 웹 브라우저에는 아래와 같이 뜬다.
total 클래스가 적용된 div의 height가 400px로 설정되었음을 확인할 수 있다. 부모 <div>가 float되어버린 자식 요소들을 인지할 수 있게 되면서 정상적인 height 값을 가지게 된 것이다.
위와 같이 float 처리를 위한 방법은 CSS 가상 요소 설정 외에도 overflow 속성을 활용한다던지, HTML 문서 내에서 빈 요소를 삽입하는 방법들도 있다. 그에 대해선 다음에 기회가 되면 또 다시 포스팅해보도록 하겠다.
오늘은 float 속성에 대해 알아보았다. 알면 알수록 까다로운 float 속성. 하지만 이를 제대로 알고 나면 레이아웃을 구성하는데 크게 도움이 될 것이라 믿는다. 다음에도 재미있는 공부거리를 들고 찾아오겠다.
P. S 조잡한 글 읽어주셔서 감사합니다! 혹시나 틀린 정보가 있다면 과감한 지적(하지만 욕은 삼가해주시면 감사하겠습니다 ㅎㅎ) 부탁드립니다.
'웹 프로그래밍 > CSS' 카테고리의 다른 글
<22.03.18> CSS 공부 일지 #07. 마지막 남은 display 속성 ㅡ Flex (0) | 2022.03.18 |
---|---|
<22.03.17> CSS 공부 일지 #06. CSS로 요소 움직이기! ㅡ position 속성에 대해 (0) | 2022.03.17 |
<22.03.15> CSS 공부 일지 #04. CSS의 다양한 Selector들 (0) | 2022.03.15 |
<22.03.14> CSS 공부 일지 #03. display 속성에 대해 ㅡ Block과 Inline 그리고 inline-block (0) | 2022.03.14 |
<22.03.14> CSS 공부 일지 #02. Box-Model에 대해 (0) | 2022.03.14 |