개발 기술/개발 이야기

[CSS] 스타일 우선순위를 정하는, Cascade Layer(@layer)

by GicoMomg (Lux) 2022. 9. 11.

🙂 이번 시간에는 CSS의 스타일 우선순위를 정할 수 있는 @layer에 대해 알아보았다!
만약 CSS의 명시도를 알고 있다면 “1. CSS 스타일을 선언할 때, 우선순위가 있다고?”은 넘어가자!


1. CSS 스타일을 선언할 때, 우선순위가 있다고?

1) CSS 스타일 선언 방식

  • CSS에서 스타일을 선언하는 방식은 6가지가 존재한다.
  • 그럼 이 6가지에는 어떤 것이 있을까? 간단히 알아보자 🙂

(1) 속성값에 !important를 사용한 경우

  • 스타일 속성값에 !important를 사용해 스타일을 우선 적용할 수 있다.
h1 {
  color: red !important;
}

(2) HTML에 style로 선언한 경우

  • HTML에서 인라인 스타일 방식으로 지정할 수 있다.
<h1 style="color: red;"> hello world </h1>

(3) id로 선언한 경우

  • 아이디를 이용해 스타일을 지정할 수 있다.
#id {
  color: red;
}

(4) 클래스, 의사 클래스로 선언한 경우

  • 클래스를 이용해 스타일을 지정할 수 있다.
.class { /* 클래스 */
  color: red;
  &:hover {     /* 의사클래스 */
    color: blue;
  }
}

(5) 요소 이름으로 선언한 경우

  • 요소 이름(태그)을 사용하여 스타일을 적용할 수 있다.
h1 {
  color: red;
}

(6) 상속으로 스타일을 선언한 경우

  • p태그에 스타일을 적용하면, 상속으로 인해 span태그(자식)에도 스타일이 적용된다.
<p class="parent"> 부모 <span>자식</span> </p>
.parent {
  color: red;  /* span에 color: red가 적용됨 */
}

🙂 그런데 스타일을 어떤 방식으로 선언하냐에 따라 우선순위가 달라진다는데 어떻게 확인할 수 있을까?
바로 명시도로 알 수 있다!



2) 명시도란?

  • 명시도는 스타일이 적용되는 우선순위로, 수치가 클수록 우선순위가 높다.
  • 만약 요소에 적용하는 스타일이 충돌하는 경우, 명시도가 높은 선택자를 적용한다.
  • 단, !important는 제일 큰 명시도를 가진다.

선언 방식  명시도 계산
인라인 스타일  인라인 스타일로 선언시 1000단위로 명시도가 증가한다.
id  id로 선언시 100단위로 명시도가 증가한다.
클래스(.class), 의사 클래스([속성], :hover, :focus)  클래스, 의사클래스로 선언시 10단위로 명시도가 증가한다.
요소(h1, div), 의사 요소(:after)  요소, 의사요소로 선언시 1단위로 명시도가 증가한다.
  • 이처럼 CSS는 선언 방식에 따라 스타일 우선순위가 달라지고, 적용되는 스타일도 달라진다.
  • 그렇기에, 개발자는 CSS 스타일을 선언할 때 명시도와 작성 순서를 고려해주어야 하는데,
  • 만약, 특정 스타일 그룹 간에 우선순위를 정하고 싶다면? @layer를 사용하는 것이다!








2. @layer에 대해 알아보자!

1) @layer란?

  • @layer는 스타일을 레이어로 그룹화할 수 있으며, 레이어의 스타일 우선순위를 정할 수 있다.
  • 이때 레이어 간의 우선순위에는 “선택자 명시도”, “속성 선언 순서”는 영향을 주지 않는다.
  • 레이어는 아래와 같이 선언하고 사용할 수 있다.
@layer <layer-name>  {
  ...
} 
/* 이름이 style인 layer 생성 */

@layer style {
  .text {
    color: red;
  }
}

See the Pen layer example_1 by KumJungMin (@kumjungmin) on CodePen.



2) @layer의 특징

(1) 레이어 순서를 미리 정의할 수 있다.

  • 레이어는 선언 순서에 따라 스타일이 적용되며, 늦게 선언될수록 높은 우선순위를 가진다.
  • 아래 코드에서는 layer_3 > layer_2 > layer_1 순으로 스타일 우선 순위를 가진다.
@layer layer_1 { ... }

@layer layer_2 { ... }

@layer layer_3 { ... }

See the Pen layer example_2 by KumJungMin (@kumjungmin) on CodePen.



  • 만약 레이어 순서를 미리 선언하고 싶다면 아래와 같이 순서를 미리 정의할 수 있다.
  • 레이어 우선순위는 layer_2 > layer_1 > layer_3이 된다.
@layer layer_3, layer_1, layer_2;  /* 레이어 순서 정의 */

