CSS Rendering

HTML과 CSS는 선언형 프로그래밍이다.
따라서 가장 효율적인 선언(알고리즘)을 사용해서 코딩을 구현해야 한다.

CSS는 2가지 형태로 화면을 렌더링한다.

1. geometry
Geometry는 쉽게 말해 좌표를 지정하는 것으로 생각하면 된다.
2. fragment
Fragment는 지정한 좌표의 공간을 채우는 작업이다.

Geometry는 상황에 따라 달라질 수 있지만 거의 대부분 Fragment보다 빠르게 작업이 완료된다.

하지만 주의할 점은 Geometry의 변화는 곧 연관된 Fragment의 작업을 요구하기 때문에 최대한 Geometry를 변경하지 않는 방식의 코드를 구현하는 것이 중요하다!



CSS 배경지식

CSS를 배우기 전 알아야 하는 배경지식들부터 설명

Graphics System

그래픽스 시스템은 한마디로 정의하면 점 찍는 방법이라 생각할 수 있다.

Fixed Number
점을 찍는 것부터 생각해보자.
화면에 하나의 점을 찍는다고 했을 때 결국엔
X, Y, WIDTH, HEIGHT, COLOR 등이 고정된 숫자로 지정되어야한다.
이들은 FIXED NUMBER라고 한다.

근데 반응형(다양한 환경)에는 대응할 수 없는 심각한 문제가 있었다.
환경적인 변화에는 1. SCREEN, 2. CHROME SIZE, 3. HIERARCHY 등이 있다.

Abstract Callculator
이를 대응하기 위해 숫자 대신 정해진 공식을 써준다.
공식을 이용해서 실제 그림을 그릴 때 숫자를 이용하는 체계가
Abstract Callculator(추상화된 계산기-> 함수)이다.
%, LEFT, BLOCK, INLINE, FLOAT

Components & Framework
원시적인 숫자로 기술하는 방식(Fixed Number)을 넘어서 함수로 기술하는 방식(Abstract Callculator)으로 발전했다.
하지만 이것만으로는 그래픽스 시스템을 그릴 수 없기 때문에 이를 이어받아서 Componets 더 나아가 Framework로 발전했다.

Componet 레벨의 예를 들어보면
그림을 그리기 위해서 그림이미지의 경로의 jpeg픽셀을 다 가져와서 0,0부터 하나하나 칠하지 않는다. 전부 자동으로 설정된다.
즉, HTML에서 이미지태그에다가 이미지 넣으면 끝 이러한 것을 컴포넌트 레벨의 녀석들이 해준다.
HTML 태그의 각 태그별 공통된 스타일들을 컴포넌트라고 생각한다면 HTML은 결국 하나의 프레임워크라고 할 수 있게 된다.


항상 생각해야 할 것은 컴퓨터 사이언스에서 모든 것은 상대적으로 평가된다.
어떤 것에서는 부모가 되는 것이 어떤 것에서는 자식이 될 수 있다.
따라서 소프트웨어도 상대적인 것을 항상 생각하고 있어야 한다.


Rendering System

렌더링이라는 말은 그래픽스 시스템이 아닌 다른 곳에서도 사용된다.
(예를 들어 데이터베이스의 내용을 JSON 형태로 렌더링 해줘!)

그러면 렌더링이란 무엇일까?
어떤 대상이 있으면 내가 원하는 모습으로 다시 그려주는 것을 다 렌더링이라고 한다.
일반적으로 보다 구체적이고 시각적인 형태로 바꿔주는 것을 렌더링이라고 한다. (꼭 시각적일 필요는 없다.)

이러한 생각을 해보자!
그림을 그리기 위한 데이터를 어떻게 그림으로 바뀌는가?
그림을 표현하기 위한 정보는 뭘까?

렌더링 시스템은 그래픽스 분야에서 보통 2단계를 거친다.
첫 번째 단계 Geometry Calculate (지형 계산) = Reflow
박스를 나눈다.(땅 따먹기라고 생각, 지형 나누기)

