CSS 환경 변수 모듈 레벨 1

W3C 최초 공개 워킹 드래프트,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2025/WD-css-env-1-20250923/
최신 공개 버전:
https://www.w3.org/TR/css-env-1/
에디터 초안:
https://drafts.csswg.org/css-env-1/
히스토리:
https://www.w3.org/standards/history/css-env-1/
피드백:
CSSWG 이슈 저장소
명세 내 인라인
에디터:
Tab Atkins-Bittner (Google)
이전 에디터:
Dean Jackson (Apple)
이 명세에 대한 수정 제안:
GitHub 에디터

요약

이 명세서는 환경 변수env() 함수의 개념을 정의합니다. 이들은 사용자 정의 속성과 var() 함수와 유사하게 동작하지만, 문서 전체에 전역적으로 정의됩니다. 환경 변수는 사용자 에이전트에 의해 정의되어 UA가 특별히 접근 가능한 정보를 기반으로 페이지에서 사용할 수 있는 값을 제공하거나, 저자가 "전역" 변수로 제공하여 문서 어디에서 사용해도 동일한 값이 보장됩니다.

CSS는 구조화된 문서(예: HTML, XML)의 렌더링을 화면, 인쇄물 등 다양한 매체에서 기술하기 위한 언어입니다.

이 문서의 상태

이 섹션은 이 문서가 출판될 당시의 상태를 설명합니다. 최신 W3C 출판물 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.

이 문서는 CSS 워킹 그룹에 의해 최초 공개 워킹 드래프트권고안 경로를 사용하여 출판되었습니다. 최초 공개 워킹 드래프트로서의 출판은 W3C 및 그 회원사의 승인(endorsement)을 의미하지 않습니다.

이 문서는 초안 상태이며 언제든지 수정, 대체 또는 폐기될 수 있습니다. 진행 중인 작업 외의 용도로 이 문서를 인용하는 것은 부적절합니다.

피드백은 GitHub 이슈 등록(권장) 방식으로 보내주시고, 제목에 명세 코드 “css-env”를 포함해주세요. 예: “[css-env] …코멘트 요약…”. 모든 이슈와 코멘트는 아카이브됩니다. 또는 (아카이브됨) 공개 메일링 리스트 www-style@w3.org로도 피드백을 보낼 수 있습니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서에 의해 관리됩니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 그룹 산출물과 관련하여 이루어진 특허 공개의 공개 목록을 유지하며; 해당 페이지에는 특허 공개 방법에 대한 안내도 포함되어 있습니다. 어떤 개인이 실질적으로 특허를 알고 있고, 그 특허가 필수적 청구(Essential Claim)을 포함한다고 믿는 경우, W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.

1. 소개

[css-variables-1] 명세는 "계단식 변수(cascading variables)"의 개념을 정의하였습니다. 이는 사용자 정의 속성(custom properties)의 값을 기반으로 작성자가 정의한 변수로, var() 함수를 통해 임의의 다른 속성에 치환될 수 있습니다.

이 명세서는 이와 연관되지만 더 단순한 환경 변수의 개념을 정의합니다. "계단식 변수"는 해당 사용자 정의 속성이 여러 값으로 바뀌면서 페이지 전체에서 값이 변할 수 있지만, 환경 변수는 특정 문서 전체에 "전역적"으로 적용되며 값이 어디서나 동일합니다. env() 함수를 사용하여 이 값을 임의의 위치에 치환할 수 있으며, var() 함수와 유사하게 동작합니다.

이러한 "전역" 변수는 계단식 변수에 비해 장점과 단점을 모두 가지고 있습니다:

대부분의 환경 변수는 한 번에 하나의 값만 가집니다. 하지만 일부는 "인덱스"를 가지며, 여러 값을 동시에 나타냅니다. 예를 들어 viewport-segment-* 변수는 여러 개의 고유한 콘텐츠 패널의 크기와 위치를 나타냅니다. 이러한 인덱스가 필요한 변수에 접근하려면 변수명과 함께 하나 이상의 정수값을 제공해야 하며, 예를 들어 viewport-segment-width 1 0처럼 사용하여 가능성 목록이나 그리드에서 하나의 값을 선택합니다. 이는 전통적인 프로그래밍 언어에서 values[0]와 같이 리스트에서 하나의 요소를 선택하는 방식과 유사합니다.

2. 환경 변수

