Skip to content
This page has been auto-translated and may contain errors.View in English

CSS란 무엇인가

docs.scrimba.com

잘 만들어진 웹사이트를 하나 열어서 CSS를 걷어내면, 흰 배경에 검은색 텍스트만 세로로 쭉 늘어선 모습이 남습니다. 모든 제목, 모든 문단, 모든 링크가 순서대로 쌓여 있을 뿐 아무런 꾸밈도 없는 상태죠. 그 꾸밈없는 텍스트 뭉치가 바로 HTML입니다. 페이지를 디자인된 것처럼 보이게 만드는 모든 것, 즉 색상, 여백, 폰트, 칼럼과 카드, 내비게이션 바 같은 것들은 모두 CSS의 몫입니다. 이번 장에서는 이 두 번째 언어가 무엇이고, 첫 번째 언어와 어떻게 함께 작동하는지 다룹니다.

CSS 적용 전후의 페이지

CSS는 **Cascading Style Sheets**의 줄임말입니다. 여기서 기억해야 할 핵심은 style, 즉 "스타일"입니다. CSS는 페이지의 겉모습을 표현하는 방법입니다. HTML이 "이건 제목이다, 이건 문단이다, 이건 버튼이다"라고 말한다면, CSS는 "제목을 크고 진한 파란색으로 만들어라, 버튼에는 패딩을 주고 모서리를 둥글게 해라"라고 말합니다.

HTML을 방 안의 내용물, 즉 가구와 그 배치라고 생각하고, CSS를 페인트와 조명, 인테리어 배치라고 생각해보세요. 같은 방이지만 하나는 텅 비어 있고 다른 하나는 있고 싶은 공간이 됩니다. CSS는 HTML의 특정 부분을 가리키며 그 외관을 바꾸는 별도의 규칙들로 작성합니다.

CSS는 웹 페이지의 표현(presentation) 계층입니다. HTML이 구조와 의미를 제공하면, CSS는 그 구조를 읽어서 어떻게 렌더링해야 하는지를 기술합니다. 색상, 타이포그래피, 여백, 크기, 레이아웃이 그 대상입니다. 이 둘은 별도로 작성되도록 설계되어 있어서, 같은 HTML이라도 CSS만 바꾸면 완전히 다르게 다시 스타일링할 수 있고, 하나의 스타일시트로 수천 개의 페이지를 한꺼번에 스타일링할 수도 있습니다.

이 분리가 바로 핵심입니다. 콘텐츠는 HTML에, 표현은 CSS에 두면 마크업을 손대지 않고도 사이트를 리디자인할 수 있고, 페이지마다 일일이 수정하는 대신 공유하는 스타일시트 하나만 바꾸면 됩니다. 이 둘을 분리하는 습관은 첫 규칙을 작성할 때부터 들여야 할 만한 가치가 있습니다.

CSS는 표현 계층이며, 브라우저는 이를 렌더링의 독립된 단계로 적용합니다. 즉, HTML을 파싱하여 DOM(Document Object Model, 마크업으로부터 브라우저가 만들어내는 실시간 요소 트리)을 만들고, CSS를 파싱하여 일련의 규칙으로 바꾸고, 그다음 규칙을 요소에 매칭시켜 각 요소의 최종 스타일을 계산합니다. CSS는 DOM 트리 자체를 절대 바꾸지 않습니다. 단지 그 위를 꾸밀 뿐입니다.

이렇게 단계가 나뉜 모델 때문에 관심사의 분리가 원칙만이 아니라 실제로도 유효하게 작동합니다. 의미가 온전히 HTML에 담긴 페이지는 우아하게 성능이 저하됩니다. CSS 로드가 실패해도 콘텐츠는 여전히 존재하고 여전히 순서대로 나열되어 있는데, 구조와 표현이 처음부터 서로 얽혀 있지 않았기 때문입니다. 또한 같은 마크업으로 라이트 테마와 다크 테마를, 혹은 인쇄용 레이아웃과 화면용 레이아웃을 HTML을 전혀 바꾸지 않고 구현할 수 있는 이유도 여기에 있습니다. 표현은 콘텐츠에 내재된 속성이 아니라 덧붙이는 계층입니다.

