CSS Priority

2024년 11월 20일

CSS는 작업의 우선 순위가 중요하다.

위의 그림은 CSS의 우선순위에 대한 내용을 설명하고 있는 그림입니다. CSS는 우선순위에 따라서 스타일이 적용되는데 이러한 우선순위는 어떻게 결정이 되는 것일까요? 이에 대해서 알아보기 위해서 CSS의 우선순위에 대해서 알아보겠습니다.

1. Transition declarations (전환 선언)

/* 기본적인 전환 선언 */
.element {
  transition: all 0.3s ease;
  transition: background-color 0.5s ease-in-out;
}

/* 여러 속성에 대한 전환 선언 */
.button {
  transition:
    background-color 0.3s ease,
    color 0.2s linear,
    transform 0.3s ease-in-out;
}

/* 개별 전환 속성 선언 */
.card {
  transition-property: transform, opacity;
  transition-duration: 0.3s, 0.5s;
  transition-timing-function: ease-out, linear;
  transition-delay: 0s, 0.1s;
}
Transition 선언은 요소의 상태에 delay를 주고 특정 애니메이션 알고리즘을 적용하여 애니메이션을 부드럽게 애니메이션화 하는데 주로 사용이 됩니다. 이 규칙은 우리가 흔히 가장 우선된다고 생각하는 !important 보다 더 중요한 우선 순위로 적용이 됩니다.
이러한 이유는 무엇일까요? 이에 대한 이유는 transition의 목적과 연결이 됩니다. 앞 서 설명 했듯이 transition은 시간에 따라서 클래스가 적용되는 컴포넌트를 움직이게 끔 하는 역할을 수행합니다. 하지만 여기서 갑자기 !important 가 우선 순위가 더 높다고 해서 진행 중이던 애니메이션이 끊어져 버리면 어떻게 될까요? 사용자의 경험과 일관성을 깨드리는 문제가 발생할 수 있습니다.
이외에도 transition은 시간이 지남에 따라 움직임을 계산하여 적용 시키는 방법을 사용합니다. 이러한 계산 방식은 아래와 같을 것입니다.
  1. 현재 상태의 값을 파악
  2. 목표 상태의 값을 계산
  3. 타이밍 함수에 따라 중간 값을 계산
  4. 각 프레임마다 새로운 값을 스타일에 적용
이러한 과정이 우선순위가 뒤로 밀려서 깨지게 된다면 무결성이 깨지는 문제가 발생하기 때문에 transition이 다른 스타일 규칙 보다 우선순위가 높게 적용되어야 합니다.

2. Important user agent declarations (중요 사용자 에이전트 선언)

/* 브라우저의 기본 스타일시트에서 */
input[type="hidden"] {
  display: none !important;
}

/* Firefox의 특정 내부 스타일 */
input::-moz-focus-inner {
  border: none !important;
  padding: 0 !important;
}

/* Chrome의 자동완성 스타일 */
input:-webkit-autofill {
  background-color: #ffffff !important;
  background-image: none !important;
}

/* 브라우저의 필수 접근성 스타일 */
[aria-hidden="true"] {
  display: none !important;
}
사용자 에이전트 선언은 브라우저에서 기본적으로 제공하는 스타일입니다. !important가 붙은 경우 매우 높은 우선순위를 가집니다. 이 규칙은 개발자가 직접 조정이 가능한 규칙이 아닙니다. 이미 우리가 사용하는 웹 브라우저에 적용되어 있는 스타일을 이해할 수 있게 위와 같이 css 로 표현한 것입니다.
이러한 스타일은 브라우저의 내부 스타일시트에 정의되어 있으며, 보안이나 접근성과 같은 중요한 기능을 보장하기 위해 사용됩니다.
여기서 궁금한 점이 생겼는데 사용자 에이전트 선언이 뭔지가 좀 궁금해졌습니다.
/* 브라우저의 기본 스타일시트 예시 */
html {
  display: block;
}

body {
  margin: 8px;
  line-height: 1.2;
}

/* 폼 요소의 기본 스타일 */
input {
  background-color: white;
  border: 1px solid gray;
  padding: 2px;
}

/* 링크의 기본 스타일 */
a:link {
  color: blue;
  text-decoration: underline;
}

/* 테이블의 기본 스타일 */
table {
  border-collapse: separate;
  border-spacing: 2px;
}
위의 예시는 css를 작성한 것이 아니고 실제로 어떠한 스타일을 적용하지 않아도 html, body와 같은 태그들이 기본적인 웹의 구조를 갖기 위해서 선언하지 않아도 설정되어 있는 스타일을 이해하기 쉽게 표현한 것입니다.
사용자 에이전트 선언은 브라우저에서 기본으로 제공하는 기본 스타일을 사용하여 스타일을 선언하는 방식을 의미합니다. 이러한 설정은 개발자가 직접 수정할 수 없다는 특징을 갖고 있습니다. 그러면 이와 반대되는 사용자 선언 은 무엇인지도 궁금해졌습니다.
/* 사용자가 브라우저 설정을 통해 정의한 스타일 예시 */
@media (prefers-color-scheme: dark) {
  body {
    background-color: black;
    color: white;
  }
}

/* 사용자 정의 글꼴 설정 */
body {
  font-family: "My Custom Font";
  font-size: 18px;
}

/* 접근성을 위한 사용자 설정 */
* {
  line-height: 2;
  letter-spacing: 0.1em;
}

/* 고대비 모드 설정 */
@media (prefers-contrast: high) {
  * {
    background: white !important;
    color: black !important;
  }
}
사용자 선언은 우리가 흔히 css 를 이용하여 설정하는 스타일을 의미합니다. 사용자의 필요와 선호도에 따라서 웹사이트의 표시 방식을 조정할 수 있고 이러한 방법들을 사용자 선언을 통해서 정의했다고 표현합니다.

3. Important user declarations (중요 사용자 선언)

/* 사용자의 접근성 설정 */
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

/* 사용자의 글꼴 크기 설정 */
html {
  font-size: 20px !important; /* 사용자가 설정한 기본 글꼴 크기 */
}

/* 사용자 정의 색상 scheme */
:root {
  color-scheme: dark !important; /* 사용자가 강제로 다크 모드 설정 */
}
앞서 설명한 사용자 선언에 !important가 붙일 경우 개발자가 작성한 대부분의 스타일보다 우선적으로 적용됩니다.

4. Important Author Declarations

/* 중요한 작성자 선언 */
.element {
  color: red !important;
}

/* 중요한 작성자 선언 */
.element {
  color: blue !important;
}
작성자 선언은 개발자가 직접 작성한 스타일을 의미합니다. 이러한 스타일은 사용자 에이전트 선언보다 우선 순위가 높습니다. 그리고 사용자 선언보다는 우선 순위가 낮습니다.