자식의 크기가 부모 요소보다 커서
자식이 부모 요소의 범위를 벗어났을 때 처리할 방법을 지정하는 속성이다.
자식 요소가 부모의 배치 흐름으로 부터 빠져나온다.
이때 이 요소는 텍스트 및inline
요소가 본인에 좌우측을 따라 배치되어야 함을 지정한다.
-MDN 발췌-
인강에 따르면
float
가 적용된 요소는 묵시적으로inline-block
요소가 된다고 한다.정확하게는 BFC 요소가 되는 것이다. BFC는 아래에서 설명한다.
자식요소(div.parent > div.child)에 float 속성 적용 전,
<!DOCTYPE html> <html lang="en"> <head> <title>float & overflow</title> <style> * { box-sizing: border-box; } body { background-color: #eee } .parent { width: 600px; border: 5px solid red; } .child { background-color: royalblue; border-radius: 12px; text-align: center; color: white; } </style> </head> <body> <div class="parent"> <div class="child">child</div> </div> </body> </html>
자식요소(div.parent > div.child)에 float 속성 적용 후, inline-block이 된 모습
<!DOCTYPE html> <html lang="en"> <head> <title>float & overflow</title> <style> * { box-sizing: border-box; } body { background-color: #eee } .parent { width: 600px; border: 5px solid red; background-color: white; } .child { background-color: royalblue; border-radius: 12px; text-align: center; color: white; } .float-left { float: left; } </style> </head> <body> <div class="parent"> <div class="child float-left">child</div> </div> </body> </html>
이상한 점을 발견할 수 있다.
부모요소 (div.parent)의 범위가 줄어들었다.
위에서 언급했던자식 요소가 부모의 배치 흐름으로 부터 빠져나온다.
의
의미를 이 부분에서 확인할 수 있다.부모 요소에 크기를 지정하지 않으면 자식의 크기에 알맞게 알아서 증가한다.
현재는width
만 지정되어있고height
는 지정되어있지 않다.즉, 부모 요소는
float
속성이 적용된 자식요소의 범위를 취급하지 않는다.
이를 확인하기 위해서 child의 모양과 크기를 변경하고
float
속성이 적용되지 않은span
자식을 추가해보겠다.부모요소는 float 속성이 적용되지 않은
span
자식요소의 범위만 취급해서 부모요소의 범위가 커진 모습을 확인할 수 있다.
<!DOCTYPE html> <html lang="en"> <head> <title>float & overflow</title> <style> * { box-sizing: border-box; } body { background-color: #eee } .parent { width: 600px; border: 5px solid red; background-color: white; } .child { background-color: royalblue; border-radius: 12px; text-align: center; color: white; } .float-left { float: left; } .circle { width: 200px; height: 200px; border-radius: 50%; text-align: center; line-height: 200px; } .orange { background-color: orange; } </style> </head> <body> <div class="parent"> <div class="circle child float-left">child</div> <span class="orange child">span</span> </div> </body> </html>
인강에서 듣기로는 이러한 현상을 해결하기 위해서
부모요소에overflow: hidden
을 추가하거나
height
를 지정하면 된다고 한다.
<!DOCTYPE html> <html lang="en"> <head> <title>float & overflow</title> <style> /* 생략 */ .parent { width: 600px; border: 5px solid red; overflow: hidden; } /* 생략 */ </style> </head> <body> <div class="parent"> <div class="circle child float-left">child</div> <span class="orange child">span</span> </div> </body> </html>
왜 하필
overflow
속성 일까?맨 처음에 말했던 것처럼
overflow
의 본 목적은 스크롤 기능을 부여하거나 가리거나 하는 등
부모요소의 범위를 넘어간 자식요소를 어떻게 할지 지정하기 위함이다.
overflow
는float
이슈를 해결하기 위해 존재하는 것이 아닌데
왜 여기서 사용하는가?강사도 이유에 대해서 설명해주지 않았다.
조사한 바에 따르면 CSS의
BFC(Block Formatting Context)
와 관련이 있다고 한다.
웹 페이지를 렌더링하는 시각적 CSS의 일부로서,
블록 박스의 레이아웃이 발생하는 지점과float
요소의 상호작용 범위를 결정하는 범위이다.
-MDN 발췌-
내가 이해한 대로 설명하자면 BFC 요소는
float
요소인 자식의 범위도 취급한다는 말인 것 같다.
즉,새로운 문서(블록 혹은 body 혹은 html)
을 만들어낸다는 것이다.
최상위 태그인
html
태그가 BFC 요소라고 한다.이를 확인하기 위해서
body
에float
속성을 추가해봤다.
html
라는 부모요소에는body
자식 하나 밖에 없기 때문에
자식 요소의 범위를 취급하지 않아야한다.
html
태그의 자식요소로head
태그도 있지 않냐 하는데
head
태그는 문서의 메타데이터를 담는 공간으로, 랜더링 되지 않는다.확실한 확인을 위해서
body
태그의background-color
를 잠깐yellow
로 변경하고
float: left
를 지정했다.
html
이float
요소인body
를 인식하고 배경색이 출력되는 것을 확인할 수 잇다.<!DOCTYPE html> <html lang="en"> <head> <title>float & overflow</title> <style> /* 생략 */ body { background-color: yellow; float: left; } .parent { width: 600px; border: 5px solid red; background-color: white; overflow: hidden; } /* 생략 */ </style> </head> <body> <div class="parent"> <div class="circle child float-left">child</div> <span class="orange child">span</span> </div> </body> </html>
여기서 또 이상한 점을 발견할 수 있다.
body
요소에width
와height
를 지정하지 않았는데
왜parent
의width
와height
를 벗어나서
뷰포트 전체에background-color: yellow
가 지정이 되는가?
결론부터 말하자면
body
의background
는
루트 요소인html
태그가background
속성이 존재하지 않을 때
body
의background
를html
에 전달한다.CSS의 목적은 안정적인 레이아웃을 쉽게 만들기 위함이다.
이 목적을 달성하기 위해 의도적으로 이렇게 만들었다고 한다.이를 확인하기 위해서
body
에border: 10px solid green
과padding: 20px
을 추가해보겠다.
<!DOCTYPE html> <html lang="en"> <head> <title>float & overflow</title> <style> /* 생략 */ body { background-color: yellow; float: left; border: 10px solid green; padding: 20px; } /* 생략 */ </style> </head> <body> <div class="parent"> <div class="circle child float-left">child</div> <span class="orange child">span</span> </div> </body> </html>
관례 상
html
태그에는background
속성을 넣지 않지만
사실 확인을 위해서html
태그에background-color
속성을 추가해보겠다.
<!DOCTYPE html> <html lang="en"> <head> <title>float & overflow</title> <style> /* 생략 */ html{ background-color: blueviolet; } body { background-color: yellow; float: left; border: 10px solid green; padding: 20px; } /* 생략 */ </style> </head> <body> <div class="parent"> <div class="circle child float-left">child</div> <span class="orange child">span</span> </div> </body> </html>
overflow
속성을 지정하면 그 요소는 BFC 요소가 되기 때문이다!!!그렇기 때문에 부모요소에
overflow
속성을 지정하면
float
인 자식들을 자신의 범위로 취급하고 이에 따라 범위가 늘어나는 것이다.
문서의 루트요소인 html 태그
float
속성 지정
position
:absolute
|fixed
절대 위치를 지정
display
:inline-block
|flex
|flex-inline
|grid
|inline-grid
지정
overflow
속성 값이visible 이외의 값
으로 지정
display
:flow-root
지정
이외의 빙밥은 다음 링크에서 참조
https://developer.mozilla.org/ko/docs/Web/Guide/CSS/Block_formatting_context
overflow의 본 목적은 float 인 요소를 제어하기 위함이 아니다.
문제 해결은 할 수 있지만overflow: hidden
으로 작성된 코드를
이후에 다른 개발자가 본다면 의도를 파악하기 힘들 가능성이 있다.MDN에 따르면 float 범위 문제 현상은
display: flow-root
을 지정하여 해결하라고 권장하고 있다.
flow-root
말 그대로 이 요소는 문서의 시작을 의미하기 때문이다.
마진 겹침/상쇄 현상에 대해 먼저 설명하겠다.
마진 겹침/상쇄 현상이 발생하는 코드이다.
<!DOCTYPE html> <html lang="en"> <head> <title>margin problem</title> <style> .parent { background-color: lightblue; width: 140px; } .child { width: 100px; height: 100px; background-color: white; margin: 20px; } .row { display: flex; } </style> </head> <body> <div class="parent"> <div class="child">child 1</div> <div class="child">child 2</div> </div> </body> </html>
child
상하좌우에margin: 20px
을 부여했다.이상한 점 2가지를 확인할 수 있다.
child 1
은margin-top: 20px
이고child 2
의margin-bottom: 20px
이니
child
들 사이의 공간은총 40px
이어야하는데20px
만 적용되었다.(겹침)
child 1
상단과child 2
하단에margin
이 적용되지 않았다.(상쇄)
겹침
현상의 경우 CSS의 의도된 동작이라고 한다.
단, 상하 요소에서만 발생한다. 좌우에서는 겹침 현상이 발생하지 않는다.
이 또한 CSS의 목적을 달성하기 위해 의도적으로 이렇게 만들었다고 한다.
모든
margin
을 삭제하고
child 1
에는margin-bottom: 20px
,
child 2
에는margin-top: 40px
을 줘서
사이margin
값이 다를 때도 겹침 현상이 일어나는지 실험해봤다.
최상단 자식의
margin-top
과 최하단 자식의margin-bottom
이 상쇄되는 현상이다.
논리대로라면20px
씩 부여되어야한다.이를 해결하기 위해서 부모요소를 BFC 요소로 만들어준다.
W3C 에 따르면 BFC는 이 현상을 해결하기 위한 용도라고 한다.BFC 요소의 높이 계산 알고리즘은
최상단 요소의 margin-top-edge - 최하단 요소의 margin-bottom-edge
로
구현되어 있기 때문이다.만약 모든 자식이
inline
요소일 경우inline
요소의 최상/하단 을 기준으로 계산된다고 한다.