CSS 환경 변수<declaration-value> (0개 이상의 CSS 토큰 시퀀스로, 어떤 토큰이든 거의 제한 없이 올 수 있음)과 연관된 이름입니다. 이는 사용자 정의 속성과 유사합니다. 환경 변수는 사용자 에이전트 또는 사용자가 정의할 수 있습니다. (후자의 경우, 이름은 <custom-property-name>이며, 사용자 정의 식별자 표준에 따라 `--`로 시작합니다.)

UA가 정의한 환경 변수의 집합이 스크립트에서 보이나요? 그렇다면, Document 에 해당 변수를 노출하는 API를 정의하세요.

저자가 환경 변수를 추가할 수 있는 방법을 정의하세요. JS와 CSS 모두를 통해 정의할 수 있으면 좋습니다. CSS 규칙과 JS로 정의한 값이 혼합될 경우 쉽게 복잡해질 수 있으니 주의하세요. (CSSFontFaceRule과 FontFace의 사례 참고)

아래의 UA 정의 환경 변수는 공식적으로 정의되어 있으며 반드시 지원되어야 합니다. 추가적으로 UA에서 정의한 환경 변수는 이 목록에 추가되기 전까지 지원해서는 안 됩니다.

2.1. 세이프 영역 인셋 변수

이름 차원 수
safe-area-inset-top <length> 0 (스칼라)
safe-area-inset-right <length> 0 (스칼라)
safe-area-inset-bottom <length> 0 (스칼라)
safe-area-inset-left <length> 0 (스칼라)

세이프 영역 인셋은 네 개의 환경 변수로, 뷰포트의 상단, 우측, 하단, 좌측 인셋을 통해 사각형을 정의합니다. 직사각형 디스플레이에서는 모두 0이어야 하지만, 비직사각형 디스플레이에서는 사용자 에이전트가 선택한 사각형을 형성해야 하며, 사각형 내부의 모든 콘텐츠가 보이도록 하고, 인셋 중 하나라도 줄어들면 비직사각형 디스플레이의 특성상 내부 콘텐츠 일부가 보이지 않아야 합니다. 이를 통해 작성자는 중요한 콘텐츠의 레이아웃을 세이프 영역 내부에 제한할 수 있습니다.

2.2. 세이프 영역 최대 인셋 변수

이름 차원 수
safe-area-max-inset-top <length> 0 (스칼라)
safe-area-max-inset-right <length> 0 (스칼라)
safe-area-max-inset-bottom <length> 0 (스칼라)
safe-area-max-inset-left <length> 0 (스칼라)

세이프 영역 최대 인셋은 네 개의 환경 변수로, 세이프 영역 인셋 변수와 연동되어 있습니다. 세이프 영역 인셋 변수가 동적인 값인 것과 달리, 세이프 영역 최대 인셋은 동적 값의 최대값을 나타내는 정적 값입니다. 동적 UA 인터페이스가 숨겨질 때의 최대값을 의미하며, 레이아웃 뷰포트 크기가 큰 뷰포트 크기가 됩니다.

2.3. 뷰포트 세그먼트 변수

이름 차원 수
viewport-segment-width <length> 2
viewport-segment-height <length> 2
viewport-segment-top <length> 2
viewport-segment-left <length> 2
viewport-segment-bottom <length> 2
viewport-segment-right <length> 2

뷰포트 세그먼트는 환경 변수로, 뷰포트의 논리적으로 분리된 영역의 위치와 크기를 정의합니다. 뷰포트가 하나 이상의 하드웨어 특성(예: 폴드나 분리된 디스플레이 사이의 힌지)으로 분할될 때 세그먼트가 생성되며, 세그먼트는 작성자가 논리적으로 구분할 수 있는 뷰포트의 영역입니다.

뷰포트 세그먼트 환경 변수는 두 개의 차원을 가지며, 이는 하드웨어 특성으로 분리된 2차원 그리드에서 각각 x, y 위치를 나타냅니다. 왼쪽 가장자리의 세그먼트는 x 위치가 0이고, 오른쪽으로 한 칸 이동할 때마다 x 위치가 1씩 증가합니다. 마찬가지로, 위쪽 가장자리의 세그먼트는 y 위치가 0입니다.

참고: 특정 하드웨어 구성에서는 구분선 자체가 뷰포트 내 논리적 공간을 차지할 수 있습니다. 구분선의 크기는 뷰포트 세그먼트의 위치를 이용해 계산할 수 있습니다.

