기존 CSS에 캐스케이드 레이어를 도입하려면 먼저 기존 규칙을 어디에 둘지 결정하세요. 일반 비레이어 규칙은 모든 이름이 지정된 레이어보다 우선하므로, 서로 경쟁하는 기존 규칙을 더 낮은 우선순위의 레이어로 옮긴 뒤에야 새 레이어의 오버라이드가 적용됩니다.
이 가이드는 Mac에서 작성된 웹 페이지를 편집하고 데스크톱 브라우저에서 확인하는 사람을 위한 것입니다. 구체적인 작업은 이해하기 쉬운 마이그레이션 경로를 유지하면서 기존 스타일시트를 새 컴포넌트 스타일 아래에 배치하는 것입니다. 예제에서는 로컬 파일, 임의로 정한 이름, 단순한 CSS 구조를 사용합니다.
새 레이어 스타일이 기존 규칙에 밀리는 이유는 무엇인가요?
작성자 스타일시트에서 서로 경쟁하는 일반 선언의 경우, 비레이어 CSS가 명시적 레이어 안의 CSS보다 우선합니다. 선택자의 구체성이 더 높거나 레이어 안에서 더 뒤에 나온다고 해도 이 경계를 넘을 수 없습니다. CSS 사양에는 비레이어 규칙이 더 구체적인 레이어 규칙을 덮어쓰는 동작이 설명되어 있습니다. CSS Cascading and Inheritance Level 5.
클래스가 tile인 요소를 대상으로 하는 다음 CSS 조각을 살펴보세요:
.tile {
background-color: #b8bdc5;
}
@layer components {
.tile {
background-color: #246a73;
}
}
배경은 회색으로 유지됩니다. 레이어 이름을 overrides로 지정하거나, 해당 블록을 파일 아래쪽으로 옮기거나, 선택자의 구체성을 높여도 일반 비레이어 규칙의 우선순위는 바뀌지 않습니다. 레이어 이름에는 내재된 의미가 없습니다. 선언된 순서가 레이어 사이의 우선순위를 결정합니다. MDN: 캐스케이드 레이어.
다음 의사결정 표는 작성자 출처와 컨텍스트가 같은 스타일시트 선언끼리 경쟁하며, 인라인 스타일, 애니메이션 또는 전환이 해당 속성에 영향을 주지 않는다고 가정합니다. 각 행은 우선순위가 낮은 항목에서 높은 항목 순으로 읽으세요.
| 선언 유형 | 낮은 순위 → 높은 순위 |
|---|---|
| 일반 | 먼저 선언된 레이어 → 나중에 선언된 레이어 → 비레이어 규칙 |
!important |
비레이어 규칙 → 나중에 선언된 레이어 → 먼저 선언된 레이어 |
레이어 우선순위는 선택자 구체성보다 먼저 결정됩니다. 우선순위가 가장 높은 레이어 안에서는 구체성이 여전히 중요하며, 구체성이 같으면 소스 순서가 선언의 우선순위를 결정할 수 있습니다. 중요 선언에서는 우선순위가 반대로 바뀌므로 마이그레이션 시 일반 규칙과 중요 규칙을 따로 고려해야 합니다. MDN: 캐스케이드 레이어.
어떤 마이그레이션 경계를 선택해야 하나요?
새 CSS가 제어해야 할 요소 하나와 속성 하나부터 시작하세요. 현재 어떤 선언이 우선하는지 확인하고, 해당 선언이 있는 스타일시트를 찾은 다음, 그 파일을 수정할 수 있는지 또는 페이지에서 스타일시트를 불러오는 방식을 바꿀 수 있는지 결정하세요. 이렇게 하면 유용한 최소 마이그레이션 경계를 정할 수 있습니다.
| 현재 상황 | 실용적인 다음 단계 | 결과 |
|---|---|---|
| 기존 CSS의 우선순위를 유지해야 함 | 기존 CSS는 비레이어 상태로 두고 우선순위가 낮은 레이어 기본값을 추가 | 더 우선하는 규칙과 경쟁하지 않는 부분에 새 레이어의 값이 적용됨 |
| 기존 CSS를 수정할 수 있음 | 적용 가능한 기존 규칙을 @layer legacy 안에 넣기 |
이후 레이어에서 일반 기존 선언을 덮어쓸 수 있음 |
| 스타일시트 진입점을 변경할 수 있음 | 기존 파일을 layer(legacy)로 가져오기 |
선택자를 다시 작성하지 않고도 가져온 스타일시트가 해당 레이어에 포함됨 |
| 경쟁하는 기존 CSS나 로딩 방식을 변경할 수 없음 | 필요한 오버라이드는 임시로 비레이어 상태로 유지 | 구체성 및 기타 캐스케이드 요인을 계속 해결해야 함 |
이러한 선택지는 CSS에 문서화된 세 가지 레이어 메커니즘을 따릅니다. 선언문은 레이어 이름을 선언하고, 블록은 규칙을 레이어에 할당하며, 레이어가 지정된 import는 가져온 스타일시트를 레이어에 할당합니다. 선언문만으로는 기존 규칙이 이동하지 않습니다. CSS Cascading and Inheritance Level 5: 캐스케이드 레이어 선언.
작은 스타일시트라면 일반 규칙을 감싸는 방식이 편리할 수 있습니다. 기존 외부 파일에는 레이어 import를 사용하면 경계가 명확해집니다. 기존 @import 규칙을 @layer 블록 안에 넣지 마세요. import는 위치 제한이 있는 최상위 규칙입니다. MDN: @import.
아래에서 권장하는 마이그레이션은 기존 파일을 이름이 지정된 레이어로 가져옵니다. 이렇게 하면 다른 스타일시트와의 우선순위 관계가 바뀌므로, 샘플 페이지를 넘어 동일한 변경을 적용하기 전에 함께 로드되는 다른 CSS를 확인하세요.
Mac에서 완전한 로컬 예제를 만드는 방법은 무엇인가요?
일반 텍스트 파일 세 개를 포함하는 폴더를 만드세요. 코드 편집기를 사용하고 .html 및 .css 확장자를 그대로 유지하세요. 이 파일에는 패키지, 스크립트, 글꼴 또는 다운로드한 에셋이 필요하지 않습니다. 파일 이름은 로컬 예제용입니다.
다음 전체 문서를 sample.html으로 저장하세요:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Layer sample</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main id="sample">
<h1>Shape sample</h1>
<p>Tile A</p>
<div class="tile" aria-label="Sample shape"></div>
</main>
</body>
</html>
이 문서는 styles.css에만 연결합니다. HTML은 rel="stylesheet" 및 href을 사용해 외부 스타일시트를 페이지와 연결합니다. 현재 HTML 표준에는 link 요소의 layer 속성이 정의되어 있지 않습니다. CSS를 통해 리소스를 레이어에 할당하세요. HTML Standard: 링크 요소.
기존 규칙을 나타내는 다음 전체 스타일시트를 legacy.css로 저장하세요. 선택자는 그대로 유지합니다:
body {
margin: 2rem;
font-family: system-ui, sans-serif;
color: #26313a;
background-color: #f4f5f7;
}
#sample .tile {
width: 6rem;
height: 6rem;
background-color: #b8bdc5;
border-radius: 0;
}
다음 전체 진입 스타일시트를 styles.css으로 저장하세요:
@layer legacy, components;
@import url("legacy.css") layer(legacy);
@layer components {
.tile {
background-color: #246a73;
border-radius: 50%;
}
}
sample.html를 최신 데스크톱 Safari 또는 Firefox에서 여세요. 예상 결과는 Tile A 레이블 아래에 청록색 원이 표시되는 것입니다. legacy 레이어는 크기를 지정하고, 뒤에 오는 components 레이어는 배경과 둥근 모양을 지정합니다. 선언이 서로 다른 레이어에서 경쟁하므로 단일 클래스 선택자가 기존 ID 선택자보다 우선합니다. MDN: @layer.
진입 파일은 먼저 레이어 순서를 설정하고, 블록보다 앞에 import를 둔 다음, 컴포넌트 규칙을 추가합니다. 이는 문서화된 import 구문과 위치 규칙을 따릅니다. 레이어 선언문은 import 앞에 올 수 있지만, 레이어 블록은 그럴 수 없습니다. MDN: @import.
기존 페이지에서 무엇을 바꿔야 하나요?
이 구성으로 전환할 때는 페이지에서 직접 참조하는 스타일시트를 새 진입 스타일시트로 바꾸세요. 페이지가 legacy.css을 직접 불러오는 동시에 레이어로도 가져온다면, 직접 로드된 파일이 비레이어 선언을 제공해 마이그레이션을 무력화할 수 있습니다.
실패 상황을 예측해 보세요. legacy.css에 대한 직접 스타일시트 링크를 별도로 추가하면 일반 선언이 회색 정사각형을 되살릴 수 있습니다. 직접 로드를 제거하면 기존 규칙이 의도한 레이어 안에 남습니다. 이 예측은 일반 우선순위에서 명시적 레이어 다음에 비레이어 규칙이 배치된다는 사양에 근거합니다. CSS Cascading and Inheritance Module Level 5: 레이어 순서.
이 예제에서는 세 파일을 모두 같은 위치에 두세요. 이 방식을 실제 페이지에 적용할 때는 미디어 제한과 같은 기존 리소스 조건을 유지하고, 캐스케이드 충돌을 진단하기 전에 참조된 모든 스타일시트가 로드되는지 확인하세요.
macOS의 Firefox에서 마이그레이션을 확인하는 방법은 무엇인가요?
Command–Option–I를 눌러 Firefox 개발자 도구를 열고 Inspector를 선택하세요. 문서 트리에서 샘플 모양을 선택한 다음 Rules 뷰를 살펴보세요. Mozilla는 Mac용 도구 상자 단축키와 Inspector의 CSS 검사 기능을 문서화하고 있습니다. 모든 키보드 단축키, CSS 검사 및 편집.
샘플의 각 속성을 하나씩 확인하세요:
background-color을 찾으세요. 컴포넌트 선언이 기존의 회색 값보다 우선해야 합니다.border-radius을 찾으세요. 컴포넌트 값에 따라 원 모양이 표시되어야 합니다.width과height을 확인하세요. 해당 값은 기존 파일에서 계속 가져와야 합니다.- 컴포넌트의 배경 선언을 일시적으로 비활성화하세요. 모양은 둥근 상태를 유지하면서 기존의 회색이 표시되어야 합니다.
Firefox는 덮어써진 선언에 취소선을 표시하고, 선언을 일시적으로 비활성화하는 체크박스를 제공합니다. 또한 규칙을 소스 파일에 연결합니다. 예상하지 못한 결과를 모두 선택자 문제로 간주하지 말고, 해당 컨트롤을 사용해 경쟁하는 선언을 찾으세요. Mozilla: CSS 검사 및 편집.
실제 페이지에서는 변경한 상태를 각각 반복해서 확인하세요. 창 너비가 좁을 때, 관련 미디어 조건, 컴포넌트 변형을 확인해야 합니다. 지속적인 수정은 소스 파일에 저장하고 새로고침하세요. 일시적인 검사 변경은 진단에 유용합니다.
마이그레이션 중 예상치 못하게 바뀔 수 있는 것은 무엇인가요?
중요 선언은 의도한 순서를 뒤집습니다
@layer legacy, components일 때 legacy의 중요 선언은 components의 경쟁하는 중요 선언보다 우선합니다. 따라서 중요한 기존 규칙을 초기 레이어로 옮기면 오히려 덮어쓰기가 더 어려워질 수 있습니다. 같은 작성자 출처와 컨텍스트에서는 모든 중요 레이어 스타일시트 선언이 경쟁하는 중요 비레이어 스타일시트 선언보다 우선합니다. MDN: @layer.
파일을 옮기기 전에 !important를 검색하고 관련된 각 충돌을 살펴보세요. 두 선언을 모두 제어할 수 있다면 레이어를 도입한 뒤에도 중요도가 필요한지 판단하세요. 새 컴포넌트 규칙마다 중요도를 추가하지 마세요. 그렇게 하면 사용하는 우선순위 체계가 달라집니다.
인라인 스타일은 별도로 살펴봐야 합니다. 일반 인라인 스타일은 일반 작성자 스타일시트 규칙보다 우선하고, 중요 인라인 스타일은 다른 중요 작성자 선언보다 우선합니다. 스타일시트를 레이어로 옮겨도 요소의 style 속성은 이동하지 않습니다. MDN: CSS 캐스케이드 소개.
나중에 나온 선언문으로 기존 레이어의 순서를 바꿀 수 없습니다
레이어의 순서는 처음 선언될 때 정해집니다. 이름이 지정된 레이어를 다시 열어 규칙을 추가해도 순서는 바뀌지 않습니다. 가져온 스타일시트를 통해 레이어가 생성되는 경우까지 포함해, 페이지에서 해당 레이어가 처음 생성되기 전에 의도한 순서를 지정하세요. CSS Cascading and Inheritance Module Level 5.
점진적으로 마이그레이션할 때는 초기 순서를 짧고 명확하게 유지하세요. 서로 연관된 규칙을 옮기고, 어떤 선언이 우선하는지 확인한 뒤 다음 규칙을 옮기세요. 경쟁하는 비레이어 규칙을 남겨둔 채 규칙 하나만 옮기면 없애려던 우선순위 경계가 그대로 유지되는 경우가 많습니다.
Mac에서 브라우저 지원과 관련해 고려할 점은 무엇인가요?
MDN은 @layer를 2022년 3월부터 브라우저 전반에서 널리 사용할 수 있는 기능으로 표시합니다. WebKit은 Safari 15.4에서 캐스케이드 레이어를 지원한다고 문서화하고 있습니다. 이 날짜는 기능을 사용할 수 있게 된 시점을 설명할 뿐, 모든 Mac에 지원 브라우저가 설치되어 있음을 뜻하지는 않습니다. 페이지에서 실제로 지원해야 하는 버전을 확인하세요. MDN: @layer, WebKit: Safari 15.4의 새로운 WebKit 기능.
레이어 블록을 이해하지 못하는 브라우저는 그 안에 있는 스타일을 일반 비레이어 규칙으로 적용하지 않습니다. CSS 구문 분석 규칙에 따라 지원되지 않는 구문은 버려집니다. 따라서 필수 CSS를 모두 레이어로 감싸는 방식은 구형 브라우저를 위한 대체 방안이 아닙니다. MDN: CSS 오류 처리.
해당 브라우저도 계속 지원해야 한다면, 그 지원 경로에 사용할 비레이어 스타일시트를 별도로 유지하고 선택자와 소스 순서로 충돌을 해결하세요. 레이어를 지원하는 브라우저에서 레이어 버전과 함께 비레이어 중복 파일을 불러오지 마세요. 방금 설계한 캐스케이드가 달라집니다.
새 컴포넌트가 의도한 속성을 제어하도록 하는 최소 마이그레이션부터 시작하세요. 레이어 순서를 정하고, 경쟁하는 기존 규칙을 레이어에 할당하고, 비레이어 중복 로드를 제거한 다음, 어떤 선언이 적용되는지 확인하세요. 이렇게 하면 더 많은 CSS를 마이그레이션하기 전에 각 우선순위 변경을 확인할 수 있습니다.
출처
- CSS Cascading and Inheritance Level 5 — W3C.
- CSS Cascading and Inheritance Module Level 5 — CSS Working Group.
- HTML Standard — WHATWG.
@layerCSS at-rule — MDN Web Docs.@importCSS at-rule — MDN Web Docs.- 캐스케이드 레이어 — MDN Web Docs.
- CSS 캐스케이드 소개 — MDN Web Docs.
- CSS 오류 처리 — MDN Web Docs.
- 모든 키보드 단축키 — Mozilla.
- CSS 검사 및 편집 — Mozilla.
- Safari 15.4의 새로운 WebKit 기능 — WebKit.