LabHub
学习 学习路径 课程

CSS — 后写的规则获胜

用图层取胜

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

목표

@layer 를 쓴 스타일시트를 쓰고, 어느 선언이 이기는지를 계산기로 확인합니다. 브라우저가 없어도 이 답은 하나입니다.

왜 중요한가

정렬 순서에서 레이어는 특정성보다 먼저 갈립니다. 그래서 레이어를 쓰기 시작하면 "특정성이 높은데 왜 지지?" 라는 질문이 생기고, 그 답을 모르면 사람들은 다시 !important 로 돌아갑니다.

규칙은 두 줄입니다. 레이어에 넣지 않은 선언은 맨 마지막 레이어에 들어가고, 일반 선언은 뒤 레이어가 이기고 !important앞 레이어가 이깁니다. 이 두 줄이 합쳐지면 레이어 밖 일반 선언은 가장 세고, 레이어 밖 !important 는 가장 약해집니다.

만들 것

/root/work/layers/theme.css 하나와 예측 파일 둘입니다. HTML 은 필요 없습니다 — 채점기가 아래 요소들을 가정하고 캐스케이드를 풉니다.

div#app > article.card > h2.title
div#app > article.card > h2.title.u-hidden
div#app > article.card > a.btn.primary
div.toolbar > button.btn

계산기

cd /root/work/layers
python3 /opt/lab/checks/css-layer-lab/layercalc.py theme.css

선언마다 레이어 · 미디어 조건 · 특정성 · 순서를 보여 주고, 맨 위에 레이어 순서를 찍습니다. 다루지 못하는 선택자를 만나면 조용히 넘기지 않고 "해석할 수 없다" 고 말합니다.

단계

  1. @layer reset, base, components, utilities; 를 맨 위에
  2. 네 레이어를 채우고 뒤 레이어가 이기는 것을 확인
  3. 레이어 규칙이 특정성이 낮은데도 이긴다 → 03-predict.txt
  4. !important 는 순서를 뒤집는다 → 04-predict.txt
  5. :where() 로 특정성 0 인 기본값
  6. 유틸리티가 특정성 없이 컴포넌트를 이긴다
  7. 계산기 결과를 07-resolve.txt
  8. 레이어 밖 !important 를 없앤다
  9. 정리 → 09-notes.md

참고

레이어 순서를 못 박는다

/root/work/layers/theme.css 를 만들고 첫 규칙으로 @layer reset, base, components, utilities; 를 쓰세요. 그리고 각 레이어에 최소 한 규칙을 넣으세요.

mkdir -p /root/work/layers. 레이어 순서는 이름이 처음 나온 차례로 정해집니다. 블록 없는 선언형 규칙을 맨 위에 한 줄 두면, 그다음부터 어느 파일이 먼저 읽히든 순서가 고정됩니다.

뒤 레이어가 이긴다

basecomponents 두 레이어에 div#app > article.card > h2.title 에 걸리는 color 규칙을 각각 두고, components 가 이기게 하세요. 이 단계에서는 !important 를 쓰지 않습니다.

일반 선언은 뒤 레이어가 이깁니다. 특정성을 올릴 필요가 없습니다 — 레이어 단계가 특정성보다 먼저 갈리기 때문입니다. 계산기로 승자의 레이어 이름을 확인하세요.

레이어 밖이 가장 세다

@layer 블록 바깥에 제목 색 규칙을 한 줄 쓰세요. 그 선택자의 특정성은 components 규칙보다 낮아야 합니다. 그리고 /root/work/layers/03-predict.txt 에 이기는 곳과 이기는 값을 적으세요.

레이어에 넣지 않은 선언은 암묵적으로 맨 마지막 레이어에 들어갑니다. 특정성이 1,2,0 인 규칙을 0,1,0 이 이기는 것을 보게 됩니다 — 계산이 틀린 것이 아니라 볼 차례가 오지 않은 것입니다. 예측 파일에는 레이어 밖 이라는 말과 이기는 색 값이 들어가야 합니다.

important 는 순서를 뒤집는다

reset 레이어와 components 레이어에 div#app > article.card > a.btn.primary 에 걸리는 !important 색 규칙을 각각 두세요. reset 쪽 선택자의 특정성이 더 낮아야 합니다. 04-predict.txt 에 어느 레이어가 이기는지와 그 이유를 적으세요.

일반 선언은 뒤 레이어가 이기지만 !important 는 앞 레이어가 이깁니다. 명세는 이것이 important 가 출처 순서를 뒤집는 것과 같은 논리라고 설명합니다. 예측 파일에 resetimportant 가 들어가야 합니다.

특정성 0 인 기본값

base 레이어에 :where() 로 제목 굵기 기본값을 쓰고, 같은 레이어 안에 특정성이 있는 굵기 규칙을 하나 더 두세요. :where() 규칙이 파일에서 더 뒤에 있어야 합니다.

:where() 는 특정성이 언제나 0,0,0 입니다. 뒤에 썼는데도 앞의 태그 선택자에 지는 것을 보면 순서가 아니라 특정성으로 갈렸다는 것이 증명됩니다. 괄호 안에는 결합자 없이 하나만 넣으세요.

유틸리티가 특정성 없이 이긴다

utilities 레이어에 .u-hidden { display: none } 을 두고, components 레이어에는 같은 요소를 잡는 더 높은 특정성display 규칙을 두세요. !important 없이 유틸리티가 이겨야 합니다.

채점기는 div#app > article.card > h2.title.u-hidden 에서 무엇이 이기는지 계산합니다. 유틸리티 클래스에 !important 를 붙이던 관행은 레이어가 있으면 필요 없어집니다 — 유틸리티 레이어를 컴포넌트 뒤에 선언한 것으로 끝입니다.

계산기로 확인한다

layercalc.py 를 돌려 결과를 /root/work/layers/07-resolve.txt 로 남기세요. 저장된 줄 수가 지금 시트의 선언 수와 같아야 하고, 레이어 순서 줄이 그대로 들어 있어야 합니다.

python3 /opt/lab/checks/css-layer-lab/layercalc.py theme.css | tee 07-resolve.txt. 개발자 도구에서 취소선 그어진 규칙을 볼 때 머릿속에서 하는 계산이 이것입니다.

레이어 밖 important 를 없앤다

시트 전체에서 레이어 밖 !important 가 없어야 합니다. 그리고 components 레이어에 .toolbar > button.btn 의 색 규칙을 더해 툴바 단추 색이 components 에서 나오게 하세요. !important 는 모두 합쳐 네 개를 넘지 않아야 합니다.

레이어 밖 !important 는 모든 레이어의 !important집니다. 가장 세라고 쓴 것이 가장 약해지는 자리라, 레이어를 도입한 시트에서 가장 자주 나는 사고입니다. 지우거나 reset 으로 옮기세요.

왜 특정성이 볼 차례가 아닌가

/root/work/layers/09-notes.md 에 세 줄 이상(120자 이상) 적으세요. 본문에 레이어, 특정성, important 가 들어가야 합니다. 시트도 여전히 앞 단계 기준을 통과해야 합니다.

핵심은 하나입니다 — 정렬 순서에서 레이어가 특정성보다 앞에 있다. 앞에서 갈리면 뒤는 보지 않는다는 것이 캐스케이드 전체를 관통하는 규칙입니다.