티스토리 뷰

HTML & CSS

CodeSpitz - CSS Box Model

_Bibidi 2021. 12. 20. 16:47

 

[ 고전 Box Model ]

 CSS layout box라는 시스템 안에 들어가는 모든 element들이 지켜야하는 박스 규격을 Box Model이라고 한다. 다음과 같이 구성돼 있다.

 - margin : 무조건 투명하게 되어있고 이걸 바꿀 방법은 지금은 없다. 투명하지만 실체를 확보하고 있는 공간이다.

 - border : 외곽선을 칠하는 경계면이다. 이 부분도 contents처럼 쓸 수 있다. 현재 나오는 스펙들을 보면 border background도 있다.

 - padding : 투명하다. border로부터 contents box를 띄어주는 역할을 한다. 내부 마진이라고도 부른다.

 - contents

 

 - box-sizing : box의 width, height 기준을 정하는 속성이다. border-box, content-box를 값으로 가질 수 있다. content-box는 contents 영역의 크기를 보존하고 싶을 때 사용하고 border-box는 어떤 크기 안에 무조건 그려넣어야 할 때 사용한다.

 

 

[ Modern Box Model ]

 고전 box model은 CSS layout box를 만들어내기 때문에 자기의 공간을 차지하고 CSS Normal Flow의 배치를 결정하거나 위치를 계산할 때 영향을 준다. 그러나 그 이후에 확장되어 있는 CSS Module에서는 CSS의 layout box에는 영향을 주지 않지만 그림에는 더 많은 외곽선을 그릴 수 있는 스펙을 발표했다. 그중 첫 번째가 box shadow이다.

 

 - Box Shadow

1. 그림자 역할을 하는 box이다. left, top을 이용해 offset을 정하고 blur를 통해 투명도, spread를 통해 크기를 정할 수 있다.

2. blur만 제거하면 border와 완전히 같다. blur 없애고 offset 0 주면 정확히 spread 크기의 border를 얻을 수 있다.

3. box shadow가 그려지는 위치는 기본적으로 border box 바깥이고 geometry로 계싼되지 않는다. fragment 단계에서 작동하는 기능으로 추가적으로 그림만 그린다.

4. inset이라는 속성을 주면 border 안쪽에도 그릴 수 있다.

5. 콤마(,)를 이용해 여러 번 그릴 수 있다. CSS에 선언된 반대 순서로 그려진다.

6. border radius에 영향을 받는다. border가 둥글면 box shadow도 같이 둥글어진다.

 

 - Outline

1. 정확히 box shadow와 같은 위치에 그려진다.

2. geometry에 영향을 주지 않는다.

3. border의 모양에 영향을 받지 않는다. (지금은 IE에서만 되고 최신 브라우저들에서는 안 된다)

 

 * inline 요소 사이에 공백(line feed, space 등)이 있으면 이를 인식해서 공백을 출력한다. opening tag와 closing tag를 붙여서 태그 사이의 공백을 없앨 수 있다.

 * box에 background color를 채우면 border까지 채우고 난 뒤에 다시 border를 그린다.

 * position absolute나 fixed만 z-index로 그려지는 순서가 있다고 생각하는 경향이 있다. inline 요소도 그려지는 데 순서가 있다.

 

 

[ Offset System ]

 

브라우저의 특징

1. HTML과 CSS는 브라우저에 희망사항을 요청하는 것이지 실제 구현 사항이 아니다. 희망사항이 제대로 구현되는가는 브라우저에 달렸다.

 

2. 우리는 브라우저 렌더링 시스템에 지시만 내릴 수 있을 뿐 실제로 계산된 값(offset)은 모른다.

 ex) 구형 IE6에는 float를 주면 무조건 padding 3을 주는 버그가 있었다. 우리는 3이 없을 거라 생각했지만 나중에 offset을 조사해보니 padding이 3씩 먹혀있었다.

 

3. 브라우저는 효율적인 계산을 위해 geometry 계산을 한 번에 몰아서 하려고 한다. 이 묶음의 단위를 frame이라고 부른다.

 ex) 박스 여러 개의 사이즈를 조정한다고 할 때 각각 하나씩 처리하면 영향을 받는 박스 계산 등을 고려했을 때 계산량이 너무 많아진다. 그래서 움직이는 요소들만 따로 모아서 묶어놓고 한 번에 계산하려고 한다. 

 

4. 그림을 그리는 사이에 element의 offset을 요청하면 브라우저는 이 offset을 계산하기 위해 큐를 강제로 비우고 재계산을 진행한다. 한 frame이 아닌데도 offset을 요청하면 재계산을 때리기 때문에 주의해야 하며, 웬만하면 요청을 하지 않는 것이 좋다. offset을 요청해도 되는 것은 계산이 다 끝난 것이다. geometry의 변화가 없고 큐에 쌓여있는 게 없기 때문에 offset을 요청해도 된다.

 초보자들이 많이 하는 실수는 레이아웃을 그리기 위해 offset을 받아오고 offset 베이스로 다시 레이아웃을 그리려고 하는 경우 큐에 계속 쌓이고 계속 재계산하고 한 프레임 그릴 때 전체 계산을 몇 번씩 때리게 된다. 그러면 엄청나게 느려진다.

 