두 번째 단계 Fragmet Fill (조각 채우기= 색칠) = Repaint
색칠을 할 때 하나하나의 대상을 Fragment라고 한다.
픽셀이라는 단어가 중립적이지 않기 때문에 사용하지 않는다.


CSS Specifications

브라우저가 작동하는 것이 맞는지 틀린지를 알기 위해서는 사양서를 알아야 한다.
그래야만 표준이 어떤 것인지를 알고, 올바른 문법으로 작성을 하는 것과 동시에 안되는 부분은 폴리필(웹 개발에서 기능을 지원하지 않는 웹 브라우저 상의 기능을 구현하는 코드를 뜻한다.)을 할 수 있기 때문에 사양서를 아는 것이 굉장히 중요하다.

CSS Level 1
- a4 한장 정도로 내용이 적다.

CSS Level 2 + Module
- 그림에 대한 것은 하나의 스펙으로 관리하는 것은 힘들지 않을까?하는 제안을 받아들여서 Module로 관리하자는 내용이 제안되었다.

CSS Level 2.1
- Include Level 3 Module
- 모듈별로 활발한 연구를 통해 여전히 버전업이 자주 되는게 있는가하면 어떤 사양은 확정되고 레벨이 올라갈 일이 없다는 것을 깨달았다.

즉, CSS Level 3는 나올 수 없다는걸 깨달음이 있고 CSS 2.1 때의 모듈들 중에 Level 3들을 모아서 CSS3로 부르게 된다.
그리고 이후에는 Module Level(Transforms 1, Grid 1, Flexbox 1) 이라고 부른다.

CSS 사양의 세계에서는 끊임없이 모듈이 탄생하고 각 모듈별로 계속 업데이트가 되고 있을 것이다.
그렇기에 브라우저마다 특이하게 동작하는 이유는 CSS 스펙이 이렇게 모듈별로 진행상황이 다르기 때문에 브라우저 제조사가 전부 다 최신으로 따라가기 힘들기 때문이다.

이러한 특성을 알고 있다면,
예를 들어 브라우저가 Transform을 지원하더라도 Transform모듈의 레벨 1을 지원하는지 지원한다면?! 레벨 2는 지원을 하는지 확인해야하는 필요성을 깨닫게 되는 것이다.

https://www.w3.org/Style/CSS/specs.en.html

 

All CSS specifications

History Tests Selectors describes the element selectors used in CSS and some other technologies. Selectors are used to select elements in an HTML or XML document, in order to attach (style) properties to them. Elements can be selected based on their name,

www.w3.org


최근에는 W3C의 권고안에 없어도 브라우저에 구현할 수 있게 제약을 풀었고 드래프트에 있더라도 브라우저에서 사용이 가능하다. (참고로 WICG의 파워가 쎄다...)


Normal Flow

CSS 2.1에서 Visual Formatting Model 문서에서
Positioning Schemes & Normal Flow가 쓰여 있고 그곳에서 처음 등장했다.
중요한 것은 고유 명사다!

Position

(그래픽스 시스템에서 Abstract Calculate를 생각할 것)
어떤 Geometry 영역에 x, y, width, height를 결정할 때 추상적인 위치를 결정하게 하는 어떤 시스템을 말한다.
이 계산 방법에 따라
Static | Relative | Absolute | Fixed | Inherit 등이 있다.
즉, 각각 계산 공식이나 계산하는 컨텍스트인 것이다!

Normal Flow는 Position이 Static, Relative에서만 적용이 된다. Normal Flow는 총 3가지 계산 공식으로 이뤄져 있다.
Block Formatting Contexts(BFC), Inline Formatting Contexts (IFC), Relative Positioning이 있다. Relative Positioning의 경우는 Normal Flow의 일부이긴 하지만 Position 모델에서 정의하고 있다.
그렇기에 실제 Normal Flow를 계산하는 방법은 BFC, IFC 2가지가 있다. Block 계산 방식으로 그려질 것인지 아니면 Inline 계산 방식으로 그려질 것인지에 대한 원리를 BFC, IFC라고 한다.

Block Formatting Context(BFC)

