# 코드스피츠 스터디 - CSS Rendering 2회차 정리 및 리마인드

> 히카맹 선생님의 코드스피츠 강의를 들으며 자바스크립트에 대한 이해를 높이기 위해 스터디를 하게 되었다. 이 포스팅은 그에 대한 정리글이다.

### **들어가면서...**

매주 코드스피츠 영상을 2개씩 보며 발표를 하고 서로 얘기 나누는 스터디를 진행 중이다. (이해를 못해서..) 막상 발표할 때는 얼마 없는 것 같다가도 실제로 블로깅할 때는 시간이 엄청 드는 거 보면 신기하다. 그리고 그 신기함에는 역시 깨달음에 있겠지. 처음부터 바로 신기했다.

---

# **Box Model**

Box Model은 CSS를 처음 접하면 가장 먼저 접하는 중요한 이론 중 하나인 것 같다. 그렇기 때문에 (마치 수학의 정석 첫파트마냥) 가장 많이 보게되고 학습하게 되는 부분 아닌가 싶은데, 이 박스모델도 내가 간과하거나 지나친 내용이 많다.

## **Box Model이란?**

일반적으로 Box모델에서 Geometry로 잡히는 부분은 contents-box, padding-box, border, margin 이다. 하지만 Geometry에 인정되지 않으나 Box모델 내에 포함되어있는 요소가 존재하는데 outline, box-shadow, box-shadow inset 이다.

## **Box의 실제 사이즈는 Content-Box**

> 엥? 박스모델의 정의를 위해서 해놓고 content-box가 실제사이즈라고 한다고?
> 
> @ : 이유가 있어, 계속 좀 봐..

div 등 요소들을 CSS로 작업하다보면 내가 정한 width, height 등의 값과 사이즈가 일치하지 않는 경우가 있는데, 이는 앞서 말한 Box모델의 특징에 있다.