css
h1 {
  color: navy;
  font-size: 2rem;
}

이것이 하나의 CSS 규칙입니다. 페이지 안의 모든 <h1> 제목을 찾아서 네이비색으로, 더 크게 만듭니다. HTML은 그대로 남아 있고, 외관만 바뀝니다.

JunoCSS 적용 전후의 페이지 HTML은 내용이고, CSS는 겉모습입니다. 페이지의 특정 부분을 가리키며 그 외관을 바꾸는 규칙을 작성합니다. 예를 들어 제목을 크고 파랗게 만드는 식이죠. 그 밑에 있는 페이지 자체는 바뀌지 않고, 보여지는 방식만 바뀝니다. 이 분리가 CSS의 전부라고 할 수 있습니다.
JunoCSS 적용 전후의 페이지 CSS는 표현이고 HTML은 구조이며, 이 둘은 의도적으로 분리되어 있습니다. CSS를 다시 스타일링하면 같은 마크업이 완전히 다르게 보이고, 스타일시트 하나를 공유하면 모든 페이지에 적용됩니다. 첫 규칙을 작성할 때부터 콘텐츠와 외관을 분리하는 습관을 들이세요.
JunoCSS 적용 전후의 페이지 브라우저는 HTML을 DOM으로 파싱하고, CSS를 규칙으로 파싱한 다음, 각 요소의 스타일을 계산합니다. CSS는 트리를 꾸밀 뿐 절대 다시 작성하지 않습니다. 이렇게 단계가 나뉜 모델 때문에 의미가 HTML에 담긴 페이지는 CSS 로드가 실패해도 여전히 작동합니다. 표현은 콘텐츠에 내재된 것이 아니라 덧붙이는 계층입니다.

CSS가 HTML을 가리키는 방법

CSS는 페이지의 올바른 부분을 찾아낼 수 있어야 비로소 유용해집니다. 이때 사용하는 것이 **선택자(selector)**입니다. 규칙 맨 앞에 오는 부분으로, 무엇을 꾸밀지 지정합니다. 위 규칙에서 h1이 선택자이고, "모든 h1 제목"을 의미합니다.

보통은 HTML 요소에 class를 붙이고, CSS에서 그 클래스를 가리켜서 요소를 지정합니다. 클래스는 여러분이 직접 정하는 이름입니다.

html
<button class="buy-button">지금 구매</button>
css
.buy-button {
  background-color: teal;
  color: white;
}

.buy-button 선택자는 그 클래스를 가진 요소를 찾아서 스타일을 적용합니다. 앞으로 다양한 종류의 선택자를 만나게 되겠지만, 가장 많이 사용하게 될 것은 클래스입니다.

CSS 규칙은 두 부분으로 이루어집니다. 어떤 요소를 매칭할지 지정하는 선택자와, 그 요소를 어떻게 꾸밀지 지정하는 선언 블록입니다. 선택자는 CSS가 DOM에 들어가서 스타일을 적용할 요소를 골라내는 방식입니다. 요소 타입(h1), 클래스(.buy-button), id, 관계 등으로 선택할 수 있습니다.

html
<button class="buy-button">지금 구매</button>
css
.buy-button {
  background-color: teal;
  color: white;
}

실제로는 요소 타입이나 id보다 클래스로 스타일링하는 경우가 훨씬 많습니다. 클래스는 재사용이 가능하고 내재된 특정도(specificity) 부담이 없기 때문입니다. 선택자 장에서 전체 범위와 각각을 어떤 상황에 써야 하는지 다룹니다.

선택자는 CSS의 쿼리 언어입니다. 각 선택자는 어떤 규칙을 적용할지 결정하기 위해 브라우저가 모든 요소를 대상으로 검사하는 패턴입니다. 이 매칭에는 비용이 따르며, 특정도(specificity)(같은 속성을 설정하는 여러 규칙이 같은 요소에 충돌할 때 브라우저가 승패를 가르기 위해 선택자에 부여하는 가중치)와도 맞물립니다. 클래스는 요소 타입보다 무겁고, id는 클래스보다 무겁고, 인라인 스타일은 그보다 더 무겁습니다.