Blcok -> 부모의 가로 길이를 갇그 채운 한 줄을 의미, 부모만큼 가로를 다 먹는 행위
따라서 BFC는 한 줄을 다 먹을 때 어떻게 계산하는지를 생각하는 것이고,
x는 언제나 0, width는 언제나 부모의 width이다.
그렇기 때문에 BFC 요소에서 생각해야할 것은
특성 1. 다음번 Block이 나올 때 Y자리가 어디인지만 생각하면 된다. (Y자리는 첫 번째 블록 컨텍스트의 height가 두 번째 컨텍스트의 Y값이 된다.) 특성 2. 안에 있는 블록요소의 height의 합이 나의 height가 된다.

이러한 계산 방법이 BFC이다.

Inline Formatting Context(IFC)
Inline -> 한 줄을 다 먹지 않고 자신의 컨텐츠 크기만큼만 가로를 차지한다.
동시에 다음 번 요소의 IFC요소의 x는 첫 번째 IFC요소의 가로길이만큼 떨어진 자리에 x가 결정된다.
추가적으로 inline width의 합이 부모의 width를 넘어가는 순간 밑으로 내려간다. 그러면 얼만큼 내려가야하는지(구성된 인라인 요소 중에 height가 가장 큰 애가 line-height가 돼서 line-height만큼 y값이 내려온다.)도 IFC에 포함되어 있다. baseline이라는 개념은 인라인을 구성하는 한 줄의 요소들 중 height가 제일 큰 요소가 있으면 그 요소를 기준으로 위에 맞출지 밑에 맞출지 가운데에 맞출지처럼 세로축 정렬이라는 개념이 생기고 이 또한 IFC 안에 있는 시스템이다.



IFC 영역이 있는데 다음을 BFC 영역을 사용하면 격리되고 그 다음에 바로 BFC를 사용하게 된다.

다음 코드를 살펴보자

<div style="width:200px;background:red">
	aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
</div>

해당 코드의 결과는 a의 글자들이 공백이 포함되어있지 않아서 width를 뚫고 계속 이어진다. 이것은 해당 a들의 글자들은 하나의 인라인요소(IFC)로 바라보기 때문이다.

<div style="width:200px;background:red">
	aaaaaaaaaaaaaaaaaa
	aaaaaaaaaaaaaaaaaa
	aaaaaaaaaaa
</div>

이럴 경우는 뚫고 나오지 않고 잘 표현된다.
이유는 공백을 주는 순간 하나의 span 태그처럼 행동한다.
아니면 다른 방법은 word-break 속성을 주는 것이다.
word-break라는 속성은 해당 IFC공간에서 공백문자가 없는 문자들을 전부 하나하나를 전부 인라인으로 바라보라는 속성이다. (당연히 브라우저에는 속도 저하의 원인이 된다.)
즉, 글자 하나하나를 전부 Geometry로 계산해야하기 때문에 느리다.


이번에는 BFC와 IFC를 합쳐보자.

See the Pen BFC + IFC (1) by Lee Sangkwon (@k9want) on CodePen.
 

 


우리가 명심해야할 부분은 렌더링 시스템과 DOM의 구조는 무관하다.
태그의 구조가 렌더링의 구조와 일치하는 것은 아니다.


Relative Positioning

noraml flow인 static으로 그린 다음에 상대적으로 이동시킨다.
기존 자리는 알고 있는 상태에서 붕떠서 이동한다.
relative는 static 위로 무조건 뜬다.
또한 relative는 그림만 그렇게 표현할 뿐이라는 것을 잘 알고 쓰자.
다시 말해 static으로 그린 다음에 relative로 이동시키는 만큼만 이동시켜서 그림을 그린다.





https://coding-farmer.tistory.com/14

 

CSS Rendering - 코드 스피츠 76회차를 보고나서 정리

목차 코드 스피츠라는 유튜브를 보고 나서 여태까지 내가 깊게 공부하지 않았다는 느낌을 받았습니다. 그래서 이제부터라도 깊게 공부하기 위해서 코드 스피츠에 올라온 영상들을 차근 차근 정

coding-farmer.tistory.com

 

'인턴' 카테고리의 다른 글

HTTP multipart  (0) 2023.03.16