CSS는 'Cascading StyleSheet'의 준말이다.
'Cascade(이하 케스케이드)'를 구글에 검색하면 다음과 같이 계단식의 폭포, 분수 사진이 나타난다.

검색 결과에서 알 수 있듯이, 케스케이드는 계단식 구조가 있는 계층성을 의미한다.
CSS는 여러 스타일 규칙이 충돌할 때 계단식으로 우선순위에 따라 적용된다. 즉, CSS는 규칙에 따라 "계층성"을 가진다. 그래서 HTML 요소에 여러 스타일을 적용할 때 이 스타일들이 어떻게 결합되고 결정되는지에 대한 명확한 이해가 필요하다.
다음과 같이 하나의 div 요소에 두 가지 스타일 규칙을 중복해서 적용했을 때 어떤 일이 벌어지게 될까?
/* 첫 번째 규칙 */
div {
color: red;
}
/* 두 번째 규칙 */
div {
color: blue;
}
위 코드는 케스케이딩의 원리에 의해 두 번째 규칙이 첫 번째 규칙을 덮어쓰게 된다. 위 코드에서 적용된 케스케이딩 원리는 여러 스타일 규칙이 중복되어 충돌할 때, 마지막에 작성된 코드가 최종적으로 적용된다는 특성이다.
CSS의 우선순위와 계층 구조를 이해하는 것은 스타일링의 정확성과 효율성을 높이는 데 중요하다. 이를 통해 충돌을 피하고, 코드의 가독성을 개선할 수 있다.
네이버 홈페이지에서 개발자 도구(F12)를 열어서 Styles 검사를 해보면 다음과 같은 화면을 볼 수 있다.
오른쪽 아래 형광색 네모 박스의 CSS 속성들을 보면 중복된 선택자도 있고, 중복된 속성도 존재하고, 그 중에서는 취소표로 처리된 속성도 존재한다.
위 사진에서는 3번째 탭의 font-size 속성과 line-height 속성이 4번째 탭에도 존재하는데, 3번째 탭의 속성으로 스타일을 덮어써버렸다. 케스케이딩 규칙에 의해서 이런 결과가 나타난 것이다.

Styles를 조금 내리다보면 user agent stylesheet라는 속성도 있고, Ingherited from html.fzoom이라는 것도 보인다. 우선은 이것들이 뭔지 지금은 잘 모르겠으니 이어서 알아보자.

네이버 홈페이지 구경해보기를 통해 개발자 도구 styles 검사에서 user agent stylesheet라는 것을 확인할 수 있었다. 이것은 스타일 시트의 타입을 나타내는 것으로, 타입의 종류는 다음과 같다.
User Agent Stylesheet는 웹 브라우저에서 기본적으로 제공하는 스타일 시트이다. 브라우저는 HTML 요소에 기본 스타일을 적용하는데, body 태그에 기본으로 설정된 margin 값이나, h1 태그가 자동으로 크기가 크게 표시되는 등을 말한다. 이런 기본 스타일들이 User Agent Stylesheet에서 나오는 것이다.
브라우저마다 기본 스타일이 다를 수 있지만, 대부분의 브라우저는 HTML 요소에 어느 정도의 스타일을 미리 적용한다. User Agent Stylesheet는 스타일 시트 중에 우선순위가 가장 낮기 때문에 대부분 새로운 규칙을 적용하여 개발한다.
Author Stylesheet는 개발자가 직접 작성한 CSS 파일로,style.css와 같은 외부 CSS 파일을 말한다. Author Stylesheet를 작성하여 HTML에 연결하게 되면, 기본 스타일인 User Agent Stylesheet를 override한다.
User Stylesheet는 사용자가 직접 설정한 스타일이다. 사용자가 브라우저 설정에서 글꼴 크기, 배율 조정 등의 커스텀 스타일을 설정하면 웹 페이지가 해당 스타일을 따르게 된다. 우선 순위는 Author Stylesheet가 더 높다.
스타일시트 종류 별 우선순위로 나타내면, 1) Author > 2) User > 3) User Agent이다.
CSS에 동일한 속성을 부여했을 때 중복되어 충돌이 일어나면 우선순위로 인한 캐스케이딩이 발생한다.
즉, 우선순위가 낮은 속성은 우선순위가 높은 속성에 오버라이딩 된다.
!important (중요도)!important라는 키워드를 선언하여 다른 스타일 규칙보다 최우선순위를 얻을 수 있다.
/* 기본 스타일 */
p {
color: red;
}
/* !importance 선언 */
p {
color: blue !important;
}
위 코드에서는 color: blue !important;가 선언되었기 때문에 color: red;는 무시되고 최종적으로 빨간색이 적용된다. !important는 특정 스타일을 강제할 때 유용하지만, 너무 많이 사용하면 유지보수성이 떨어질 수 있으므로 신중하게 사용해야 한다.

