디기딩~디기딩~? 제대로된 HTML과 CSS를 이해를 위한 스터디! 초보 개발자도 잘하고 싶다 퍼블리싱!!
S68 스터디를 참여한 dimanche는 무엇을 느꼈을까요?
설레이는 이 마음은 뭘까?
1회차 스터디 내용은 그래픽스 시스템, Geometry 등.. 레이아웃이 어떻게 그려지는지에 대한 일반적인 내용이었습니다.
이번엔 무엇이 우리의 정신을 혼미하게 할까요~
‘설레이는 이 마음은 뭘까~ 왠지 잠을 이룰 수가 없어~’
출처 : http://blog.naver.com/PostView.nhn?blogId=mujinara&logNo=220593876026
이번 스터디 내용은 크게 보자면 4가지정도로 나눠 볼 수 있었습니다.
- Normal Flow
- Box Model
- BFC & IFC
- Display & Float
사실 제 속마음은 달랐습니다. ‘설명을 해주신 많은 내용이 4가지일리 없어….’
이제 이번 스터디 내용 중 일부를 정리해보도록 하겠습니다.
Normal Flow
html 요소들의 위치를 정하는 방법은 여러가지가 있습니다. 그 중 기본값은 static position입니다. 여기서 static은 정적이다라는 의미가 아닌 컴퓨터가 알아서 그린다는 의미를 가지고 있다고 합니다.
그렇다면 컴퓨터는 어떤 방식으로 요소들을 알아서 그려줄까요? 아주아주 궁금합니다!
html을 렌더링 할 때, static position 요소를 그리는 방법을 Normal Flow라고 합니다.
Normal Flow는 박스 단위로 요소의 크기를 계산하고, 두가지의 배치 방식으로 요소의 위치를 정해 그리게 됩니다.
이렇게만 들어서는 이해하기가 힘듭니다. 왜냐면 모르는게 너무 많기 때문이죠ㅠㅠ
이제 박스가 무엇인지, 어떻게 요소의 크기를 계산하는지, 배치 방식은 무엇이 있는지, 위치는 어떻게 정해지는지에 대한 이해가 필요합니다!
Box Model
Normal Flow는 박스모델을 사용해 그림을 그린다고 했습니다. 여기서 박스 모델이 뭔지부터 알아봐야 할 것 같습니다.
박스모델은 하나의 요소를 사각형 박스로 나타내고 이 박스에는 4가지 영역이 있습니다.
- margin : 바깥을 감싸고 있는 부분으로 다른 요소들과 구별하기 위해 쓰이는 빈 영역
- border : 외곽선
- padding : 외곽선을 기준으로 contents까지의 영역
- contents : 요소의 실제 내용을 포함하는 영역
이 박스의 크기로 요소의 Geometry 공간을 계산하고, 배치를 하게되는데…
4가지 영역 중 어느 영역까지가 width와 height에 해당할까요?
요소에는 box-sizing이라는 속성이 있습니다. 이는 요소의 width와 height를 계산하는 방식을 정하는 속성입니다.
(참고 – MDN문서, https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing)
이 속성에는 content-box, padding-box, border-box라는 3가지의 값이 있습니다. 값의 이름만 봐도 느낌이 슬~ 오지 않나요??
content-box는 CSS 표준에 의해 정의된 기본 값입니다. 이 속성을 가진 요소의 크기(width, height)는 contents 영역만을 측정해 포함하고, margin과 border, padding 영역의 크기는 요소의 크기(width, height)에 포함하지 않습니다.
이와 같이 padding-box와 border-box도 값 명에 표현되어 있듯이 요소의 크기에 포함하는 영역이 다릅니다.
padding-box는 요소의 크기를 contents 영역부터 padding 영역까지를 포함하고, margin과 border 영역의 크기는 포함하지 않습니다.
border-box는 요소의 크기를 contents 영역부터 padding, border 영역까지를 포함하고, margin 영역의 크기는 포함하지 않습니다.
예제를 통해 이를 좀 더 명확히 이해해보려고 합니다.
content-box 값을 가진 박스의 width는 contents 영역의 가로 길이입니다. 이렇게되면 요소의 Geometry 공간 가로는 좌측 margin(margin-left) + 우측 margin(margin-right) + 좌측 border(border-left) + 우측 border(border-right) + 좌측 padding(padding-left) + 우측 padding(padding-right) + width(contents의 가로 길이)가 됩니다.
이렇다보니 content-box의 width는 contents 영역 이외의 다른 영역의 크기가 고려되지 않아 제가 원하는대로 박스 크기를 만들기에는 무리가 있습니다.
<html> <head><title>content-box</title></head> <style> .box1{ background:darkgray; width:200px; height:150px; padding-top:10px } .box2{ background:cornflowerblue; width:100%; height:100px; margin:10px; border:5px solid transparent; padding:8px; box-sizing:content-box } </style> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html>
box2의 width는 contents 영역의 가로입니다. 그래서 contents 영역의 가로가 부모 div의 가로인 200px이 되었습니다.
이렇게 되면, 요소의 Geometry 공간 가로는 10px(margin-left) + 10px(margin-right) + 5px(border-left) + 5px(border-right) + 8px(padding-left) + 8px(padding-right) + 200px(contents의 가로 길이)로 246px로 box1를 벗어나게 되었습니다.
그럼 이번엔 box-sizing 속성의 값을 border-box로 하고 margin을 0으로 설정해보겠습니다.
<html> <head><title>border-box</title></head> <style> .box1{ background:darkgray; width:200px; height:150px; padding-top:10px } .box2{ background:cornflowerblue; width:100%; height:100px; margin:0; border:5px solid transparent; padding:8px; box-sizing:border-box } </style> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html>
box2의 width에 contents, padding, border 영역까지 포함해 200px을 맞추게 됩니다. 그래서 요소의 Geometry 공간 가로는 좌측 margin(margin-left) + 우측 margin(margin-right) + width = 0 + 0 + 200px로 box1의 영역에 딱 맞게 들어가게되었습니다.
이렇게 속성에 따라 박스의 크기가 측정하고 요소의 Geometry 공간을 계산하게 됩니다.
BFC & IFC
Normal Flow에는 두 가지 배치 방식이 있다고 했습니다. 그것은 가로로 배치하거나, 세로로 배치하는 것이죠.
세로로 배치하는 행위를 block이라고 하고, 가로로 배치하는 행위를 inline이라고 합니다.
여기서 어디서도 쉽게 들을 수 없었던 개념이 나옵니다!!!
‘두구두구두구두구!! 치느님을 기다리는 떨림과 비슷해’
출처 : https://namu.wiki/w/KFC
그것은 바로! BFC(Block Formatting Context)와 IFC(Inline Formatting Context)입니다.
BFC : 요소를 세로로 배치하는 컨텍스트
IFC : 요소를 가로로 배치하는 컨텍스트
즉, BFC는 BFC영역에서 요소들을 세로 배치할 수 있도록 위치를 계산해 알려주고, IFC는 IFC영역에서 요소들을 가로로 배치할 수 있도록 위치를 계산해 알려주는 것입니다.
위치를 알려주고 있는 BFC
이제 BFC, IFC를 생각하며 페이지를 보도록하겠습니다.
여기서 빨간색박스를 세로로 배치한 검정색 박스가 BFC입니다.
또한 파란색박스를 가로로 배치한 마지막 빨간색박스가 IFC가 되는 것이죠.
오호~ 그럼 이들은 언제 만들어질까요? 또 그 안에는 무엇을 포함하고 있을까요?
BFC에 대해 좀 더 파헤쳐보도록 하겠습니다.
BFC는 특정한 조건에 해당하는 요소로부터 생성이됩니다. 그럼 특정한 조건을 살펴봐야겠네요.
스펙문서의 내용을 보기 쉽게 해석해준 MDN문서를 참고해보겠습니다.
- 루트 또는 이를 포함하는 요소(body)
- float (float가 none이 아닌 요소)
- 절대위치로 지정된 요소 (position이 absolute 또는 fixed인 요소)
- 인라인블록 (display: inline-block 인 요소)
- 테이블 셀 (display: table-cell 인 요소, HTML table cell의 기본값)
- 테이블 캡션 (display: table-caption 인 요소, HTML table caption의 기본값)
- overflow가 visible이 아닌 요소
- flex box (display: flex 또는 inline-flex인 요소)
그리고 BFC는 그것을 만든 요소안에 있는 다른 요소들 중, 새로 생성되는 BFC 하위 요소 내에 있는 요소들을 제외한 모든것을 포함하고 있다고 합니다.
이 조건들만 봐서는.. 저는 바로 이해하지는 못 했습니다. ‘어려워…’
어렵게 느껴져서인지.. 제 머리가 이해하기를 거부하려합니다ㅠㅠ
포기하지마!!
이해하는 것을 포기하지 않겠슴다!!!!!!! 조건들 중 float와 overflow를 사용해 이를 좀 더 보도록 합시다.
아래의 소스는 스터디에서 예제로 사용했던 코드입니다.
<html> <head> <meta charset="utf-8"> <title>block formatting context</title> </head> <body> <div style="background:rgb(39,241,188)"> <div style="float:left;width:100px;height:100px;background:#f00"> <div style="margin:10px;width:50px;height:150px;background:#ff0"></div> </div> sample inline text. sample inline text. sample inline text. sample inline text. sample inline text. </div> <div style="clear:both;margin-bottom:100px"></div> <div style="overflow:hidden;background:rgb(39,241,188)"> <div style="float:left;width:100px;height:100px;background:#f00"> <div style="margin:10px;width:50px;height:150px;background:#ff0"></div> </div> sample inline text. sample inline text. sample inline text. sample inline text. sample inline text. </div> </body> </html>
이 이미지를 통해 몇가지 확인해 보도록 하겠습니다.
(1) 위, 아래의 초록색 박스의 세로 길이는 왜 다를까?
초록색 박스는 div로 block요소입니다. block요소는 floating된 요소는 모르쇠~하고 인식하지 않습니다.
따라서 위의 이미지의 초록색 div는 자신의 세로 영역의 크기를 계산할 때 하위에 floating되어 있는 빨간색 div의 크기는 안중에도 없습니다. 하지만 아래의 이미지의 초록색 div는 자신의 세로 영역 크기를 하위의 빨간색 div크기만큼 늘린 것을 확인할 수 있습니다.
왜 그럴까요???
코드를 보면, 아래의 이미지 초록색 div에는 overflow:hidden이라는 값을 주었습니다. 따라서 overflow가 visible이 아닌 요소로 BFC를 생성하게 됩니다.
BFC는 자기의 자식은 포함하여 표현해야하는 책임을 가지고 있습니다. 그렇다보니 빨간색 div의 크기만큼 늘어난 것이죠.
(2) 노란색 div 크기는 왜 무시하는가?
아래의 이미지에서 초록색 div에서 BFC가 생성되어 빨간색 div만큼 크기가 늘어났지만 노란색 크기만큼은 늘어나지 않았습니다.
이는 왜 그럴까요???
BFC는 자기의 자식은 포함하여 표현해야하는 책임은 있지만 그 안에서 새로운 BFC가 생성이 된다면 그 하위의 자식까지는 표현하지 않습니다. 빨간색 div가 float 속성을 가지고 있기 때문에 새로운 BFC를 생성되어, 빨간색 div의 하위 요소인 노란색 div의 크기는 신경쓰지 않는 것이죠.
(3) 빨간색 div는 BFC를 생성했으면서 왜 노란색 div만큼 늘어나지 않았는가?
빨간색 div는 사실 노란색 div만큼 늘어나야합니다. 하지만 빨간색 div에 height를 100px로 값을 정해놓아서 그만큼 늘어나지 않은 것입니다. 이는 빨간색 div의 height 값을 없애보면 확인할 수 있었습니다.
(4) 아래의 이미지에서 노란색 div 왜 잘렸는가?
초록색 div에서 BFC를 생성할 수 있도록 overflow:hidden 속성 값을 주었습니다. overflow:hidden은 내용이 넘치면 늘어나지 않고 잘라버리고 보이지 않기 때문에 노란색 div가 잘려버렸습니다.
(5) 코드에서 〈div style=”clear:both;margin-bottom:100px”〉〈/div〉는 무슨 역할인가?
요소가 float되면 둥둥 떠있는 float 레이어가 생깁니다. float 레이어가 있는 한 그 이후의 요소들에게는 float 효과가 적용이 되어버립니다.
그래서 이렇게 아래의 이미지들이 위의 빨간색 div옆에 붙어있게 되어버렸습니다.
그럼 float 레이어는 언제까지 존재할까요? 이 레이어는 자신의 부모 BFC가 끝날 때까지 존재하게 됩니다.
이를 막을 수 있는 것이 있습니다. 바로 clear입니다. clear는 float 효과를 해제시켜버립니다.
그래서 코드 중간에 clear 속성을 가진 요소를 추가하여 아래의 이미지가 예~쁘게 보일 수 있도록 한 것입니다.
원리를 찾아라!
모든 일에는 경험을 통해 얻어지는 것들이 있고, 그 것으로 자신만의 노하우가 생깁니다.
많은 경우의 수가 있는 개발을 자신만의 노하우만으로 대처하기 위해선 오랜 시간과 많은 경험이 필요할 것입니다. 부족하다면 작은 변화에도 대처하지 못해 쉽게 깨져버리는 개발이 되겠죠.
하지만 그에 비해 원리를 알고 개발을 한다면 많은 경우의 수는 생기지 않을 것입니다. 그래서 어려울 수도 있지만 입문부터 원리를 이해하는 바른 방법이 중요하다는 말씀에 공감을 하게 되었습니다.
이때까지의 html과 css에 대한 공부에서는 ‘이건 원래 이런거야~ 저건 원래 저런거야~ 그러니까 이런 경우에는 그냥 이렇게 써야돼~’라는 식의 습득이었습니다. 그러다 보니 어쩌다가 되는 css를 경험해 왔습니다.
이번 스터디에서는 왜?라는 질문과 함께 원리를 이해하는 방식의 공부를 하고있습니다. 어렵지만 원리를 알아간다는 것의 중요함을 생각하며 이해하기 위해 노력해야겠습니다.
—S68 스터디 2회차 스터디 자료 공유(클릭! 클릭!)
스터디 교안 링크
스터디 영상 1/2
스터디 영상 2/2
dimanche | bsidesoft 신입사원
좋은 개발자가 뭔지도 모르고 좋은 개발자가 되고 싶은 초보 개발자입니다.
회사에서는 열심히 교육받고 발전하는 운 좋은 개발자로 일하고 있습니다.
recent comment