뷰포트가 좌우 두 개의 세그먼트로 나뉘는 경우, 왼쪽 세그먼트의 인덱스는 (0, 0)입니다. 그 너비는 env(viewport-segment-width 0 0, 300px)으로 나타낼 수 있습니다. 오른쪽 세그먼트의 인덱스는 (1, 0)입니다. 마찬가지로, 뷰포트가 상하 두 세그먼트로 나뉘는 경우, 위쪽 세그먼트의 인덱스는 (0, 0), 아래쪽은 (0, 1)입니다.

이 변수들은 두 개 이상의 세그먼트가 있을 때만 정의됩니다. 뷰포트를 분할하는 하드웨어 특성이 없을 때는 뷰포트 단위를 사용하는 것이 좋으며, 그렇지 않으면 다중 세그먼트 디바이스에서 콘텐츠가 의도대로 표시되지 않을 수 있습니다.

2.4. 선호 텍스트 확대

이름 차원 수
preferred-text-scale <number> 0 (스칼라)

preferred-text-scale 환경 변수는 사용자의 선호 텍스트 배율을 나타냅니다. 즉, 운영체제 및/또는 사용자 에이전트의 "기본" 글꼴 크기에 대해 사용자가 조정한 값을 의미합니다. (text-size-adjust가 적용되는 디바이스에서는, text-size-adjust: auto에 의해 적용되는 배율입니다.)

예를 들어, text-size-adjust:auto가 텍스트 크기를 두 배로 만든다면, env(preferred-text-scale) 값은 2가 됩니다.

참고: pem 단위는 동일한 정보를 나타냅니다. 1emcalc(1em * env(preferred-text-scale))과 정확히 같습니다. 직접 크기를 지정할 때는 bsem이 더 편리한 길이 단위가 됩니다.

환경 변수는 올바르게 사용하기 위해 주의가 필요합니다. 기본적으로 텍스트 확대는 자동으로 적용됩니다. env(preferred-text-scale) 또는 pem을 사용하면 배율이 이중 적용되어, 텍스트나 UI 요소가 너무 커질 수 있습니다.

일반적으로 작성자는 다음 중 하나를 선택해야 합니다:

3. 환경 변수 사용: env() 표기법

환경 변수의 값을 CSS 컨텍스트에 치환하려면, env() 함수를 사용하세요:

env() = env( <custom-ident> <integer [0,∞]>*, <declaration-value>? )

env() 함수는 어떤 요소의 어떤 속성 값의 일부, 또는 어떤 at-rule의 어떤 디스크립터 값 일부 등, CSS 값이 허용되는 여러 위치에서 사용할 수 있습니다.

env()를 사용할 수 있는 전체 위치를 정의하세요.

env() 함수의 첫 번째 인자는 치환할 환경 변수의 이름을 지정합니다. 이어지는 인자들은, 이름이 배열 형태의 환경 변수인 경우, 해당 변수의 차원에 대한 인덱스를 나타내는 정수입니다. 쉼표 뒤에 오는 인자(있다면)는 대체 값(fallback)으로, 참조된 환경 변수가 존재하지 않을 때 사용됩니다.

참고: 사용자 정의 속성과 마찬가지로 fallback의 구문은 쉼표를 허용합니다. 예를 들어, env(foo, red, blue)red, blue를 대체 값으로 정의합니다. 즉, 첫 번째 쉼표부터 함수 끝까지가 모두 fallback 값으로 간주됩니다.

속성에 하나 이상의 env() 함수가 포함되어 있고, 그 함수들이 구문적으로 유효하다면, 전체 속성 문법은 파싱 시점에 유효한 것으로 간주해야 합니다. 실제 구문 검사는 env() 함수가 치환된 이후 계산 시점에만 수행됩니다.

디스크립터에 하나 이상의 env() 함수가 포함되어 있고, 그 함수들이 구문적으로 유효하다면, 전체 선언 문법은 파싱 시점에 유효한 것으로 간주해야 합니다. 실제 구문 검사는 env() 함수가 치환된 이후에만 수행됩니다.

속성 또는 디스크립터에서 env()를 치환하려면:
  1. env() 함수의 첫 번째 인자로 제공된 이름이 인식 가능한 환경 변수 이름이고, 제공된 정수 개수가 그 변수의 차원 수와 일치하며, 인덱스 값이 유효한 하위 값을 가리키면, 해당 이름의 env() 함수를 지정한 환경 변수의 값으로 대체합니다.

  2. 그렇지 않고 env() 함수에 두 번째 인자로 fallback 값이 있다면, env() 함수를 fallback 값으로 대체합니다. fallback에 env() 참조가 있으면, 그것도 치환합니다.

  3. 그 외의 경우, env() 함수가 포함된 속성 또는 디스크립터는 computed-value 시점에 유효하지 않음이 됩니다.