css
.buy-button {
  background-color: teal;
  color: white;
}

실제로 중요한 결과는, 어떻게 선택하느냐가 단순한 타겟팅 문제가 아니라 설계 결정이라는 점입니다. id와 깊게 중첩된 선택자로 모든 것을 지정하면 특정도가 계속 쌓여서 이후의 규칙들이 이를 덮어쓰기 어려워지고, 이런 식으로 특정도가 계속 상승하면서 스타일시트가 굳어버립니다. 평평하고 클래스 기반인 선택자는 특정도를 낮고 예측 가능하게 유지하며, 확장 가능한 CSS 방법론 대부분이 클래스를 기반으로 하는 이유도 여기에 있습니다. 선택자 장에서 특정도를 제대로 파헤칩니다.

JunoCSS가 HTML을 가리키는 방법 선택자는 규칙에서 무엇을 꾸밀지 지정하는 부분입니다. 처음 배우기 가장 편한 것은 클래스입니다. HTML 요소에 class="이름"을 붙이고, CSS에서 .이름을 스타일링하면 됩니다. 다른 종류들은 아직 걱정하지 마세요, 클래스만으로도 오랫동안 충분합니다.
JunoCSS가 HTML을 가리키는 방법 모든 규칙은 DOM 안의 요소를 매칭하는 선택자로 시작하고, 타입, 클래스, id, 관계로 매칭할 수 있습니다. 기본적으로 클래스를 사용하세요. 재사용이 가능하고 특정도를 관리하기 쉽습니다. 선택자 장에서 전체 도구를 다룹니다.
JunoCSS가 HTML을 가리키는 방법 선택자는 쿼리 언어이며, 각각은 규칙이 충돌할 때 누가 이길지 결정하는 특정도 가중치를 가집니다. id가 클래스를 이기고, 클래스가 타입을 이기고, 인라인이 전부를 이깁니다. 어떻게 선택하느냐는 유지보수성의 문제이므로, 평평하고 클래스 기반으로 유지해서 특정도가 스타일시트를 굳혀버리지 않게 하세요. 특정도는 선택자 장에서 제대로 다룹니다.

"cascading"이 의미하는 것

Cascading Style Sheets에서 첫 단어는 사람들이 흔히 지나치는 부분이지만, 사실 많은 것을 설명해줍니다. 같은 요소에 여러 규칙이 적용될 수 있고, 그 규칙들이 서로 충돌할 수 있습니다. 어떤 규칙은 문단을 회색으로 만들고, 다른 규칙은 이 특정 문단을 검은색으로 만들라고 할 수도 있습니다. **캐스케이드(cascade)**란 브라우저가 어느 규칙이 이길지 결정할 때 사용하는 일련의 규칙입니다.

대부분의 경우 이것 하나로 정리됩니다. 두 규칙의 특정도가 같다면, 나중에 작성된 규칙이 이깁니다. 아직 전체 그림을 다 알 필요는 없습니다. 스타일이 예상한 대로 나오지 않을 때는 보통 CSS가 고장 난 것이 아니라 다른 규칙이 이겼기 때문이라는 것만 기억하면 됩니다.

캐스케이드는 여러 규칙이 같은 요소를 대상으로 같은 속성을 설정할 때 그 충돌을 해결하는 알고리즘입니다. 순서대로 몇 가지 요소를 따집니다. 규칙이 어디서 왔는지, 선택자의 특정도가 얼마나 높은지, 그리고 최종 동점 처리 기준으로 소스 순서(나중에 나온 쪽이 이김)를 봅니다. 두 규칙의 특정도가 같다면, 마지막에 선언된 쪽이 이깁니다.

"내 CSS가 왜 안 되지"라는 순간의 대부분은 이 메커니즘 때문에 벌어집니다. 스타일이 적용되지 않는 것이 아니라, 더 높은 순위의 규칙에 의해 덮어써지고 있는 것입니다. 변화를 강제하려고 규칙을 더 쌓는 대신 캐스케이드를 제대로 읽어내는 것이야말로 CSS와 싸우는 것과 CSS를 다루는 것을 가르는 습관입니다. CSS의 동작 방식 장에서 전체 해석 순서를 살펴봅니다.