Offset

 geometry 계산이 다 끝나서 fixed number 체계로 바뀌어 있을 때의 숫자이다. 참고할 순 있지만 변경할 수 없는 읽기 전용 속성이다.

 

OFFset Parent

1. offset을 계산하는 가장 기본적인 로직은 모든 수치가 상대적인 위치로 기술되어 있기 때문에 어디가 기준점인지를 찾는 것이 가장 우선된다. 이 기준점이 offset parent이다.

2. offset parent는 DOM parent가 아니다. 그림 그려주는 로직과 DOM의 데이터적인 구조는 별개이다.

3. position static, relative라고 반드시 offset parent가 DOM parent인 것은 아니다. inline 안에 block이 들어있는 경우 BFC의 offset parent를 계산할 때 그 바깥쪽에 있는 요소를 기준으로 계산하거나 inline 요소를 강제로 끌어내서 위치를 계산한다.

 

Offset Parent 찾는 법

1. NULL

 - ROOT, HTML, BODY

 - POSITION:FIXED

 - OUT OF DOM TREE 

 

 position fixed의 경우 chorme을 기준으로 그리는데, 브라우저의 bound box를 기준으로 그린다. out of DOM의 경우 DOM에 element가 없는 경우이다. 예를 들면 create를 이용해 element를 만든 경우 append로 DOM tree내에 넣기 전까진 offset parent가 없다.

 

2. Recursive Search

 - PARENT.POSITION:FIXED = NULL

 - PARENT.POSITION:!STATIC = OK

 - BODY = OK

 - TD, TH, TABLE = OK

 - PARENT.PARENT CONTINUE

 

 position absolute의 offset parent가 될 수 있는 건 position absolute와 relative밖에 없다. 그런데 relative는 static을 기준으로 위치를 잡기 때문에 일반적으로 absolute를 넣기 위한 container로서 relative를 많이 사용한다.

 * 스펙대로라면 td 안에 absolute 속성을 먹인 div을 넣으면 td를 offset parent로 여겨야 하지만 실제로는 이렇게 작동 안 한다. 대부분의 브라우저가 스펙과 다르게 구현돼있다.

 

 Offset value

 - offsetLeft, offsetTop : offset parent로부터 얼마나 떨어져 있는가가 left, top으로 나온다.

 - offsetWidth, offsetHeight : 실제로 확보한 geometry의 크기. scroll bar가 있는 경우 포함한 크기이다.

 - offsetScrollTop, offsetScrollLeft : 가장자리로부터 얼마나 scroll 되었는지에 대한 값

 - offsetScrollWidth, offsetScrollHeight : 진짜 컨텐츠의 크기

 

 원래 큰 것이 좁은 곳에 갇혀 scroll이 생긴다. 그래서 scroll이 붙은 속성이 진짜 컨텐츠의 영역이라 생각하면 외우기 편하다.

 

 

[ Position Absolute ]

1. offset의 기본값은 static의 위치와 똑같은 기본값을 가진다.

2. left, top을 주는 순간 offset parent를 기준으로 거리를 계산한다.

 * position static의 경우 left, right, top, bottm 모두 무시된다. Normal Flow를 그려야 하기 때문이다. 속성 간 계산 공식이 충돌하는 경우 중 하나.

 * position relative의 경우 left, right의 의미는 Normal Flow로 그려졌을 때의 거리를 의미한다. left, top은 상황에 따라 다르게 해석된다는 걸 기억해야 한다.

 * position absolute에 float를 주면은 float가 무의미해진다. float는 normal flow에서만 작동하기 때문이다.

 * static 안에 absolute가 공생하는 방법은 relative이다.

 

 * 그리고 position static, relative가 아니므로 Normal Flow를 따르지 않는다. geometry 관련 해서 발생하는 문제는 Normal Flow와 관련지어 생각하면 논리가 맞아 떨어진다.

 * 부모가 absolute가 걸린 자식을 인식 못 한다고 생각했는데 그게 아니라 Normal Flow를 벗어나서 계산에 포함이 안 된 것이다.

 

'HTML & CSS' 카테고리의 다른 글

CodeSpitz - Semantic Web & CSS Query  (0) 2021.12.20
CodeSpitz - Transform 3D & SCSS & Compass  (0) 2021.12.20
CodeSpitz - CSSOM & Vendor Prefix  (0) 2021.12.20
CodeSpitz - Graphics System & Normal Flow  (0) 2021.11.09
HTML & CSS  (0) 2021.10.21
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 27 28 29 30 31
글 보관함