치환이 언제 발생하는지 정의하세요. var() 치환보다 먼저여야 합니다. 또는 env() 치환이 파싱 시점에 일어나서, 알 수 없는 변수명은 구문 검사 실패가 되도록 해야 할까요? var()처럼 computed-value 시점에 일어날 이유는 없습니다. 그 방식은 사용자 정의 속성이 값을 상속한 뒤 var()로 참조되도록 하기 위함이었습니다.

env()가 사용될 수 있는 다른 위치를 파악하면, 어떻게/언제 치환되는지 정의하세요.

3.1. 축약 속성에서의 환경 변수

env() 치환이 파싱 중에 발생한다면, 이 절은 불필요합니다.

env() 함수는 축약 속성에서 var() 함수와 동일한 문제를 야기할 수 있습니다. env()축약 속성에서 사용되면, CSS Variables 1 § 3.2 Variables in Shorthand Properties에 정의된 동일한 효과를 가집니다.

4. 개인정보 보호 고려사항

이 명세서에서 정의하는 환경 변수들은 잠재적으로 개인정보에 민감할 수 있습니다. 이는 페이지에 기존에 없던 추가 정보를 제공할 수 있기 때문입니다. 특히, 사용자가 페이지를 보는 기기에 대한 추가 정보를 노출하여 핑거프린팅 벡터가 될 수 있습니다.

지금까지 이 명세서에서 정의된 환경 변수들은 CSSWG의 검토를 거쳐 노출이 허용된 것으로 간주됩니다.

5. 보안 고려사항

이 명세서는 디바이스에 대한 새로운 유형의 정보를 읽기 전용으로 제공합니다.

이 명세서에서 정의하는 환경 변수는 보안에 민감한 정보를 노출하지 않습니다.

준수

문서 관례

준수 요건은 설명적 진술과 RFC 2119 용어의 조합으로 표현됩니다. 주요 단어인 “MUST”(필수), “MUST NOT”(금지), “REQUIRED”(요구), “SHALL”(해야 한다), “SHALL NOT”(해서는 안 된다), “SHOULD”(권장), “SHOULD NOT”(비권장), “RECOMMENDED”(권장됨), “MAY”(허용), “OPTIONAL”(선택 사항)은 이 문서의 규범적 부분에서 RFC 2119에 명시된 대로 해석되어야 합니다. 다만, 가독성을 위해 이 단어들은 대문자로 표기되지 않습니다.

이 명세서의 모든 텍스트는 명시적으로 비규범적임, 예시, 참고로 표시된 섹션을 제외하면 규범적입니다. [RFC2119]

이 명세서의 예시는 “예를 들어(for example)”라는 문장으로 시작하거나, class="example"와 같이 규범적 텍스트와 구분되어 제시됩니다:

이것은 정보 제공용 예시입니다.

정보성 참고는 “참고(Note)”라는 단어로 시작하며, class="note"로 규범적 텍스트와 구분되어 제시됩니다:

참고, 이것은 정보 제공용 참고입니다.

권고 사항은 특별한 주의를 환기하도록 스타일링된 규범적 섹션이며, <strong class="advisement">로 구분되어 제시됩니다: UA는 접근 가능한 대체 수단을 반드시 제공해야 합니다.

준수 클래스

이 명세에 대한 준수는 세 가지 준수 클래스로 정의됩니다:

스타일 시트
CSS 스타일 시트.
렌더러
UA로, 스타일 시트의 의미를 해석하고 해당 스타일 시트를 사용하는 문서를 렌더링합니다.
작성 도구
UA로, 스타일 시트를 생성합니다.

스타일 시트가 이 명세를 준수하려면, 이 모듈에서 정의된 문법을 사용하는 모든 문이 일반 CSS 문법 및 각 기능별 문법에 따라 유효해야 합니다.

렌더러가 이 명세를 준수하려면, 적절한 명세에 정의된 대로 스타일 시트를 해석하는 것 이외에, 이 명세서에 정의된 모든 기능을 올바르게 파싱 및 지원하여 문서를 적절히 렌더링해야 합니다. 단, 디바이스의 한계로 인해 UA가 문서를 올바로 렌더링하지 못해도 비준수로 간주하지 않습니다. (예: 색상을 표시하지 못하는 흑백 모니터에서 색상 렌더링을 요구하지 않음)