인라인 스타일을 구현하면 CSS 파일이나<style> 태그에서 선언한 스타일보다 높은 우선순위를 가진다.
즉, Inline Style이 Author Stylesheet보다 우선순위가 높다.
<p style="color: green;">이 문장은 초록색입니다.</p>
외부 스타일시트, 내부 스타일시트, 인라인 스타일 중 인라인 스타일이 최종적으로 적용된 모습을 확인할 수 있다.


외부 스타일시트, 내부 스타일시트 중에서는 내부 스타일시트가 우선 순위가 더 높다.
명시도는 CSS 선택자가 얼마나 구체적인지 수치화한 개념이다. 선택자의 우선순위를 숫자로 변환하여 비교할 수 있다. 선택자를 구체적으로 작성할수록 명시도가 주로 높다.
명시도를 비교할 때 더 왼쪽 자리의 숫자가 클수록 우선순위가 높아진다.
| 우선순위 | 종류 | 명시도 |
|---|---|---|
| 1 | id 선택자(#id) | (0, 1, 0, 0) |
| 2 | 클래스, 속성, 가상 클래스 | (0, 0, 1, 0) |
| 3 | 태그(div 등), 가상 요소(::before 등) | (0, 0, 0, 1) |
Inline Style은 가장 높은 명시도(1,000,000)를 가지게 된다.
아래 예제에서 아래 속성이 우선순위가 더 높은 것이 되어 오버라이드 된다.
수가 높아도 왼쪽에 있는 숫자가 존재하기만 해도 우선 순위가 낮아진다.
/* Specificity (0,0,3,0) */
.text .description .info{
color: blue;
}
/* Specificity (0,1,1,0) */
/* 더 높은 우선순위 */
#title .text{
color: red;
}
해당 사이트에서 명시도 검사를 수행해볼 수도 있다.
아래 예시에서도, id 선택자가 존재하는 아래 속성이 더 높은 우선 순위를 가진다.

동일한 명시도를 가진 규칙이 여러 개 존재할 경우 소스 코드에서 나중에 작성된 스타일이 우선적으로 적용된다. 즉, 코드에서 더 아랫 줄에 작성된 코드가 우선 순위가 높아진다.
아래 코드에서 두 개의 p 요소 스타일이 동일한 명시도를 가지지만 나중에 선언된 스타일이 우선 적용되므로, 최종적으로 color: blue;가 적용된다.
/* 첫 번째 선언 */
p {
color: red;
}
/* 두 번째 선언 (나중에 작성됨) */
p {
color: blue;
}

이 원칙은 같은 명시도를 가진 스타일 규칙이 충돌할 때 적용되므로 스타일이 예상과 다르게 적용될 경우 소스 코드 순서를 확인하는 것이 중요하다.
CSS는 특정 속성을 부모 요소로부터 자식 요소에게 "상속"하는 기능을 가지고 있다.
하지만 모든 CSS 속성이 상속되는 것은 아니다.
상속되는 속성 (텍스트 관련 속성)
상속되지 않는 속성 (박스 모델 관련 속성)
강제 상속 (inherit, initial, unset)
상속되지 않는 속성을 강제로 상속하거나 기본값을 적용할 수 있다.
/* 부모 요소의 color 값을 자식 요소에도 적용 */
div {
color: red;
}
p {
color: inherit; /* 부모의 color를 상속 */
}
/* 기본값으로 리셋 */
span {
all: initial;
}
/* 속성 유형에 따라 inherit 또는 initial 적용 */
strong {
all: unset;
}
네이버 홈 구경하기에서도 Inherited from~을 확인할 수 있었다.
이는 html.fzoom이라는 파일에서 CSS 속성을 물려받은 것이다.

CSS 구현에 있어서 핵심 원칙인 케스케이딩을 살펴보았다.
캐스케이딩 조건에는 명시도, 코드 순서, 스타일시트 종류 등이 있으며, 캐스케이딩을 잘 이해하고 CSS를 구현하면 보다 예측 가능한 스타일링을 할 수 있을 것이다!