캐스케이드는 CSS의 충돌 해결 알고리즘이며, 그 순서를 알면 대부분의 스타일링 버그가 미스터리가 아니라 그냥 찾아보면 되는 문제로 바뀝니다. 경쟁하는 선언들을 다음 순서로 해결합니다. 출처와 중요도(작성자 스타일 대 브라우저 기본값 대 !important), 그다음 특정도(선택자의 가중치), 그다음 소스 순서(마지막 동점 처리에서 나중 규칙이 이김).

이것이 프로덕션 규모에서 중요한 이유는, 여러분이 작성하는 모든 오버라이드가 이 순위표에서의 한 수라는 점 때문입니다. 충돌을 이기려고 !important나 id를 쓰면 같은 요소를 나중에 다뤄야 하는 모든 규칙의 기준선이 올라가고, 이런 상승이 쌓이면 아무도 안전하게 손댈 수 없는 스타일시트가 됩니다. 지속 가능한 해법은 거의 항상 여기서 특정도를 높이는 것이 아니라 다른 곳에서 특정도를 낮추는 것입니다. 최신 CSS는 특정도 경쟁 없이 캐스케이드를 제어할 수 있는 도구를 제공하는데, 캐스케이드 레이어가 그 예이며 CSS 구조화와 확장 장에서 다룹니다. 전체 해석 순서는 CSS의 동작 방식을 참고하세요.

Junocascading이 의미하는 것 Cascading은 같은 요소에 여러 규칙이 적용될 수 있다는 뜻이고, 캐스케이드는 그중 어느 것이 이길지 결정합니다. 일상적으로는 이렇게 정리됩니다. 두 규칙의 특정도가 같다면 나중 것이 이깁니다. 그러니 스타일이 안 나타난다면 다른 규칙이 이겼을 가능성이 큽니다. 저도 이걸 이해하기까지 한참 헷갈렸습니다.
Junocascading이 의미하는 것 캐스케이드는 출처, 그다음 특정도, 그다음 소스 순서로 충돌을 해결하며, 동점이면 나중 규칙이 이깁니다. "내 CSS가 안 돼요"라는 순간은 대부분 버그가 아니라 오버라이드입니다. 규칙을 더 쌓아 강제하는 대신 왜 졌는지 읽어내는 법을 배우면 CSS가 싸움처럼 느껴지지 않게 됩니다.
Junocascading이 의미하는 것 충돌은 출처와 중요도, 그다음 특정도, 그다음 소스 순서로 해결됩니다. 여러분이 작성하는 모든 오버라이드는 이 순위표에서의 한 수이므로, !important나 id로 이기면 그 뒤에 오는 모든 규칙의 기준선이 올라갑니다. 지속 가능한 해법은 여기서 특정도를 높이는 게 아니라 다른 곳에서 낮추는 것입니다. 캐스케이드 레이어는 경쟁 없이 통제권을 줍니다.

여기서부터 CSS는 어디로 향하는가

CSS는 핵심만 보면 작은 언어입니다. 선택자 하나와 몇 개의 속성-값 쌍이 전부죠. 하지만 그 범위는 아주 넓게 뻗어 있습니다. 요소를 지정하고 속성을 설정할 수 있게 되면, 이 핸드북의 나머지는 알아둘 만한 속성들과 그 위에 세워진 체계들을 다룹니다. 여백과 크기를 다루는 박스 모델, 그다음 색상과 타이포그래피, 그리고 페이지 전체를 배치하는 레이아웃 도구인 flexbox와 grid까지 이어집니다.

다음 장인 CSS의 동작 방식에서는 이번 장에서 소개한 메커니즘을 구체적으로 다룹니다. CSS를 페이지에 연결하는 세 가지 방법, 규칙의 정확한 구조, 그리고 캐스케이드와 상속이 모든 요소의 최종 모습을 어떻게 결정하는지를 살펴봅니다.