작성 도구가 이 명세를 준수하려면, 이 모듈의 일반 CSS 문법 및 각 기능별 문법에 따라 구문적으로 올바른 스타일 시트를 작성해야 하며, 이 모듈에 설명된 스타일 시트의 모든 기타 준수 요건도 충족해야 합니다.

부분 구현

작성자가 하위 호환 파싱 규칙을 활용해 대체 값을 지정할 수 있도록, CSS 렌더러는 지원하지 않는 at-rule, 속성, 속성 값, 키워드 및 기타 구문 구조를 유효하지 않은 것으로 간주하고 (적절히 무시)해야 합니다. 특히, 사용자 에이전트는 지원하지 않는 구성 값만 무시하고 지원되는 값만 채택해서는 안 됩니다: 하나의 선언에서 어떤 값이라도 유효하지 않으면(즉, 지원되지 않는 값이면), CSS는 전체 선언을 무시해야 합니다.

불안정 및 독점 기능의 구현

향후 안정화된 CSS 기능과의 충돌을 피하기 위해, CSSWG는 미래 호환성 확보를 위한 모범 사례를 따르며 불안정 기능 및 독점 확장 구현을 권장합니다.

비실험적 구현

명세가 후보 권고(CR) 단계에 도달하면, 비실험적 구현이 가능하며, 구현자는 명세를 올바르게 구현했음을 입증할 수 있는 모든 CR 수준 기능에 대해 접두사 없는 구현(unprefixed implementation)을 공개해야 합니다.

CSS의 상호 운용성을 확립하고 유지하기 위해, CSS 워킹 그룹은 비실험적 CSS 렌더러가 어떤 CSS 기능의 접두사 없는 구현을 공개하기 전에 W3C에 구현 보고서(및 필요한 경우, 해당 구현 보고서에 사용한 테스트케이스)를 제출할 것을 요청합니다. 제출된 테스트케이스는 CSS 워킹 그룹이 검토 및 수정할 수 있습니다.

테스트케이스 및 구현 보고서 제출에 대한 추가 정보는 CSS 워킹 그룹 웹사이트 https://www.w3.org/Style/CSS/Test/에서 확인할 수 있습니다. 문의는 public-css-testsuite@w3.org 메일링 리스트로 하세요.

색인

이 명세서에서 정의한 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022년 1월 13일. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-CONDITIONAL-3]
Chris Lilley; David Baron; Elika Etemad. CSS Conditional Rules Module Level 3. 2024년 8월 15일. CRD. URL: https://www.w3.org/TR/css-conditional-3/
[CSS-SIZE-ADJUST-1]
CSS Mobile Text Size Adjustment Module Level 1. 에디터 초안. URL: https://drafts.csswg.org/css-size-adjust-1/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS Syntax Module Level 3. 2021년 12월 24일. CRD. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2024년 3월 12일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VARIABLES-1]
Tab Atkins Jr.. CSS Custom Properties for Cascading Variables Module Level 1. 2022년 6월 16일. CR. URL: https://www.w3.org/TR/css-variables-1/
[CSSOM-VIEW-1]
Simon Fraser; Emilio Cobos Álvarez. CSSOM View Module. 2025년 9월 16일. WD. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119

이슈 색인

UA가 정의한 환경 변수 집합이 스크립트에서 보이나요? 그렇다면, Document에 해당 변수를 노출하는 API를 정의하세요.
저자가 환경 변수를 추가할 수 있는 방법을 정의하세요. JS와 CSS 모두를 통해 정의할 수 있으면 좋습니다. CSS 규칙과 JS로 정의한 값이 혼합될 경우 쉽게 복잡해질 수 있으니 주의하세요. (CSSFontFaceRule과 FontFace의 사례 참고)
env()를 사용할 수 있는 전체 위치를 정의하세요.
치환이 언제 발생하는지 정의하세요. var() 치환보다 먼저여야 합니다. 또는 env() 치환이 파싱 시점에 일어나서, 알 수 없는 변수명은 구문 검사 실패가 되도록 해야 할까요? var()처럼 computed-value 시점에 일어날 이유는 없습니다. 그 방식은 사용자 정의 속성이 값을 상속한 뒤 var()로 참조되도록 하기 위함이었습니다.
env()가 사용될 수 있는 다른 위치를 파악하면, 어떻게/언제 치환되는지 정의하세요.
env() 치환이 파싱 중에 발생한다면, 이 절은 불필요합니다.