The cascade is an algorithm that defines how user agents combine property values originating from different sources. The cascade defines the origin and layer that takes precedence when declarations in more than one origin, cascade layer, or @scope block set a value for a property on an element.
MDN Web Docs
캐스케이딩
은 CSS
의 중요한 규칙으로, CSS
자체도 Cascading Style Sheet
의 준말이다.
MDN에서는 Cascade
를 User agent(주로 웹 브라우저)가 서로 다른 소스에서 비롯된 속성 값을 결합하는 방식을 정의하는 알고리즘이라고 설명하고 있다.
Cascade
를 '폭포처럼 흐르는, 위에서 아래로 쏟아지는' 등으로 해석해서 설명하는 곳도 있지만 계단식
으로 이해하는 편이 가장 쉬울 것 같다. 쉽게 설명하자면 동일한 한 요소에 두 가지 이상의 규칙(CSS 선언)되었을 때, 무엇을 우선해서 적용해야 하는지에 대한 규칙이다.
캐스케이딩
에는 아래와 같은 사항이 고려된다.
스타일시트는 세가지의 Origin을 가질 수 있으며, Origin types에 의한 중요도 순서는 다음과 같다.
중요도 순서에 따라서 사용자 도구 스타일시트를 사용자 스타일시트가 덮어쓰기(Override)하고,
사용자 스타일시트를 작성자 스타일시트가 덮어쓰기 한다.
작성자 스타일시트 > 사용자 스타일시트 > 사용자 도구 스타일시트
일반적으로 우리가 생각하는 CSS
파일을 생각하면 된다.
페이지 제작자의 의도대로 정의된 스타일로, 링크된 CSS
파일(External CSS)이나 HTML
의 <style>
태그 내에 작성된 스타일(Internal CSS)을 모두 포함한다.
사용자 개인이 별도로 정의한 스타일시트.
User agent에 따라 사용자가 직접 스타일시트를 구성할 수도 있고 확장 프로그램을 이용해야 하는 경우도 있다.
User agent에서 기본적으로 제공하는 스타일이 담긴 스타일시트.
앞서 말했듯이 User agent는 대개 웹 브라우저라고 이해하면 편하고,
웹 브라우저마다 기본적인 스타일 설정이 조금씩 다르다.
아무런 스타일도 적용되지 않은 HTML
파일을 사파리와 크롬으로 각각 열어봤을 때,
기본 폰트부터 다르다는 걸 확인할 수 있다.
웹 브라우저의 기본 제공 스타일로 인해 원하지 않는 스타일이 설정될 수 있으므로,
일반적으로 CSS
초기화를 통해 불필요한 스타일 설정을 없앤 뒤 CSS
작업을 하게 된다.
일반적으로 명시도라고 칭하는데, 지정한 대상이 명확할 수록 우선순위가 높다고 이해하면 편하다.
CSS
선언을 할 때 사용하는 선택자가 얼마나 구체적인지를 중점적으로 본다.
기본적으로는 아래의 규칙을 따른다.
Inline CSS > #Id selector > .Class selector > Tag name(element selector)
HTML
문서 태그 내에 style 속성을 이용하여 스타일을 정의하는 인라인 방식이 가장 우선순위가 높다. 그 다음으로는 아이디 선택자, 클래스 선택자, 그리고 최하위가 태그 이름을 사용하는 요소 선택자이다.
명확한 대상을 지정한다는 말의 의미를 생각해보면 딱히 외우지 않아도 이해할 수 있다.
예를 들어보자면,
즉 아이디 선택자는 동일한 이름을 사용하지 않으므로 반복해서 사용 가능한 클래스 선택자보다 명시도가 높고, 인라인 스타일 선언은 오직 한 태그만을 위한 스타일 선언이므로 명시도가 가장 높다.
그리고 선택자의 명시성(특정성)은 합산 적용된다.
.wrap #content .card { background-color: #fff; }
#content .card { background-color: #000; }
이 경우 .card
의 배경색은 #fff
가 된다.
일부 CSS
속성 값은 상위 요소에서 하위 요소에 상속된다.
아래는 상속되는 속성의 예이다.
가까운 조상 요소일수록 우선 순위가 높다.
하위 요소에 별도로 속성이 부여되어 있을 경우는 자식 요소의 속성 값을 따른다.
<!-- HTML -->
<body>
<p>
<span> 저녁이라 배가 고파요 </span>
</p>
</body>
/* CSS */
body { color: #fff; }
p { color: #000; }
이 경우 span
의 글씨색은 #000
이 된다.
위와 같은 사항을 고려한 후 최종적으로 지정된 우선순위에 따르되,
모순된 명령(한 대상에 두 가지 이상의 스타일 규칙)이 서로 같은 origins, 명시성을 가진다면 가장 나중에 선언된 명령을 따른다.
p { color: red; }
p { color: blue; }
위와 같은 경우 p
의 글씨색은 파란색이 된다.
이 모든걸 다 무시하는 깡패같은 녀석이 !important
명령이다.
선언된 CSS
속성 뒤에 !important
를 붙이면 중요도를 최우선으로 올려준다.
짱인데?! 라고 생각할 수 있지만 현업에서는 사용을 지양하고 있다고 한다.
#itemBox { color: #fff; }
#itemBox { color: #000 !important; }
이 경우 #itemBox
의 글씨 색은 #000
이 된다.
!important
명령은 인라인 CSS 선언보다 우선한다.
특별한 점은, !important
명령에 한해서 origin types에 의한 우선 순위가 다르다.
사용자 도구 !important > 사용자 !important > 작성자 !important
사용자에게 특수한 요구사항(큰 글꼴, 색상 조합 등)이 있을 수 있기 때문에
사용자가 해당 부분을 조정할 수 있도록 균형을 맞춘것이라고 한다.
웬만하면 사용하지 말고, 다른 규칙을 통해 CSS 충돌을 최소화하도록 하자.