CSS Flexbox와 Grid 시대에 개발하는 우리는 CSS Clearfix를 자주 떠올리지 않습니다. Flexbox와 Grid는 float보다 요소 배치를 훨씬 더 쉽고 깔끔하게 처리해 주기 때문입니다.
그럼에도 불구하고 clearfix를 알아두면 좋습니다. 레거시 코드에서는 여전히 float를 사용하는 경우가 많고, 코드베이스 전체를 최신 방식으로 전환할 시간이나 예산이 없을 때가 있기 때문입니다.
이 글에서는 clearfix 핵(hack)이 무엇인지 살펴보고, 이를 대체할 수 있는 더 현대적인 방법인 display: flow-root까지 함께 알아보겠습니다.
플로트(Float)란 무엇일까?
먼저 복습 차원에서 짚어보면, float 속성은 지정한 요소를 컨테이너의 왼쪽 또는 오른쪽으로 밀어내 배치하는 기능입니다.
<!DOCTYPE html>
<html lang="en">
<head>
<title>CSS Clearfix</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
background-color: grey;
}
ul {
max-width: 800px;
width: 100%;
background: lightblue;
border: 5px double black;
padding: 20px;
}
img {
width: 300px;
margin: 20px;
}
li {
list-style: none;
float: left;
}
</style>
</head>
<body>
<!-- https://unsplash.com/photos/2PPjq7I3bs4 -->
<ul>
<li>
<img src="https://images.unsplash.com/photo-1567268377583-d1aaf9ccfc22?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3300&q=80" /> </li>
<!-- https://unsplash.com/photos/vYhBeZ_G_xE -->
<li>
<img src="https://images.unsplash.com/photo-1592283338081-beb63fa6a156?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1850&q=80" /> </li>
<!-- https://unsplash.com/photos/7UduWMpT618 -->
<li>
<img src="https://images.unsplash.com/photo-1583513702439-2e611c58e93d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3298&q=80" /> </li>
<!-- https://unsplash.com/photos/Ah_QC2v2alE -->
<li>
<img src="https://images.unsplash.com/photo-1552944150-6dd1180e5999?ixlib=rb-1.2.1&auto=format&fit=crop&w=1850&q=80" />
</li>
<!-- https://unsplash.com/photos/T-0EW-SEbsE -->
<li>
<img src="https://images.unsplash.com/photo-1548199973-03cce0bbc87b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2250&q=80" /> </li>
</ul>
<p>Here is a sample paragraph element. Something is wrong about where I am in the layout. What else is wrong with the layout?</p>
</body>
</html>
위 예제에서는 연한 파란색 배경의 <ul> 컨테이너 안에 이미지들이 들어 있지만, 이미지들이 컨테이너의 다른 요소들보다 훨씬 큽니다. 그 결과 float가 제대로 해제(clear)되지 않은 채로 영역을 넘쳐버리고, 가로 마진마저 무너져 버립니다.
바로 이 때문에 연한 파란색 컨테이너가 비정상적으로 납작해 보이고, float된 요소들이 엉뚱한 위치에 놓이며, 문단이 float 요소들과 나란히 배치되는 것입니다. 부모 컨테이너보다 큰 자식 요소에 float를 적용했을 때 나타나는 기본 동작입니다.
해결 방법: Clearfix 핵
가장 고전적인 해결책은 clearfix 핵입니다. 이 기법은 부모 컨테이너 뒤에 빈 콘텐츠를 삽입해, 부모가 float된 자식 요소들을 모두 감싸도록 확장시키는 방식입니다. ::after 가상 요소(pseudo-element)를 활용하면 손쉽게 구현할 수 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<title>CSS Clearfix</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
background-color: grey;
}
ul {
max-width: 800px;
width: 100%;
background: lightblue;
border: 5px double black;
padding: 20px;
}
img {
width: 300px;
}
li {
list-style: none;
float: left;
margin: 20px;
}
.clearfix-hack::after {
content: " ";
clear: both;
display: table;
}
</style>
</head>
<body>
<!-- https://unsplash.com/photos/2PPjq7I3bs4 -->
<ul>
<li>
<img src="https://images.unsplash.com/photo-1567268377583-d1aaf9ccfc22?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3300&q=80" /> </li>
<!-- https://unsplash.com/photos/vYhBeZ_G_xE -->
<li>
<img src="https://images.unsplash.com/photo-1592283338081-beb63fa6a156?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1850&q=80" /> </li>
<!-- https://unsplash.com/photos/7UduWMpT618 -->
<li>
<img src="https://images.unsplash.com/photo-1583513702439-2e611c58e93d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3298&q=80" /> </li>
<!-- https://unsplash.com/photos/Ah_QC2v2alE -->
<li>
<img src="https://images.unsplash.com/photo-1552944150-6dd1180e5999?ixlib=rb-1.2.1&auto=format&fit=crop&w=1850&q=80" />
</li>
<!-- https://unsplash.com/photos/T-0EW-SEbsE -->
<li>
<img src="https://images.unsplash.com/photo-1548199973-03cce0bbc87b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2250&q=80" /> </li>
</ul>
<p>Here is a sample paragraph element. Something is wrong about where I am in the layout. What else is wrong with the layout?</p>
</body>
</html>
<li>에 간격 조정용 마진을 약간 추가한 것 외에는 .clearfix-hack::after 선택자만 추가했습니다. 이 선택자는 content, clear, display 세 가지 속성을 사용합니다.
content 속성에는 빈 문자열(" ")을 넣고, clear 속성으로는 왼쪽과 오른쪽 양쪽 float 아래로 요소의 경계를 내리고, display 속성은 block 또는 table로 설정해 데이터와 이미지가 페이지에 올바르게 표시되도록 합니다.
그 결과 이미지들이 컨테이너 안에 깔끔하게 들어가고, 그 아래에 <p> 태그가 정상적으로 배치됩니다.
Clearfix의 시대는 끝난 걸까?
Flexbox와 Grid의 등장으로 clearfix의 필요성은 점점 사라지고 있습니다. 게다가 CSS에는 clearfix를 더 우아하게 처리하는 새로운 방법도 등장했습니다.
.clearfix-hack {
display: flow-root;
}
.clearfix-hack::after 선택자를 위 코드로 교체해 보세요. 화면에 어떤 변화가 있나요?display: flow-root는 clearfix 핵과 동일한 효과를 내주면서도 코드를 훨씬 더 읽기 쉽게 만들어 줍니다.
결론
이번 글에서는 float 속성을 자식 요소에 적용할 때 발생하는 레이아웃 문제를 해결하는 두 가지 방법, 즉 clearfix 핵과 display: flow-root를 살펴봤습니다. Flexbox와 Grid 덕분에 이런 기법은 처음부터 새로 작성하는 코드보다는 레거시 코드를 다룰 때 주로 사용하게 될 것입니다.