@layer layer_1 { ... }
@layer layer_2 { ... }
@layer layer_3 { ... }

See the Pen layer example_3 by KumJungMin (@kumjungmin) on CodePen.



(2) 레이어 이름을 재사용할 수 있다.

  • 이미 선언한 레이어에 스타일을 추가하고 싶을 때, 레이어 이름을 통해 접근할 수 있다.
  • 이때, 레이어의 스타일을 수정한다고 하여 순서가 변하지는 않는다.
@layer layer_1 { ... }

@layer layer_2 { ... }

@layer layer_3 { ... }

/*  layer_1에 스타일 추가 */
@layer layer_1 {
  .text {
    font-style: italic;
  }
}

See the Pen layer example_4 by KumJungMin (@kumjungmin) on CodePen.



(3) import로 외부 스타일을 레이어로 만들 수 있다.

  • @import, url을 이용해 외부 스타일을 레이어로 선언할 수 있다.
/* basic.css의 스타일을 가지는 basic 레이어 */

@import url(basic.css) layer(basic);

(4) 이름 지정은 선택사항이다. (익명 레이어 가능)

  • 레이어의 이름 지정은 선택사항이다.
  • 이름이 지정되지 않은 레이어를 익명 레이어라고 부른다.
  • 익명 레이어의 경우, 식별가능한 이름이 없기에 레이어를 참조하여 스타일을 편집할 수 없다.
/* basic.css의 스타일을 가지는 익명 레이어 생성 */
@import url(basic.css) layer;

/* 익명 레이어 생성 */
@layer { ... }

(5) revert-layer 레이어 스타일을 되돌릴 수 있다.

  • 스타일 속성값에 revert-layer를 지정하면, 현재 레이어의 스타일 대신 이전 레이어의 스타일이 적용된다.
@layer base {
  p {
    color: red;
  }
}

@layer next {
  p {
    color: blue;
  }

  /* p태그에 text클래스가 지정되어 있으면, color가 이전 레이어(base)의 red로 적용됨 */
  .text {
    color: revert-layer;
  }
}

See the Pen layer example_9 by KumJungMin (@kumjungmin) on CodePen.



(6) 레이어를 중첩할 수 있다.

  • 레이어 내부에 중첩으로 레이어를 선언할 수 있다.
  • 중첩된 레이어에도 일반 레이어와 같은 우선순위 규칙을 따른다.
  • 아래의 경우 next ( second > first ) > base 순으로 우선순위를 가진다.
@layer base { ... }

@layer next { 
  @layer first { ... }
  @layer second { ... }
}

See the Pen layer example_5 by KumJungMin (@kumjungmin) on CodePen.


🤔 만약 중첩 레이어의 스타일을 수정하고 싶다면 어떻게 해야할까?

  • 온점(.)을 이용해 중첩 레이어에 접근할 수 있다!
@layer next { 
  @layer first { ... }
  @layer second { ... }
}

/* 중첩 레이어 second에 접근 */
@layer next.second { ... }

See the Pen layer example_5-1 by KumJungMin (@kumjungmin) on CodePen.



(7) @layer로 선언치 않은 스타일은 높은 우선순위를 가진다.

  • @layer로 선언치 않은 스타일은 Unlayered Styles라고 부른다.
  • Unlayered Styles는 가장 높은 우선순위를 가진다.
  • 아래 예시의 경우, Unlayered Styles가 가장 우선순위가 높기에 p태그의 color은 blue가 된다.
.text {
  color: blue;
}

@layer layer_1 {
  .text {
    color: red;
    font-weight: 700;
  }
}

See the Pen layer example_6 by KumJungMin (@kumjungmin) on CodePen.



(8) 레이어 스타일 우선순위에서 선택자 명시도는 무의미하다.

  • 레이어 간의 스타일 우선순위는 레이어 선언 순서를 따른다.
  • 일반적으로 명시도에 따라, id 선언 스타일이 class 선언 스타일보다 우선순위가 높지만,
  • 레이어의 경우 선택자 명시도를 따르지 않으므로 해당 규칙은 무의미하다.

See the Pen layer example_7 by KumJungMin (@kumjungmin) on CodePen.



  • 단, 속성에 !important를 지정하면 레이어 우선순위 규칙이 무시된다;
  • 이 경우 레이어 선언의 목적이 상실되므로 !important사용을 지양하자.

See the Pen layer example_8 by KumJungMin (@kumjungmin) on CodePen.




이번 시간에 우리는 @layer를 사용해 레이어 간의 스타일 우선순위를 정할 수 있었다. 또한, 레이어로 지정하지 않은 스타일의 경우 가장 높은 우선순위를 가진다는 점을 알게 되었다. 이러한 레이어 체계를 활용하고자 했을 때, reset.css나 base.css처럼 기본으로 적용해야할 스타일을 지정할 때 유용할 듯 하다.

반응형

댓글