![코드로 작성된 박스](https://velog.velcdn.com/images/stardust6653/post/cc39690b-3040-40f0-a9ac-4f4e10b88d82/image.png align="left")

위의 코드를 보았을 때 (Box model의 geometry를 모른다면!) 당연히 height , width가 각각 100, 50인 두개의 상자가 렌더링 될 것이라고 생각이 들겠지만 실제로는 witdh(또는 height)와 (border+padding)\*2 를 더한 값이 렌더링된 것을 개발자 도구를 통해 확인할 수 있다.

![개발자 도구에서 확인한 div박스의 크기](https://velog.velcdn.com/images/stardust6653/post/d4493f3a-2e2b-4744-86b5-a7fe942f7f16/image.png align="left")

### **자 그러면 어떻게 해야 내가 원하는 width, height를 가질 수 있냐!!**

방법은 간단하다 CSS옵션 중 box-sizing이라는 속성을 사용하면 된다.

두가지의 속성을 제공하는데 기본값으로는 Content 영역의 크기를 보장하고 보호하는 `content-box`가 설정되어있기 때문!

*<s>어그로성 제목은 다 이것 때문이었다</s>*

자 그렇다면 width, height 표기한 만큼 렌더링 되게는 못해요? 할 수 있다.

`border-box` 주면된다. 댕쉬움. 끗

---

## **자, 이제 Geometry로 잡히지 않는 속성(box-shadow)들을 보자!**

> Box model에는 포함되나 Geometry를 가지지 않는 3가지 : `outline`, `box-shadow`, `box-shadow inset`

두가지 요소를 붙여 그렸을 때 `box-shadow`를 준 적이 있는가? 사실 붙어있을 때는 나도 사용한 적이 없고 심지어 볼드한 느낌으로 사용한 적도 없다. 그런데 만약 그런 행동을 해본다면 약간의 신선한 충격이 있을 거라고 본다. (나만 그랬나..) 왜냐면 box-shadow에는 진짜 geometry가 없다.. 땅없는 나같은 사람이다 그냥. *<s>(box-shadow도 부동산 없어..)</s>*

명확하게 보기위해 하나 작성하면,

![Geometry로 잡히지 않는 box-shadow에 대한 예시](https://velog.velcdn.com/images/stardust6653/post/9d093bee-2146-4ad4-980e-930472700bdd/image.png align="left")

위 결과를 보면 놀랍게도 z-index를 주지도 않았는데 겹쳐져서 그려진다. 그것이 box-shadow가 geometry를 가지지 않는다는 강력한 증거이다. (뭐 개발자 도구보면 크기로 안쳐준다. 서럽다 박쉐)

![Geometry로 잡히지 않는 box-shadow에 대한 예시](https://velog.velcdn.com/images/stardust6653/post/4aaee57f-8238-42e1-97d2-82636f3c9958/image.png align="left")

그렇다면 이건 뭘까? 위 결과를 내기 위해 빨간 상자에 `position : relative`를 의도적으로 주었다. 그러면 위와 같이 normal flow로 한번 그려진 후 floating되어 다시 놓이기 떄문에 위와같이 빨간 박스가 파란 박스 위로 올라오게 된다 ... 신긔

## **Box shadow는 여러개 사용할 수 있다. 그리고 실행순서도 있다-**

Box shadow에 대한 내용을 들으면서 가장 신기했던 것이 바로 `box-shadow`를 여러 개 그릴 수 있다는 것이었다. 여태 box-shadow 자체를 약간의 입체감을 주기위한 용도정도로만 사용했기 때문에 모르는 게 당연할 수 있는데.. 반성해야겠다.

아무튼 아래 코드와 결과를 나란히 놓고 보면 알 수 있는데,

![box-shadow의 특성](https://velog.velcdn.com/images/stardust6653/post/97d1d792-3309-4daa-af21-6528a21ac86a/image.png align="left")

바로 보이는 것 처럼 box-shadow를 여러개 중첩해서 사용할 수 있다는 점과 아래서 부터 위로 실행되어 아래있는 코드의 결과물은 노란색을 파랑이 다 덮어버린 채로 렌더링 된 것.

---

## **stitched box**

![box-shadow의 특성](https://velog.velcdn.com/images/stardust6653/post/c5d02df2-9935-42f8-8d7c-012e844d5430/image.png align="left")

> 그리고 이런 박스모델과 box-shadow 의 특성을 이용해 이런 귀여운 스티치 디자인도 가능하다. 오 너무 기여웡

---

# **offset**

offset은 geometry에 대한 계산이 다 끝난 후 모든 pixel 좌표가 다 정해진, fixed numbe의 상태에 "숫자"를 의미하는데 offset은 한번 정해지면 변경이 되지 않고 원한다면 강제로 재계산을 하도록 해야한다.

브라우저는 이 offset을 구하는 계산들을 매번매번하지 않고 한번에 모아서 처리하려는 특성을 가지는 이걸 Frame이라고 얘기한다. 이 Frame 단위로 쌓여있던 Queue를 소진시키고 해소한다고 보면된다.

만약에 이 Frame 단위보다 더 잘게 쪼개서 offset을 계산하고 싶다면 브라우저에 재요청을 해야하고 이 경우 렌더링 최적화가 깨져서 버벅거리는 현상이 발생하므로 사용을 지양해야한다.

## **offset parent의 자격요건**

> 렌더링을 할 때 가장 먼저해야하는 것은 위치를 정하는 것 아닐까? 넓은 화면 위에 어디에서 부터 시작을 할지를 정해야 하는데, 이 때 필요한 것이 offset parent이다. offset parent는 기준선의 역할을 하는 것.
> 
> 그럼 offset parent는 DOM parent와 동일한가? 아니다.
> 
> 그래서 문제가 생긴다. 자격요건이 별도로 존재한다.. 뜨쉿

### **offset parent가 Null (없는!!!) 경우**

1. **지가 Root, HTML, Body 일 때**
    
2. `position`이 `fixed`일 때
    
    * **fixed의 경우에는 브라우저(chrome)를 기준으로 렌더링하게 된다.**
        
3. **DOM Tree 요소가 아닐때.**
    

### **offset parent를 찾는 방법! (재귀적 탐색)**

1. **부모 요소의 포지션이 fixed라면 offset parent가 null**
    
2. **부모 요소의 포지션이 static이 아니라면 계속 해서 탐색 (absolute, relative만 가능하다는 말)**
    
3. **부모요소가 Body라면 탐색**
    
4. **Table 요소여도 탐색**
    
5. **찾을 떄까지 탐색**
    

## **그래서 offset이 뭐!**

offset의 이해가 필요한 건 `position`을 위해서이다.

자주 사용하는 position은 크게 2가지인데 (sticky나 fixed 등등 많지만) 이 relative와 absolute를 이해하기 위해서는 알아야하기 때문.

### **relative**

* 사실 relative는 다른 것보다 자식요소가 `position : absolute` 속성일 때 그 기준을 부모요소인 본인으로 삼게 하기 위한 일종의 가드 역할을 한다는 점이 중요하다. 일종의 absolute를 위한 컨테이너 역할이랄까?
    

### **absolute**

* absolute 동작원리
    
    * Absolute는 기본적으로 static의 위치에 그려진다. 하지만 top, left, bottom, right 값을 주게 되면 offsetParent를 찾아 그 값이 적용된다.
        

![코드스피츠 강의코드 발췌](https://velog.velcdn.com/images/stardust6653/post/bebc6592-905e-44bf-9747-e49cf1fec230/image.png align="left")

코드 타이핑해서 올려두기가 귀찮아서 캡쳐된 코드와 결과를 올리자면 위와 같이 absolute 포지션을 가지고 있어도 top, left, right, bottom 과 같은 속성을 적지 않으면 기본적으로 static 위에 그려지게 된다. 또한 이건 각각 속성을 기준으로 각각 static을 기준으로 하는 거라서 아래 파란 상자 역시 `left: 0` 외에 top, bottom은 static 기준인 박스가 된다.

---

### **마치며...**

공부를 하면서 offset을 통해 화려한 인터렉티브 CSS를 구현하는 것들이 있던데 한번 공부해보도록 해야겠다. CSS만으로 만들 수 있는 것도 꽤나 무궁무진하구나 싶다.!

---

> ***화려해서 궁금한 거 모음***

[화려한 거](https://velog.io/@kimhyo/CSS-offset-%EC%86%8D%EC%84%B1-%ED%8A%B9%EC%A0%95-%EA%B2%BD%EB%A1%9Csvg-path%EC%97%90-%EB%94%B0%EB%9D%BC-%EC%9D%B4%EB%8F%99%ED%95%98%EB%8A%94-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98-%EB%A7%8C%EB%93%A4%EA%B8%B0-d70mb7cs)

[화려한 거 2](https://muffinman.io/blog/draw-svg-rope-using-javascript/)
