1. 소개
이 섹션은 규범적이지 않습니다.
1997년, HTML4 [HTML401]는 다양한 미디어 타입에 맞게 미디어 의존 스타일 시트를 지원하는 메커니즘을 정의했습니다. 예를 들어, 문서는 화면과 인쇄용으로 각각 다른 스타일 시트를 사용할 수 있습니다. HTML에서는 다음과 같이 작성할 수 있습니다:
<link rel="stylesheet" type="text/css" media="screen" href="style.css"> <link rel="stylesheet" type="text/css" media="print" href="print.css">
CSS는 @media 및 @import 규칙으로 이 기능을 확장하고, 개별 기능의 값을 질의할 수 있도록 추가했습니다:
@media screen { * { font-family: sans-serif } }
이와 유사하게, 스타일 시트는 미디어쿼리에 따라 조건부로 import할 수 있습니다:
@import "print-styles.css" print;
미디어쿼리는 HTML, XHTML, XML [xml-stylesheet]와 CSS의 @import, @media 규칙에서 사용할 수 있습니다.
<link media="screen and (color), projection and (color)" rel="stylesheet" href="example.css"> <link media="screen and (color), projection and (color)" rel="stylesheet" href="example.css" /> <?xml-stylesheet media="screen and (color), projection and (color)" rel="stylesheet" href="example.css" ?> @import url(example.css) screen and (color), projection and (color); @media screen and (color), projection and (color) { … }
1.1. 모듈 상호작용
이 모듈은 [MEDIAQUERIES-4] 및 그 이전 [MEDIAQUERIES-3]을 확장하고 대체합니다. 이들 자체도 CSS 2 § 7 미디어 타입을 기반으로 구축되고 대체했습니다.
1.2. 값
이 명세에서 정의되지 않은 값 타입(예: <integer>, <number>, <resolution>)은 [CSS-VALUES-4]에 정의되어 있습니다. 다른 CSS 모듈에서 이러한 값 타입의 정의를 확장할 수 있습니다.
1.3. 단위
미디어쿼리에서 사용하는 단위는 [CSS-VALUES-4]에서 정의된 것처럼 CSS의 다른 부분과 동일합니다. 예를 들어, 픽셀 단위는 CSS 픽셀이며 물리적 픽셀이 아닙니다.
상대 길이 단위는 초기값을 기준으로 하며, 선언 결과가 아닌 초기값에 기반함을 의미합니다.
참고: 예를 들어, HTML에서 em 단위는 font-size의 초기값을 기준으로 하며, 이는 사용자 에이전트 또는 사용자의 환경설정에 의해 정의되고 페이지의 스타일링에는 영향을 받지 않습니다. 또한 사용자가 적용한 추가 제한(최소 글꼴 크기 등)도 반영됩니다.
1.4. Prefers-* 미디어 기능의 보안 및 프라이버시
이 명세를 구현하는 사용자 에이전트 및 개발자는 이러한 벡터를 인지하고 해당 기능 사용 여부를 결정할 때 이를 고려해야 합니다. 특히 `prefers-reduced-motion`, `prefers-color-scheme`, `prefers-reduced-data`는 현 시점에서 악용 우려가 있습니다.
2. 미디어 쿼리
미디어쿼리는 문서가 표시되는 사용자 에이전트나 장치의 특정 측면을 테스트하는 방법입니다. 미디어쿼리는 거의 항상 문서의 내용, 스타일, 기타 내부 요소와는 독립적이며, 명시적으로 미디어쿼리의 판정에 영향을 준다고 정의된 기능 외에는 “외부” 정보에만 의존합니다.
미디어쿼리의 구문은 선택적 미디어쿼리 한정자, 선택적 미디어 타입, 0개 이상의 미디어 기능으로 구성됩니다:
미디어쿼리는 true 또는 false인 논리식입니다. 미디어쿼리는 아래 조건일 때 true입니다:
이 섹션에서의 미디어쿼리 관련 설명은 구문 섹션을 따르는 것으로 간주합니다. 문법에 맞지 않는 미디어쿼리는 § 3.2 오류 처리에서 다룹니다. 즉, 문법이 본 섹션의 요구사항보다 우선합니다.
<link rel="stylesheet" media="screen and (color)" href="example.css" />
이 예시는 특정 스타일 시트(example.css
)가
특정 미디어 타입(screen)의
특정 기능(컬러 화면이어야 함)을 가진 장치에 적용됨을 의미합니다.
동일한 미디어쿼리를 CSS의 @import 규칙으로 작성하면 아래와 같습니다:
@import url(example.css) screen and (color);
사용자 에이전트는 인지하는 사용자 환경 변화(예: 장치가 가로에서 세로 방향으로 전환 등)에 따라 미디어쿼리를 재평가해야 하며, 해당 미디어쿼리에 의존하는 구문의 동작도 그에 맞게 변경해야 합니다.
다른 기능이 명시적으로 미디어쿼리의 판정에 영향을 준다고 정의하지 않는 한, 표현식을 평가하기 위해 스타일 시트를 적용할 필요는 없습니다.
2.1. 미디어쿼리 조합
여러 개의 미디어쿼리를 콤마로 구분하여 미디어쿼리 리스트로 결합할 수 있습니다.
미디어쿼리 리스트는 구성하는 어떤 미디어쿼리가 true이면 true이고, 모든 구성 미디어쿼리가 false일 때만 false입니다.
@media screen and (color), projection and (color) { … }
빈 미디어쿼리 리스트는 true로 평가됩니다.
2.2. 미디어쿼리 한정자
미디어쿼리는 선택적으로 한 개의 미디어쿼리 한정자를 앞에 붙일 수 있으며, 이는 다음 미디어쿼리의 의미를 변경하는 단일 키워드입니다.
2.2.1. 미디어쿼리 부정: not 키워드
개별 미디어쿼리에 not 키워드를 앞에 붙이면 결과를 반전시킬 수 있습니다. 미디어쿼리가 원래 true로 평가되는 경우, not을 붙이면 false가 되고, 그 반대도 마찬가지입니다.
<link rel="stylesheet" media="not screen and (color)" href="example.css" />
2.2.2. 레거시 사용자 에이전트에서 미디어쿼리 숨기기: only 키워드
미디어쿼리의 개념은 HTML4 [HTML401]에서 시작되었습니다. 해당 명세는 미디어 타입만 정의했지만, 향후 미디어 기능 같은 개념이 추가될 수 있도록 호환성 있는 구문을 채택했습니다: 미디어쿼리의 첫 번째 비알파벳 문자가 나올 때까지 문자를 소비해서 미디어쿼리를 미디어 타입으로 해석하고 나머지는 무시합니다. 예를 들어 media query screen and (color)은 screen만 남게 됩니다.
이로 인해 레거시 사용자 에이전트는 이 오류 처리 방식대로 동작할 경우, 미디어쿼리의 미디어 기능을 무시하게 되며, 이는 미디어 타입보다 더 중요한 경우에도 마찬가지입니다. 그 결과, 스타일이 부적절한 상황에 적용될 수 있습니다.
이러한 미디어쿼리를 레거시 사용자 에이전트에서 숨기려면, 미디어쿼리 앞에 only 키워드를 붙이면 됩니다. only 키워드는 결과에 영향을 주지 않지만, 레거시 사용자 에이전트는 미디어쿼리를 알 수 없는 미디어 타입 “only”로 해석하여 무시하게 됩니다.
<link>
요소로 지정한 스타일 시트는
레거시 사용자 에이전트에서 사용되지 않습니다.
원래는 screen 미디어 타입에 일치해도 말이죠.
<link rel="stylesheet" media="only screen and (color)" href="example.css" />
참고: only 키워드는 반드시 미디어 타입 앞에만 사용할 수 있습니다. 미디어쿼리가 미디어 기능만으로 이루어져 있거나, not과 같은 다른 미디어쿼리 한정자와 함께 쓰인 경우, 레거시 사용자 에이전트는 자동으로 false로 처리합니다.
참고: 이 명세가 공개되는 시점에는 이러한 레거시 사용자 에이전트는 매우 드물기 때문에, only 한정자를 사용할 필요가 거의 없습니다.
2.3. 미디어 타입
미디어 타입은
문서가 표시될 수 있는 사용자 에이전트 장치의 넓은 범주입니다.
원래의 미디어 타입들은 HTML4에서,
link
요소의 media
속성 용도로 정의되었습니다.
하지만 미디어 타입은 다양한 스타일링 요구를 가진 장치를 구분하는 데 충분치 않은 것으로 드러났습니다. 처음에는 명확히 구분되던 screen과 handheld 같은 범주도 시간이 흐르며 많이 혼합되었습니다. tty나 tv 등은 일반 컴퓨터 모니터와 차별화되는 특징이 있어 별도 스타일링에 유용할 수 있지만, 미디어 타입이 상호 배타적이어서 실질적으로 활용하기 어렵습니다; 대신, 이들의 배타적 특성은 미디어 기능(예: grid, scan) 등으로 표현하는 것이 더 적합합니다.
따라서, 아래 미디어 타입은 미디어쿼리에서 사용할 수 있도록 정의됩니다:
- all
- 모든 장치에 일치합니다.
- 프린터, 인쇄된 화면을 재현하려는 장치(예: 웹 브라우저의 인쇄 미리보기)에 일치합니다.
- screen
- print에 일치하지 않는 모든 장치에 일치합니다.
추가로 아래 사용 중단됨 미디어 타입도 정의되어 있습니다. 작성자는 이러한 미디어 타입을 사용하면 안 되며, 대신 스타일링하려는 장치의 특성을 더 잘 표현하는 미디어 기능을 사용하는 것이 권장됩니다.
사용자 에이전트는 아래 미디어 타입을 유효한 것으로 인식해야 하지만, 실제로는 아무 것도 일치하지 않도록 처리해야 합니다.
참고: 모든 미디어 타입도 결국 사용할 수 없게 될 것으로 예상되며, 중요한 차이를 포착하는 적합한 미디어 기능이 정의됨에 따라 대체될 것입니다.
2.4. 미디어 기능
미디어 기능은 미디어 타입보다 더 세밀하게 사용자 에이전트나 디스플레이 장치의 단일, 특정 기능을 테스트합니다.
구문적으로 미디어 기능은 CSS 속성과 유사합니다: 기능 이름, 콜론, 테스트할 값으로 구성됩니다. 부울 형태로 기능 이름만 쓰거나, 범위 형태로 비교 연산자를 사용할 수도 있습니다.
하지만 속성과 미디어 기능 사이에는 몇 가지 중요한 차이가 있습니다:
- 속성은 문서의 표현 방식을 지정하는 정보입니다. 미디어 기능은 출력 장치의 요구사항을 설명합니다.
- 미디어 기능은 항상 괄호로 감싸고, and 또는 or 키워드로 결합합니다. 예: (color) and (min-width: 600px) 세미콜론으로 구분하는 것이 아닙니다.
- 미디어 기능은 이름만으로도(콜론과 값 생략) 사용할 수 있으며, 부울 문맥에서 평가합니다. 0 또는 "none"을 의미하는 값이 있을 때 간편하게 사용할 수 있습니다. 예를 들어 (color)는 color 미디어 기능이 0이 아닐 때 true입니다.
- "range" 타입의 미디어 기능은 범위 문맥에서 표준 수학 비교 연산자를 사용하거나, 기능 이름에 "min-" 또는 "max-" 접두어를 붙일 수 있습니다.
- 속성은 복잡한 값을 받을 수 있습니다(여러 값이 계산에 사용되는 경우 등). 미디어 기능은 항상 단일 값(키워드 하나, 숫자 하나 등)만 받습니다.
미디어 기능이 UA가 실행 중인 장치에 존재하지 않는 개념을 참조한다면 (예: 음성 UA는 "width" 개념이 없음), 미디어 기능은 항상 false로 평가되어야 합니다.
<link media="speech and (device-aspect-ratio: 16/9)" rel="stylesheet" href="example.css">
2.4.1. 미디어 기능 타입: “range”와 “discrete”
모든 미디어 기능은 정의 표에서 "range" 또는 "discrete" 타입을 지정합니다.
"discrete" 미디어 기능(예: pointer)은 값이 집합에서 선택됩니다.
값은 키워드일 수도 있고, 부울 숫자(0, 1)일 수도 있지만,
공통점은 값들 사이에 고유한 "순서"가 없다는 점입니다—
"range" 미디어 기능(예: width)은 값이 범위에서 선택됩니다. 두 값은 어느 것이 더 작은지, 더 큰지 비교할 수 있습니다.
두 타입의 유의미한 차이는 "range" 미디어 기능이
범위 문맥에서 평가될 수 있으며,
이름에 "min-"과 "max-" 접두어를 허용한다는 점입니다.
이렇게 하면 기능의 의미가 달라집니다—
반면, (width: 600px)은 뷰포트 너비가 정확히 600px일 때만 true입니다. 작거나 크면 false입니다.
2.4.2. 미디어 기능의 부울 문맥 평가
미디어 기능은 일반적으로 CSS 속성과 비슷한 문법을 가지지만, 기능 이름만으로 더 간단하게 작성할 수도 있습니다. 예: (color)
이렇게 작성하면 미디어 기능은 부울 문맥에서 평가됩니다. 값이 0이 아닌 어떤 값(숫자 0, 값 0인 <dimension>, 키워드 none, 또는 해당 미디어 기능에서 부울 문맥에서 false로 정의된 값)이 아니면 미디어 기능이 true가 됩니다. 그렇지 않으면 false가 됩니다.
예를 들어 update는 보통 (update)로 작성하여 어떤 종류의 갱신이 가능한지 테스트하거나, not (update)로 반대로 테스트합니다.
명시적으로 값을 줄 수도 있습니다. (update: fast) 또는 (update: slow)는 (update)과 같고, (update: none)은 not (update)과 같습니다.
예를 들어 (pointer)는 유용합니다. pointer는 장치에 포인팅 장치가 없음을 나타내는 none 값이 있기 때문입니다. 반면 (scan)은 항상 true 또는 항상 false(장치에 적용되는지에 따라)이며, "false"를 의미하는 값이 없습니다.
2.4.3. 미디어 기능의 범위 문맥 평가
"range" 타입 미디어 기능은 값에 순서가 있다는 점을 활용하여 일반 수학 비교 연산자를 사용하는 범위 문맥에서도 쓸 수 있습니다:
참고: 이 구문은 미디어쿼리 레벨 4에서 새로 추가된 것이며, 현재 min-/max- 접두어보다 지원이 덜 보편적입니다.
기본 형태(기능 이름, 비교 연산자, 값)는 관계가 참이면 true를 반환합니다.
기능 이름이 두 값 비교 사이에 위치하는 형태는 두 비교가 모두 참이면 true를 반환합니다.
"range" 타입의 일부 미디어 기능은 음수 범위에서 false라고 명시되어 있습니다. 이는 음수 값이 유효하며 파싱되어야 하고, 해당 미디어 기능이 그 음수 값과 같거나, 작거나, 작거나 같음을 질의하면 항상 false가 된다는 뜻입니다. 음수 값보다 크거나, 크거나 같음을 질의하면 관계가 참일 때 true가 됩니다.
참고: 음수 값이 파싱에서 거부되었다면, 오류 처리 규칙에 따라 unknown으로 취급됩니다. 하지만 실제로 장치의 resolution이 -300dpi인지는 unknown이 아니라 false임이 확실합니다. 마찬가지로 모든 시각 장치에서 width가 -200px보다 큰지 여부도 false가 아닌 true임이 분명합니다. 위 규칙은 직관과 UA의 실제 동작을 일치시킵니다.
@media not ( width <= -100 px ) {
body { background : green; }
}
@media ( height > -100 px ) {
body { background : green; }
}
@media not ( resolution: -300 dpi ) {
body { background : green; }
}
2.4.4. "min-" 및 "max-" 접두어를 범위 기능에 사용하는 방법
위에서 설명한 것처럼 "range" 타입의 미디어 기능을 범위 문맥에서 평가하는 대신, 기능을 일반 미디어 기능으로 작성하되 기능 이름에 "min-" 또는 "max-" 접두어를 붙일 수 있습니다.
이는 아래와 같이 범위 문맥에서 기능을 평가하는 것과 동등합니다:
- 기능 이름에 "min-" 접두어를 사용하면 ">=" 연산자를 사용하는 것과 같습니다. 예를 들어, (min-height: 600px)은 ''(height >= 600px)''과 동일합니다.
- 기능 이름에 "max-" 접두어를 사용하면 "<=" 연산자를 사용하는 것과 같습니다. 예를 들어, (max-width: 40em)은 ''(width <= 40em)''과 동일합니다.
참고: "min-"과 "max-"는 모두 값을 포함하는 범위 비교이므로, 특정 상황에서는 제한적일 수 있습니다.
@media (max-width: 320px) { /* 320px 이하 뷰포트 스타일 */ } @media (min-width: 321px) { /* 321px 이상 뷰포트 스타일 */ }
이렇게 하면 뷰포트 너비가 320px일 때 두 스타일이 동시에 적용되지 않지만, 고정되지 않은 픽셀 밀도(예: 고해상도 디스플레이 또는 확대/축소 결과)로 인해 소수점 크기의 뷰포트가 발생할 수 있다는 점은 고려하지 않습니다. 320px과 321px 사이의 모든 뷰포트 너비에는 스타일이 적용되지 않습니다.
이 문제를 해결하는 한 가지 방법은 비교에 사용하는 값의 정밀도를 높이는 것입니다. 위 예시에서, 두 번째 비교 값을 320.01px로 변경하면 실제 장치에서 빈 구간에 속할 확률이 크게 줄어듭니다.
@media (max-width: 320px) { /* 320px 이하 뷰포트 스타일 */ } @media (min-width: 320.01px) { /* 320.01px 이상 뷰포트 스타일 */ }
하지만 이런 경우에는 범위 문맥 질의(단순히 ">=" 및 "<=" 비교에 제한되지 않음)가 더 적합한 해결책이 될 수 있습니다:
@media (width <= 320px) { /* 320px 이하 뷰포트 스타일 */ } @media (width > 320px) { /* 320px 초과 뷰포트 스타일 */ }
"discrete" 타입 속성은 "min-" 또는 "max-" 접두어를 사용할 수 없습니다. 이런 접두어를 "discrete" 타입 미디어 기능에 붙이면 알 수 없는 기능 이름이 됩니다.
min/max 접두어가 붙은 미디어 기능을 부울 문맥에서 평가하려고 하면 유효하지 않으며 구문 오류가 발생합니다.
2.5. 미디어 기능 조합
여러 미디어 기능을 전체 부울 대수(not, and, or)를 이용해 조합하여 미디어 조건으로 만들 수 있습니다.
-
어떤 미디어 기능이든 앞에 not을 붙여서 부정할 수 있습니다. 예를 들어, not (color)는 (color)의 의미를 반전시킵니다—
(color)가 색상 디스플레이가 있는 장치에 일치한다면, not (color)는 색상 디스플레이가 없는 장치에 일치합니다. -
두 개 이상의 미디어 기능을 "and"로 연결하면, 모든 미디어 기능이 true인 경우에만 질의가 true가 됩니다. 예: (width < 600px) and (height < 600px)은 화면의 너비와 높이가 모두 600px 미만인 장치에만 일치합니다.
-
또는 두 개 이상의 미디어 기능을 "or"로 연결하면, 어떤 미디어 기능이 true여도 질의가 true가 됩니다. 예: (update: slow) or (hover: none)은 장치가 화면 갱신이 느리거나(예: e-리더) 혹은 주 포인팅 장치에 hover 기능이 없으면 일치합니다. 이런 경우 레이아웃을 더 많은 정보를 보여주는 방식으로 바꾸는 것이 적합할 수 있습니다(사용자가 hover할 때까지 숨기지 않고).
-
미디어 조건은 괄호 ()로 감싸서 그룹화할 수 있으며, 이렇게 그룹화된 조건은 단일 미디어쿼리처럼 중첩해서 사용할 수 있습니다. 예: (not (color)) or (hover)는 모노크롬이면서 hover 기능이 있는 장치에 true입니다. 반대로 모노크롬이면서 hover 기능이 없는 장치를 질의하려면 not ((color) or (hover)) 또는 (not (color)) and (not (hover))로 작성해야 합니다.
and, or, not을 같은 "레벨"에서 혼합해서 쓰는 것은 유효하지 않습니다. 예: (color) and (pointer) or (hover)는 의미가 불명확하므로 허용되지 않습니다. 대신 괄호로 그룹화해서 특정 결합 키워드를 사용해야 하며, (color) and ((pointer) or (hover)) 또는 ((color) and (pointer)) or (hover)처럼 작성해야 합니다. 두 예시는 전혀 다른 의미를 가집니다: (hover)만 true면 첫 번째는 false가 되고 두 번째는 true가 됩니다.
3. 문법
미디어쿼리 문법에 대한 비공식 설명은 앞의 본문과 railroad 다이어그램에 있습니다. 공식 미디어쿼리 문법은 이 섹션에서 설명하며, 규칙/속성 문법은 [CSS-SYNTAX-3] 및 [CSS-VALUES-4]에서 정의됩니다.
<media-query-list> 생산식을 파싱할 때는 콤마로 구분된 구성 값 리스트를 파싱한 후, 반환된 리스트의 각 항목을 <media-query>로 파싱합니다. 그 값은 이렇게 생성된 <media-query> 리스트입니다.
참고: <media-query-list> 파싱을 명시적으로 정의하는 것은 미디어쿼리 리스트의 오류 복구 동작을 명확하게 하기 위해 필요합니다.
참고: <media-query-list> 파싱은 빈 리스트도 허용합니다.
참고: [CSS-SYNTAX-3]에 따라 토큰은 ASCII 대소문자 구분 없음입니다.
<media-query> = <media-condition> | [ not | only ]? <media-type> [ and <media-condition-without-or> ]? <media-type> = <ident> <media-condition> = <media-not> | <media-in-parens> [ <media-and>* | <media-or>* ] <media-condition-without-or> = <media-not> | <media-in-parens> <media-and>* <media-not> = not <media-in-parens> <media-and> = and <media-in-parens> <media-or> = or <media-in-parens> <media-in-parens> = ( <media-condition> ) | <media-feature> | <general-enclosed> <media-feature> = ( [ <mf-plain> | <mf-boolean> | <mf-range> ] ) <mf-plain> = <mf-name> : <mf-value> <mf-boolean> = <mf-name> <mf-range> = <mf-name> <mf-comparison> <mf-value> | <mf-value> <mf-comparison> <mf-name> | <mf-value> <mf-lt> <mf-name> <mf-lt> <mf-value> | <mf-value> <mf-gt> <mf-name> <mf-gt> <mf-value> <mf-name> = <ident> <mf-value> = <number> | <dimension> | <ident> | <ratio> <mf-lt> = '<' '='? <mf-gt> = '>' '='? <mf-eq> = '=' <mf-comparison> = <mf-lt> | <mf-gt> | <mf-eq> <general-enclosed> = [ <function-token> <any-value> ) ] | ( <ident> <any-value> )
<media-type> 생산식에는 only, not, and, or 키워드는 포함되지 않습니다.
"<" 또는 ">" <delim-token> 뒤에 "=" <delim-token>이 올 경우, 그 사이에는 공백이 허용되지 않습니다.
참고: not, and, or 키워드 뒤에는 반드시 ( 문자와 공백이 필요합니다. 그렇지 않으면 <function-token>으로 파싱됩니다. 이는 위의 문법에서 이미 처리되므로 별도로 명시적으로 금지하지 않습니다. ) 뒤에 키워드가 오는 경우에는 공백이 있어도 됩니다.
<media-in-parens> 생산식을 파싱할 때, <general-enclosed> 분기는 입력이 앞의 두 분기에 일치하지 않을 때만 선택해야 합니다. <general-enclosed>는 향후 문법 확장을 호환성 있게 지원하기 위해 존재합니다.
3.1. 미디어쿼리 평가
<media-condition> 또는 <media-condition-without-or>의 주요 부분식마다 아래와 같이 부울 결과가 연결됩니다:
- <media-condition>
- <media-condition-without-or>
- 결과는 자식 부분식의 결과입니다.
- <media-in-parens>
- 결과는 자식 항의 결과입니다.
- <media-not>
- 결과는 <media-in-parens> 항의 부정입니다. unknown의 부정은 unknown입니다.
- <media-in-parens> <media-and>*
- <media-in-parens> 자식 항과 <media-and> 자식 항의 모든 <media-in-parens>이 true면 결과가 true, 이 중 하나라도 false면 false, 그 외에는 unknown입니다.
- <media-in-parens> <media-or>*
- <media-in-parens> 자식 항과 <media-or> 자식 항의 모든 <media-in-parens>이 false면 결과가 false, 이 중 하나라도 true면 true, 그 외에는 unknown입니다.
- <general-enclosed>
-
결과는 unknown입니다.
작성자는 <general-enclosed>를 스타일시트에서 사용하면 안 됩니다. 이것은 미래 호환성을 위해 존재하며, 새로운 구문 추가가 오래된 사용자 에이전트에서 <media-condition>을 너무 많이 무효화하지 않도록 하기 위함입니다.
- <media-feature>
- 결과는 지정된 미디어 기능을 평가한 결과입니다.
위 생산식 결과가 2값 부울을 기대하는 맥락에서 사용될 경우, "unknown"은 "false"로 변환해야 합니다.
참고: 예를 들어, 미디어쿼리가 @media 규칙에서 사용될 때, "unknown"으로 해결되면 "false"로 간주되어 일치하지 않게 됩니다.
일반적으로 수식에 unknown 값이 들어가면 그 수식도 unknown이 됩니다. unknown을 true로 대체했을 때와 false로 대체했을 때 결과가 달라지기 때문입니다. unknown 값을 없애는 유일한 방법은 unknown을 true로 대체하든 false로 대체하든 결과가 동일한 수식에서 사용하는 것입니다. 예를 들어 "false AND unknown"(언제나 false)과 "true OR unknown"(언제나 true)이 해당됩니다.
이 논리가 채택된 이유는 <general-enclosed> 에 진리값을 할당해야 하기 때문입니다. 일반 부울 논리에서는 "false"가 유일한 선택이지만, 이렇게 하면 not unknown(function)이 true가 되어 혼란스럽고 원치 않는 결과를 낳을 수 있습니다. Kleene의 3값 논리를 사용하면 unknown이 있는 경우 미디어쿼리가 일치하지 않으며, 그 값이 최종 결과에 무관하지 않은 한 일치하지 않게 됩니다.
3.2. 오류 처리
이전 섹션의 문법과 일치하지 않는 미디어쿼리는 파싱 중에 not all로 대체되어야 합니다.
참고: 문법 불일치는 전체 미디어쿼리 리스트를 삭제하지 않습니다, 문제 있는 미디어쿼리만 제거합니다. 위에 정의된 파싱 동작은 다음 최상위 콤마에서 자동으로 복구됩니다.
@media (example, all,), speech { /* 오직 speech 장치에만 적용됨 */ } @media &test, speech { /* 오직 speech 장치에만 적용됨 */ }
위 두 미디어쿼리 리스트 모두 파싱 중에 not all, speech로 변환되며, 이는 speech만 단독으로 있을 때와 동일한 진리값을 가집니다.
오류 복구는 미디어쿼리의 최상위에서만 발생한다는 점에 유의하세요; 유효하지 않은 괄호 블록 내부의 모든 내용은 그룹으로 not all로 변환됩니다. 예를 들어:
@media (example, speech { /* speech 장치용 규칙 */ }
괄호 블록이 닫히지 않아, 이후 스타일시트의 나머지 전체가 그 안에 포함되며 (스타일시트 어디선가 일치하지 않는 “)”를 만나지 않는 한), 전체가 not all 미디어쿼리로 변환됩니다.
알 수 없는 <media-type>은 일치하지 않는 것으로 처리되어야 합니다.
하지만 not unknown은 true입니다. not이 false 미디어 타입을 부정하기 때문입니다.
알 수 없는 <mf-name> 또는 <mf-value>, 또는 허용되지 않는 <mf-value>가 있으면 값은 “unknown”이 됩니다. 값이 “unknown”인 <media-query>는 not all로 대체되어야 합니다.
<link media="screen and (max-weight: 3kg) and (color), (color)"rel="stylesheet" href="example.css" />
max-weight가 알 수 없는 미디어 기능이므로, 이 미디어쿼리 리스트는 not all, (color)로 변환되며, 이는 (color)만 있을 때와 동등합니다.
@media (min-orientation:portrait) { … }
orientation 기능은 접두어를 허용하지 않으므로, 이는 알 수 없는 미디어 기능으로 간주되어 not all로 변환됩니다.
@media test;,all { body { background:lime } }
test;,all 미디어쿼리는 단독으로 파싱하면 not all, all과 같으며, 항상 true입니다. 그러나 CSS의 파싱 규칙에 따라 @media 규칙, 즉 미디어쿼리는 세미콜론에서 끝나게 됩니다. 나머지 텍스트는 잘못된 선택자와 내용으로 스타일 규칙으로 처리됩니다.
4. 뷰포트/페이지 특성 미디어 기능
4.1. 너비: width 기능
이름: | width |
---|---|
대상: | @media |
값: | <length> |
타입: | range |
width 미디어 기능은 출력 장치의 대상 표시 영역의 너비를 설명합니다. 연속 미디어의 경우 뷰포트의 너비 (CSS2, 섹션 9.1.1 [CSS2]에 기술됨) 렌더링된 스크롤 바의 크기(있는 경우)도 포함됩니다. 페이지 미디어의 경우 페이지 박스의 너비 (CSS2, 섹션 13.2 [CSS2]에 기술됨)입니다.
<length> 값은 § 1.3 단위에 따라 해석됩니다.
width는 음수 영역에서는 false입니다.
<link rel="stylesheet" media="print and (min-width: 25cm)" href="http://…" />
@media (400px <= width <= 700px) { … }
4.2. 높이: height 기능
이름: | height |
---|---|
대상: | @media |
값: | <length> |
타입: | range |
height 미디어 기능은 출력 장치의 대상 표시 영역의 높이를 설명합니다. 연속 미디어의 경우 뷰포트의 높이(렌더링된 스크롤 바의 크기 포함, 있을 경우). 페이지 미디어의 경우 페이지 박스의 높이입니다.
<length> 값은 § 1.3 단위에 따라 해석됩니다.
height는 음수 영역에서는 false입니다.
4.3. 종횡비: aspect-ratio 기능
이름: | aspect-ratio |
---|---|
대상: | @media |
값: | <ratio> |
타입: | range |
aspect-ratio 미디어 기능은 width 미디어 기능의 값과 height 미디어 기능의 값의 비율로 정의됩니다.
4.4. 방향: orientation 기능
이름: | orientation |
---|---|
대상: | @media |
값: | portrait | landscape |
타입: | discrete |
- portrait
- orientation 미디어 기능은 portrait이며, height 미디어 기능의 값이 width 미디어 기능의 값보다 크거나 같을 때입니다.
- landscape
- 그 외의 경우 orientation은 landscape입니다.
4.5. 블록 축 오버플로우: overflow-block 기능
이름: | overflow-block |
---|---|
대상: | @media |
값: | none | scroll | paged |
타입: | discrete |
overflow-block 미디어 기능은 블록 축에서 콘텐츠가 초기 포함 블록을 넘칠 때 장치의 동작을 설명합니다.
- none
- 블록 축에서 오버플로우에 대한 대응이 없으며, 넘친 콘텐츠는 표시되지 않습니다. 예시: 전광판
- scroll
- 블록 축에서 넘친 콘텐츠를 사용자가 스크롤하여 볼 수 있습니다. 예시: 컴퓨터 화면
- paged
- 콘텐츠가 개별 페이지로 나뉘며, 블록 축에서 한 페이지를 넘친 콘텐츠는 다음 페이지에 표시됩니다. 예시: 프린터, 전자책 리더기
none 또는 scroll 값에 일치하는 미디어는 연속 미디어라 하며, paged 값에 일치하는 미디어는 페이지 미디어라 합니다.
참고: 이 미디어 기능에는 향후 연속과 페이지 미디어의 하이브리드 동작을 가진 사용자 에이전트 유형을 설명할 값이 추가될 수 있습니다. 예를 들어, 중단된 Presto 레이아웃 엔진은 continuous와 유사하지만 강제 페이지 분할을 존중하는 반페이지 모드가 있었습니다. 현재 이러한 행동을 가진 사용자 에이전트가 없으므로, 워킹그룹은 오해를 피하기 위해 이번 레벨에는 그런 값을 추가하지 않기로 결정했습니다. 위에 명시된 값으로 충분히 설명되지 않는 사용자 에이전트를 구현하는 분은, 워킹 그룹에 연락해 확장 제안을 요청하시기 바랍니다.
4.6. 인라인 축 오버플로우: overflow-inline 기능
이름: | overflow-inline |
---|---|
대상: | @media |
값: | none | scroll |
타입: | discrete |
overflow-inline 미디어 기능은 인라인 축에서 콘텐츠가 초기 포함 블록을 넘칠 때 장치의 동작을 설명합니다.
- none
- 인라인 축에서 오버플로우에 대한 대응이 없으며, 넘친 콘텐츠는 표시되지 않습니다.
- scroll
- 인라인 축에서 넘친 콘텐츠를 사용자가 스크롤하여 볼 수 있습니다.
참고: 인라인 축에서 overflow된 콘텐츠를 페이지 단위로 처리하는 구현은 알려진 바 없으며, 개념 자체도 큰 의미가 없어 paged 값은 overflow-inline에 의도적으로 존재하지 않습니다.
4.7. 수평 뷰포트 세그먼트: horizontal-viewport-segments 기능
이름: | horizontal-viewport-segments |
---|---|
대상: | @media |
값: | <integer> |
타입: | range |
horizontal-viewport-segments 미디어 기능은 뷰포트의 수평 방향 논리 세그먼트 개수를 설명합니다.
horizontal-viewport-segments 미디어 기능은 음수 영역에서는 false입니다.
뷰포트가 하나 이상의 하드웨어 요소(분리된 디스플레이 사이의 폴드, 힌지 등)에 의해 논리적으로 나뉘는 경우, 세그먼트는 페이지에서 논리적으로 개별적으로 취급될 수 있는 뷰포트의 영역입니다.
4.8. 수직 뷰포트 세그먼트: vertical-viewport-segments 기능
이름: | vertical-viewport-segments |
---|---|
대상: | @media |
값: | <integer> |
타입: | range |
vertical-viewport-segments 미디어 기능은 뷰포트의 수직 방향 논리 세그먼트 개수를 설명합니다.
vertical-viewport-segments 미디어 기능은 음수 영역에서는 false입니다.
@media (horizontal-viewport-segments: 2) and (vertical-viewport-segments: 1) { … }
4.9. 디스플레이 모드: display-mode 미디어 기능
이름: | display-mode |
---|---|
대상: | @media |
값: | fullscreen | standalone | minimal-ui | browser |
타입: | discrete |
display-mode 미디어 기능은 웹 애플리케이션의 디스플레이 모드를 나타냅니다. 자식 브라우징 컨텍스트는 자신의 디스플레이 모드를 최상위 브라우징 컨텍스트의 디스플레이 모드로 반영합니다.
디스플레이 모드는 웹 애플리케이션이 OS 환경에서 어떻게 표시되는지를 나타냅니다(예: 전체화면 등). 디스플레이 모드는 플랫폼에서 사용되는 사용자 인터페이스(UI) 메타포 및 기능에 대응합니다. 디스플레이 모드의 UI 관례는 오로지 참고용이며, 구현자는 이를 자유롭게 해석할 수 있습니다.
이 명세는 다음 디스플레이 모드를 정의합니다:
- fullscreen
- 웹 애플리케이션이 브라우저 UI 요소를 숨기고, 사용 가능한 전체 디스플레이 영역을 차지하여 표시됩니다.
- standalone
- 웹 애플리케이션이 독립 실행형 네이티브 애플리케이션처럼 보이고 동작하도록 표시됩니다. 별도의 창, 애플리케이션 런처의 자체 아이콘 등 포함될 수 있습니다. 이 모드에서는 사용자 에이전트가 표준 브라우저 UI 요소(예: URL 바)를 제외하지만, 윈도우 장식, 시스템 상태바, 시스템 백 버튼 등 표준 시스템 UI 요소는 그대로 사용할 수 있습니다.
- minimal-ui
- 이 모드는 standalone과 유사하지만, 최종 사용자에게 네비게이션 제어를 위한 최소한의 UI 요소(뒤로, 앞으로, 새로고침, 주소 보기 등)를 제공합니다. 사용자 에이전트는 "공유", "인쇄" 버튼 등 플랫폼 및 에이전트에 맞는 다른 UI 요소도 포함할 수 있습니다.
- browser
- 웹 애플리케이션이 사용자 에이전트에서 하이퍼링크를 여는 플랫폼별 방식(예: 브라우저 탭, 새 창 등)으로 표시됩니다.
fullscreen 디스플레이 모드는 Fullscreen API와 다릅니다.
fullscreen 디스플레이 모드는 브라우저 뷰포트의 전체화면 상태를 설명하며,
Fullscreen API는 뷰포트 내부의 요소에 작동합니다.
따라서 웹 애플리케이션의 디스플레이 모드가
fullscreen이어도,
fullscreenElement
가 null
을 반환하고,
fullscreenEnabled
가 false
를 반환할 수 있습니다.
fullscreen 디스플레이 모드는 CSS :fullscreen 의사 클래스와도 직접 관련되지 않습니다.
:fullscreen 의사 클래스는 해당 요소가 fullscreen stack에
포함될 때만 일치합니다.
하지만 Fullscreen API로 requestFullscreen()
메서드를 호출하면 브라우저가 OS 차원에서 fullscreen 모드로 들어갈 수 있고,
그럴 경우 :fullscreen과 (display-mode: fullscreen) 모두 일치하게 됩니다.
/* 뷰포트가 전체화면일 때 적용됨 */ @media ( display-mode: fullscreen) { ...} /* 요소가 전체화면일 때 적용됨 */ #game:fullscreen{ ...}
5. 디스플레이 품질 미디어 기능
5.1. 디스플레이 해상도: resolution 기능
이름: | resolution |
---|---|
대상: | @media |
값: | <resolution> | infinite |
타입: | range |
resolution 미디어 기능은 출력 장치의 해상도(픽셀 밀도)를 설명하며, 페이지 줌을 고려하지만, 핀치 줌은 1.0으로 가정합니다.
resolution 미디어 기능은 음수 영역에서는 false입니다.
비정사각형 픽셀을 가진 미디어를 질의할 때, resolution은 수직 방향의 밀도를 질의합니다.
프린터의 경우, 이는 스크리닝 해상도(임의 색상의 점을 인쇄하는 해상도)에 해당합니다. 프린터는 그레이스케일 인쇄에 대해 다른 해상도를 가질 수 있습니다.
물리적 해상도에 제한이 없는 출력(예: 벡터 그래픽 출력)의 경우, 이 기능은 infinite 값에 일치해야 합니다. 범위 문맥에서 이 미디어 기능을 평가할 때, infinite는 어떤 <resolution>보다 크다고 간주해야 합니다. (즉, (resolution > 1000dpi)는 infinite 미디어에서 true가 됩니다.)
@media print and (min-resolution: 300dpi) { … }
이 미디어쿼리는 CSS cm 단위를 사용한 동등한 예시입니다:
@media print and (min-resolution: 118dpcm) { … }
사용자 에이전트가 물리적 픽셀의 기하 정보를 알지 못하거나, 알지만 픽셀이 (거의) 정사각형이라면, 축마다 css 픽셀당 장치 픽셀 수를 다르게 매핑하지 않으며, 수직과 수평 해상도의 차이가 없습니다.
반면 UA가 축마다 다르게 매핑하기로 결정한다면, 이는 물리적 픽셀이 정사각형이 아닌 경우에 대응하기 위함입니다. UA가 어떻게 이 정보를 얻는지는 범위 밖이지만, 정보를 충분히 얻었다면 장치가 90도 회전할 때 매핑도 반대로 할 수 있습니다.
5.2. 디스플레이 타입: scan 기능
이름: | scan |
---|---|
대상: | @media |
값: | interlace | progressive |
타입: | discrete |
scan 미디어 기능은 일부 출력 장치의 스캔 과정을 설명합니다.
- interlace
-
CRT 및 일부 플라즈마 TV 화면은 "인터레이스" 렌더링을 사용합니다.
영상 프레임이 화면의 "짝수" 줄만, "홀수" 줄만 번갈아가며 표시되어,
자동 보정 능력을 이용해 부드러운 움직임을 만듭니다.
이를 통해 대역폭 절반으로 더 높은 FPS 방송을 흉내낼 수 있습니다.
인터레이스 화면에서는 화면을 매우 빠르게 움직이는 것을 피해야 "combing"을 방지할 수 있고, 글자 등의 세부 요소가 1px보다 넓게 만들어 "twitter" 현상을 피해야 합니다.
- progressive
-
"프로그레시브" 렌더링을 사용하는 화면은 전체 화면을 한 번에 표시하며,
특별한 처리가 필요없습니다.
대부분의 현대 화면, 모든 컴퓨터 화면은 프로그레시브 렌더링을 사용합니다.
@media (scan: interlace) { body { font-family: sans-serif; } }
참고: 작성 시점 기준, 모든 구현은 scan: progressive
에 일치하며
scan: interlace
에는 일치하지 않습니다.
5.3. 콘솔 디스플레이 감지: grid 기능
이름: | grid |
---|---|
대상: | @media |
값: | <mq-boolean> |
타입: | discrete |
grid 미디어 기능은 출력 장치가 그리드형인지 비트맵형인지 질의하는 데 사용됩니다. 출력 장치가 그리드 기반(예: tty 터미널, 고정 폰트만 지원하는 휴대폰 디스플레이)이면 값이 1, 아니면 값이 0입니다.
<mq-boolean> 값 타입은 값이 0 또는 1인 <integer>입니다. 다른 정수 값은 모두 잘못된 값입니다. 참고로 -0은 CSS에서 항상 0과 동일하므로, <mq-boolean> 값으로도 인정됩니다.
참고: <mq-boolean> 타입은 레거시 목적만 존재합니다. 오늘날 이 기능을 설계한다면 값에 적절한 키워드를 사용했을 것입니다.
참고: 작성 시점 기준, 모든 구현은 grid: 0
에 일치하며 grid: 1
에는
일치하지 않습니다.
5.4. 표시 갱신 빈도: update 기능
이름: | update |
---|---|
대상: | @media |
값: | none | slow | fast |
타입: | discrete |
update 미디어 기능은 출력 장치가 렌더링된 후 콘텐츠 외형을 수정할 수 있는 능력을 질의하는 데 사용됩니다. 다음 값을 허용합니다:
- none
- 렌더링이 끝나면 레이아웃을 더 이상 갱신할 수 없습니다. 예시: 종이에 인쇄된 문서.
- slow
- 레이아웃은 CSS의 일반 규칙에 따라 동적으로 변경될 수 있지만, 출력 장치가 변경 사항을 충분히 빠르게 렌더링하거나 표시하지 못해 부드러운 애니메이션으로 인식될 수 없습니다. 예시: E-ink 화면 또는 매우 저성능 장치.
- fast
- 레이아웃은 CSS의 일반 규칙에 따라 동적으로 변경될 수 있으며, 출력 장치의 속도가 특별히 제한되지 않으므로 CSS 애니메이션처럼 주기적으로 갱신되는 요소를 사용할 수 있습니다. 예시: 컴퓨터 화면.
@media (update) { a { text-decoration: none; } a:hover, a:focus { text-decoration: underline; } } /* 갱신이 불가능한 UA에서는 링크가 항상 기본 밑줄을 가집니다. */
5.5. 디스플레이 기술 감지: environment-blending 기능
이름: | environment-blending |
---|---|
대상: | @media |
값: | opaque | additive | subtractive |
타입: | discrete |
environment-blending 미디어 기능은 사용자의 디스플레이 특성을 질의하여 작성자가 문서 스타일을 조정할 수 있게 해줍니다. 작성자는 디스플레이 기술에 따라 시각적 요소나 레이아웃을 조정해 매력이나 가독성을 높일 수 있습니다.
다음 값이 유효합니다:
- opaque
- 문서가 불투명 매체(전통적인 모니터, 종이 등)에 렌더링됩니다. 검은색은 어둡고 흰색은 100% 밝습니다.
- additive
-
디스플레이가 캔버스의 색상을 실제 세계와 가산 혼합(additive mixing) 방식으로 블렌딩합니다.
검은색은 완전히 투명, 흰색은 100% 밝습니다.
예시: 자동차의 헤드업 디스플레이.
- subtractive
-
디스플레이가 캔버스의 색상을 실제 세계와 감산 혼합(subtractive mixing) 방식으로 블렌딩합니다.
흰색은 완전히 투명, 어두운 색상이 가장 강한 대비를 가집니다.
예시: 욕실 거울에 내장된 LCD 디스플레이.
subtractive 값이 필요한가요?
body { background-color: white; } p { color: black; } @media(environment-blending: additive) { body { background-color: black; } p { color: white; font-size: 16px; font-weight: 1000; } }
6. 색상 미디어 기능
6.1. 색상 깊이: color 기능
이름: | color |
---|---|
대상: | @media |
값: | <integer> |
타입: | range |
color 미디어 기능은 출력 장치의 색상 성분당 비트 수를 설명합니다. 장치가 컬러 장치가 아니면 값은 0입니다.
color는 음수 영역에서는 false입니다.
서로 다른 색상 성분이 서로 다른 비트 수로 표현된다면, 가장 작은 수를 사용합니다.
색상 인덱스 장치에서는, 룩업 테이블의 색상 성분당 최소 비트 수를 사용합니다.
참고: 위 기능은 색상 지원을 표면적으로만 설명할 수 있습니다. color-gamut이 보통 작성자의 요구에 더 적합합니다. 추가 기능이 필요하면 RFC2879 [RFC2879]에서 더 구체적인 미디어 기능을 제공하며, 이후 지원될 수 있습니다.
6.2. 팔레트 색상 화면: color-index 기능
이름: | color-index |
---|---|
대상: | @media |
값: | <integer> |
타입: | range |
color-index 미디어 기능은 출력 장치의 색상 룩업 테이블 항목 수를 설명합니다. 장치가 색상 룩업 테이블을 사용하지 않으면 값은 0입니다.
color-index는 음수 영역에서는 false입니다.
@media (color-index) { … } @media (color-index >= 1) { … }
<?xml-stylesheet media="(min-color-index: 256)" href="http://www.example.com/…" ?>
6.3. 모노크롬 화면: monochrome 기능
이름: | monochrome |
---|---|
대상: | @media |
값: | <integer> |
타입: | range |
monochrome 미디어 기능은 모노크롬 프레임 버퍼에서 픽셀당 비트 수를 설명합니다. 장치가 모노크롬 장치가 아니면 출력 장치 값은 0입니다.
monochrome는 음수 영역에서는 false입니다.
<link rel="stylesheet" media="print and (color)" href="http://…" /> <link rel="stylesheet" media="print and (monochrome)" href="http://…" />
6.4. 색상 디스플레이 품질: color-gamut 기능
이름: | color-gamut |
---|---|
대상: | @media |
값: | srgb | p3 | rec2020 |
타입: | discrete |
color-gamut 미디어 기능은 UA와 출력 장치가 지원하는 색상의 근사 범위를 설명합니다. 즉, UA가 지정된 색상공간의 색상을 받으면 출력 장치가 해당 색상 또는 근접한 색상을 렌더링할 수 있음을 의미합니다.
참고: 이 질의는 여러 이유로 근사 범위를 사용합니다. 첫째, 디스플레이 하드웨어에 차이가 많습니다. 예를 들어, 어떤 장치는 "Rec. 2020"을 지원한다고 하지만 실제로는 전체 색역의 일부만 렌더링할 수 있습니다. 둘째, 장치마다 지원하는 색상 범위가 다양하며, 모두 나열하는 것은 번거롭습니다. 대부분의 경우 작성자는 디스플레이의 정확한 능력을 알 필요 없이 sRGB보다 나은지, 또는 훨씬 나은지만 알면 됩니다. 그렇게 하면 적절한 이미지(색상 프로파일 포함)를 사용자에게 제공할 수 있습니다.
- srgb
-
UA와 출력 장치는 sRGB 색역 이상을 근사적으로 지원할 수 있습니다.
참고: 거의 모든 컬러 디스플레이가 이 질의에 true를 반환할 것으로 예상됩니다.
- p3
- UA와 출력 장치는 DCI P3 색공간 이상의 색역을 근사적으로 지원할 수 있습니다.
- rec2020
- UA와 출력 장치는 ITU-R 추천 BT.2020 색공간 이상의 색역을 근사적으로 지원할 수 있습니다.
아래 표는 각 색상공간의 주요 색상을 색공간 색도 좌표 기준으로 나열합니다. [COLORIMETRY]에서 정의됨.
색상공간 | 화이트 포인트 | 주색상 | ||||||
---|---|---|---|---|---|---|---|---|
빨강 | 초록 | 파랑 | ||||||
xW | yW | xR | yR | xG | yG | xB | yB | |
srgb | 0.3127 | 0.3290 | 0.640 | 0.330 | 0.300 | 0.600 | 0.150 | 0.060 |
p3 | 0.3127 | 0.3290 | 0.680 | 0.320 | 0.265 | 0.690 | 0.150 | 0.060 |
rec2020 | 0.3127 | 0.3290 | 0.708 | 0.292 | 0.170 | 0.797 | 0.131 | 0.046 |
참고: 위 표는 색상공간을 완전히 설명하기엔 충분하지 않지만, 출력 장치가 해당 색역을 근사적으로 커버하는지 판단하기엔 충분합니다. sRGB에 대한 추가 정보는 [SRGB], DCI P3에 대한 추가 정보는 [SMPTE-EG-432-1-2010] 및 [SMPTE-RP-431-2-2011], ITU-R BT.2020에 대한 추가 정보는 [ITU-R-BT-2020-2] 참고.
참고: 출력 장치는 전체 색역이 충분히 크거나, 한 색역이 다른 지원 색역의 부분집합일 경우 이 미디어 기능의 여러 값에 대해
true를 반환할 수 있습니다.
따라서 이 기능은 "오름차순" 방식으로 사용하는 것이 가장 좋습니다—
참고: 일부 출력 장치(예: 모노크롬 디스플레이)는 srgb 색역조차 지원하지 못할 수 있습니다. 이런 장치를 테스트할 때는 부울 문맥에서 부정형으로 사용할 수 있습니다: not (color-gamut).
6.5. 다이내믹 레인지: dynamic-range 기능
이름: | dynamic-range |
---|---|
대상: | @media |
값: | standard | high |
타입: | discrete |
dynamic-range는 사용자 에이전트와 출력 장치가 지원하는 최대 밝기, 색상 깊이, 명암비의 조합을 나타냅니다.
- high
-
사용자 에이전트와 출력 장치는 아래 모든 기준을 충족합니다:
참고: 일부 장치는 항상 고다이내믹 레인지 기능을 켜는 것이 아니라, 프로그래밍, 사용자 설정, 콘텐츠에 따라 활성화해야 할 수 있습니다. 이 미디어 기능은 해당 모드가 활성화됐는지 테스트하는 것이 아니라, 장치가 고다이내믹 레인지 시각을 지원할 수 있는지만 테스트합니다.
- standard
- 이 값은 모든 시각 장치에 일치하며, 시각 기능이 없는 장치에는 일치하지 않습니다.
참고: 이 미디어 기능은 여러 값이 동시에 일치할 수 있습니다: high에 일치하는 UA는 standard에도 일치합니다.
6.5.1. 디스플레이의 명암 및 밝기 판단
최대 밝기는 LCD 화면과 같은 발광 장치가 낼 수 있는 가장 밝은 점, 또는 종이·e-ink처럼 빛을 반사하는 장치의 경우 가장 적게 빛을 흡수하는 점을 의미합니다.
참고: 일부 장치는 최대 밝기를 아주 짧은 시간 또는 화면 일부에서만 낼 수 있습니다.
명암비는 시스템이 낼 수 있는 가장 밝은 색상과 가장 어두운 색상의 휘도 비율입니다.
이 명세는 이러한 품질을 측정하는 구체적 방법을 정의하지 않으며, 사용자 에이전트가 높은 명암비, 높은 최대 밝기를 무엇으로 볼지 정하게 합니다. 하지만 UA는 아래 취지에 맞게 구현해야 합니다: 높은 최대 밝기를 가진 장치는 "흰색보다 더 밝은" 하이라이트를 표시할 수 있으며, 동시에 깊은 블랙도 표현할 수 있다면(전체적으로 밝지만 탁한 이미지가 아니라면) 높은 명암비로 볼 수 있습니다.
참고: dynamic-range 및 video-dynamic-range의 판정은 UA마다 다르겠지만, 대체로 일관된 의미를 가질 것으로 예상됩니다.
6.6. 디스플레이의 반전 색상 감지: inverted-colors 기능
이름: | inverted-colors |
---|---|
대상: | @media |
값: | none | inverted |
타입: | discrete |
inverted-colors 미디어 기능은 콘텐츠가 정상적으로 표시되는지 또는 색상이 반전됐는지 나타냅니다.
참고: 이는 사용자 에이전트 또는 OS가 모든 색상을 강제로 반전시켰음을 나타내며, 색상 반전을 요청하는 기능이 아닙니다. 이는 간단한 접근성 기능으로 제공되어, 사용자가 밝은 바탕/어두운 텍스트, 또는 반대로 쉽게 전환할 수 있게 합니다. 하지만 이런 기능은 그림을 반전시키거나 그림자의 하이라이트로 바꿔 콘텐츠의 가독성을 저하시킬 수 있습니다.
- none
- 색상이 정상적으로 표시됩니다.
- inverted
-
표시 영역 내 모든 픽셀이 반전되었습니다.
이 값은 UA가 이미지를 보존하는 등 콘텐츠 인식 반전(content aware inversion)을 수행했다면 (단, UA 스타일시트에서 한 경우는 예외) 일치하지 않아야 합니다.
참고: 이 미디어 기능의 목적은 콘텐츠 인식이 없는 방식으로 모든 픽셀을 반전시켰을 때 작성자가 원치 않는 효과를 완화할 수 있도록 하는 것입니다. 만약 작성자가 콘텐츠 인식 반전에서도 대응한다면, 작성자와 UA의 대응이 서로 무효화될 위험이 있습니다.
사용자 에이전트는 아래 규칙을 UA 스타일시트에 추가해야 합니다:
@media ( inverted-colors) {
img : not ( picture>img), picture, video { filter : invert ( 100 % ); }
}
@media (inverted-colors) { * { text-shadow: none !important; box-shadow: none !important; } }
7. 상호작용 미디어 기능
“상호작용” 미디어 기능은 사용자가 페이지와 상호작용하는 다양한 측면을 반영합니다.
pointer: none | pointer: coarse | pointer: fine | |
---|---|---|---|
hover: none | 키보드 전용 컨트롤, 순차/공간(d-패드) 포커스 내비게이션 | 스마트폰, 터치 스크린 | 기본 스타일러스 디지타이저(Cintiq, Wacom 등) |
hover: hover | 닌텐도 Wii 컨트롤러, Kinect | 마우스, 터치패드, 고급 스타일러스 디지타이저(Surface, Samsung Note, Wacom Intuos Pro 등) |
pointer와 hover는 “주” 포인팅 장치의 특성과 관련되며, any-pointer 및 any-hover는 모든 사용 가능한 포인팅 장치의 특성을 질의할 때 사용됩니다.
참고: 이 명세는 사용자 에이전트가 “주” 포인팅 장치를 어떻게 결정해야 하는지 정의하지 않지만, 사용자 에이전트는 실행 환경, 사용 가능한 포인팅 장치의 수와 종류, 일반적으로/현재 사용 중인 장치에 대한 정보를 조합해 판단해야 합니다. 장치의 주요 입력이 포인팅 장치가 아니고, 보조(드물게 사용되는) 입력으로 포인팅 장치가 있을 때, 사용자 에이전트는 비포인팅 장치를 주 입력으로 간주할 수 있습니다('pointer: none' 결과). 또한 사용자 환경 변화나 사용자의 인터랙션 방식에 따라 주 포인팅 장치 유형을 동적으로 변경할 수 있습니다.
참고: pointer, hover, any-pointer, any-hover는 포인팅 장치의 특성 또는 부재만을 반영하며, 키보드 등 비포인팅 입력 메커니즘의 존재는 감지할 수 없습니다. 작성자는 이 기능을 질의할 때 어떤 값이 일치하든 비포인팅 입력이 있을 수 있음을 항상 고려해야 합니다.
7.1. 포인팅 장치 품질: pointer 기능
이름: | pointer |
---|---|
대상: | @media |
값: | none | coarse | fine |
타입: | discrete |
pointer 미디어 기능은 마우스 등의 포인팅 장치의 존재와 정확도를 질의하는 데 사용됩니다. 여러 포인팅 장치가 있을 경우, pointer 미디어 기능은 사용자 에이전트가 결정한 “주” 포인팅 장치의 특성을 반영해야 합니다. (사용 가능한 모든 포인팅 장치의 능력을 질의하려면 any-pointer 미디어 기능을 참고하세요.)
- none
- 장치의 주요 입력 메커니즘에 포인팅 장치가 포함되지 않습니다.
- coarse
- 장치의 주요 입력 메커니즘에 정확도가 제한된 포인팅 장치가 포함됩니다. 예: 터치스크린, 모션 감지 센서(Xbox용 Kinect 등)
- fine
- 장치의 주요 입력 메커니즘에 정확한 포인팅 장치가 포함됩니다. 예: 마우스, 터치패드, 드로잉 스타일러스.
coarse와 fine 모두 포인팅 장치의 존재를 의미하지만, 정확도에서 차이가 있습니다. 여러 개의 작은 인접 타겟을 확대 없이(zoom factor 1) 신뢰성 있게 선택하기 어렵거나 불가능한 장치는 coarse로 간주합니다. 확대/축소 수준을 변경해도 이 미디어 기능의 값에는 영향을 주지 않습니다.
참고: UA가 사용자가 확대/축소 기능을 사용하거나, 보조 포인팅 장치의 정확도가 다를 때, 사용자가 정확한 클릭을 할 수 있더라도 이 미디어 기능 값이 coarse일 수 있습니다. 이 미디어 기능은 사용자가 정확한 클릭을 절대 할 수 없다는 뜻이 아니라, 그렇게 하기 불편하다는 의미입니다. 작성자는 coarse 값을 보고 정확한 클릭이 필요하지 않은 페이지를 설계해야 합니다.
접근성을 위해, 포인팅 장치가 fine으로 설명될 수 있는 장치에서도, UA는 사용자가 포인팅 장치 조작이 어렵거나 불가능함을 나타내기 위해 이 미디어쿼리에 coarse 또는 none 값을 줄 수 있습니다. 또한 주 포인팅 장치가 fine 정확도를 갖더라도, 사용자가 추가로 coarse 포인팅 장치를 사용할 수 있습니다. 작성자는 any-pointer 미디어 기능을 질의해 추가 coarse 포인팅 장치도 고려할 수 있습니다.
/* 주요 포인팅 장치가 정확하지 않을 경우 라디오 버튼과 체크박스를 더 크게 만듦 */ @media (pointer:coarse) { input[type="checkbox"], input[type="radio"] { min-width:30px; min-height:40px; background:transparent; } }
7.2. 호버 가능성: hover 기능
이름: | hover |
---|---|
대상: | @media |
값: | none | hover |
타입: | discrete |
hover 미디어 기능은 사용자가 주 포인팅 장치로 페이지 요소 위에 hover할 수 있는지 질의합니다. 여러 포인팅 장치가 있는 경우, hover 미디어 기능은 사용자 에이전트가 결정한 “주” 포인팅 장치의 특성을 반영해야 합니다. (사용 가능한 모든 포인팅 장치의 능력을 질의하려면 any-hover 미디어 기능을 참고하세요.)
- none
-
주 포인팅 장치가 hover 불가능하거나,
포인팅 장치가 없는 경우를 나타냅니다.
예: 터치스크린, 기본 스타일러스 사용 화면.
hover가 가능하지만 실제로는 불편하고 일반적인 사용 방식에 포함되지 않는 포인팅 장치도 이 값에 일치합니다. 예: 터치스크린에서 롱 프레스가 hover로 처리되는 경우 hover: none에 해당됩니다.
- hover
- 주 포인팅 장치가 페이지의 여러 부분에 쉽게 hover할 수 있음을 나타냅니다. 예: 마우스, 화면을 물리적으로 가리키는 장치(닌텐도 Wii 컨트롤러 등).
하지만 마우스가 사용자의 hover를 허용하므로, 작성자는 ':hover' 의사 클래스가 'hover:none'인 장치에서 절대 일치하지 않는다고 가정해서는 안 되며, hover 없이도 완전히 사용할 수 있는 레이아웃을 설계해야 합니다.
접근성을 위해, hover를 지원하는 장치에서도 UA가 이 미디어쿼리에 hover: none 값을 줄 수 있습니다. 이는 hover 없이도 잘 동작하는 레이아웃에 opt-in 하기 위함입니다. 참고로 주 입력이 'hover: hover'인 경우에도, hover를 제공하지 않는 추가 입력 장치가 사용 가능할 수 있습니다.
/* hover가 편리한 장치에서만 드롭다운 메뉴를 hover로 활성화 */ @media (hover) { .menu > li {display:inline-block;} .menu ul {display:none; position:absolute;} .menu li:hover ul {display:block; list-style:none; padding:0;} /* ... */ }
7.3. 모든 상호작용 가능성: any-pointer 및 any-hover 기능
이름: | any-pointer |
---|---|
대상: | @media |
값: | none | coarse | fine |
타입: | discrete |
이름: | any-hover |
---|---|
대상: | @media |
값: | none | hover |
타입: | discrete |
any-pointer 및 any-hover 미디어 기능은 pointer, hover와 동일하지만, 사용자가 사용할 수 있는 모든 포인팅 장치의 특성 조합을 반영합니다. any-pointer의 경우, 서로 다른 포인팅 장치가 서로 다른 특성을 가질 때 여러 값이 동시에 일치할 수 있습니다.
any-pointer와 any-hover는 모든 포인팅 장치가 해당 질의에 대해 none에 일치하거나, 아예 포인팅 장치가 없을 때만 none에 일치해야 합니다.
스마트TV의 브라우저는 coarse 값을 pointer와 any-pointer 모두에 반환하며, 작성자는 큰 클릭 타겟을 제공하는 레이아웃을 만들 수 있습니다.
사용자가 Bluetooth 마우스를 TV와 페어링해 가끔 추가로 사용할 수도 있지만, 마우스는 TV 조작의 주 방식이 아닙니다. pointer는 계속 coarse에 일치하고, any-pointer는 이제 coarse와 fine 모두에 일치합니다.
이제 (any-pointer: fine)이 true라는 이유로 작은 클릭 타겟을 사용하면 적합하지 않습니다. TV에서 기대하는 경험과 다를 뿐 아니라, 마우스가 TV의 주 조작 방식이 아니기 때문에 손이 닿지 않거나 소파 쿠션 아래에 숨겨져 있을 수도 있습니다...
같은 TV에서 스크롤을 생각해보면, 정확한 포인팅 장치 없이는 스크롤바 조작이 어렵습니다. (pointer: coarse)가 true일 때 대안을 준비해 두고, (any-pointer: fine)이 true일 때는 스크롤바를 추가로 표시하거나, false일 때는 시각적 혼잡을 줄이기 위해 완전히 숨길 수 있습니다.
7.4. UA가 제공하는 내비게이션 컨트롤 감지: nav-controls 기능
이름: | nav-controls |
---|---|
대상: | @media |
값: | none | back |
타입: | discrete |
nav-controls 미디어 기능을 사용하면 작성자가 사용자 에이전트가 눈에 띄게 쉽게 찾을 수 있는 내비게이션 컨트롤을 UI 일부로 제공하는지 알 수 있습니다.
참고: 전통적인 브라우저는 이러한 컨트롤을 보통 제공하며, 웹 페이지는 이를 별도로 신경 쓸 필요가 없었지만, 일부 환경에서는 웹뷰를 통해 웹앱이 실행돼 완전한 UI가 항상 있는 것이 아닙니다. 작성자가 사용자 에이전트가 무엇을 제공하는지 알면, 쉽게 찾을 수 있는 대체 컨트롤을 직접 제공해야 할지 고려할 수 있습니다.
이 맥락에서 눈에 띄게 쉽게 찾을 수 있는 컨트롤은 버튼 등 UI에 직접 보이는 컨트롤이나, 해당 장치의 UI에서 일반적이며 사용자가 쉽게 식별할 수 있는 다른 형태의 컨트롤을 의미합니다. 시각적 UI에서는 보통 가시적인 컨트롤이겠지만, 오디오나 촉각 UI의 경우 다른 것일 수도 있습니다. 중요한 점은, 키보드 단축키나 제스처는 해당되지 않습니다; 편리하긴 해도 사용자가(특히 시각적 UI에서) 보기만 해서는 쉽게 알 수 있는 것이 아니기 때문입니다.
다음 값이 유효합니다:
- none
- 사용자 에이전트에 눈에 띄게 쉽게 찾을 수 있는 내비게이션 컨트롤이 없으며, 특히 공동 세션 히스토리에서 한 페이지 뒤로 이동하는 기능이 없습니다.
- back
- 사용자 에이전트가 내비게이션 컨트롤을 제공하며, 적어도 눈에 띄게 쉽게 찾을 수 있는 컨트롤이 공동 세션 히스토리에서 한 페이지 뒤로 이동시키는 기능(보통 "뒤로" 버튼)을 포함합니다.
@media ( nav-controls: back) {
#back-button {
display : none;
}
}
이 미디어 기능은 부울 문맥에서도 사용할 수 있으므로, 같은 예시를 더 짧게 작성할 수 있습니다:
@media ( nav-controls) {
#back-button {
display : none;
}
}
참고: 이론적으로 두 방식은 완전히 동일하지 않습니다. 향후 확장에서 back 이외의 새 값이 추가되어, 이 아닌 값에 일치할 수 있습니다. 이 경우 boolean 문맥에서 nav-controls를 사용하는 것은 혼동을 줄 수 있습니다. 그러나 "뒤로" 기능은 내비게이션에서 가장 기본적이므로, CSS 워킹 그룹은 명시적 내비게이션 컨트롤만 있고 뒤로 버튼이 없는 UI가 실제로 등장할 것으로 예상하지 않습니다.
눈에 띄게 쉽게 찾을 수 있는 컨트롤이 활성 상태인지 여부는 이 미디어 기능 평가에 영향을 주지 않습니다.
@media (nav-controls: back) { … }
는 계속 일치해야 합니다. 8. 비디오 접두어 기능
일부 사용자 에이전트(예: 많은 TV)는 비디오와 그래픽을 화면 특성이 구분되는 두 개의 "플레인"(bi-plane)에서 렌더링합니다. 비디오 플레인을 설명하기 위한 video 접두어 기능 집합이 제공됩니다.
bi-plane 구현은 반드시 아래 기능에 대해 비디오 플레인 기준으로 값을 반환해야 합니다: video-color-gamut; video-dynamic-range. 다른 모든 기능은 그래픽 플레인 기준 값을 반환해야 합니다.
bi-plane 구현이 아닌 경우, video 접두어 기능과 비접두어 기능의 값이 동일해야 합니다.
8.1. 비디오 색상 디스플레이 품질: video-color-gamut 기능
이름: | video-color-gamut |
---|---|
대상: | @media |
값: | srgb | p3 | rec2020 |
타입: | discrete |
video-color-gamut 미디어 기능은 UA와 출력 장치의 비디오 플레인이 지원하는 색상의 근사 범위를 설명합니다. 즉, UA가 지정된 색상공간의 색상을 받으면 출력 장치가 해당 색상 또는 근접한 색상을 렌더링할 수 있음을 의미합니다.
값과 색상공간 정의는 color-gamut과 동일합니다.
8.2. 비디오 다이내믹 레인지: video-dynamic-range 기능
이름: | video-dynamic-range |
---|---|
대상: | @media |
값: | standard | high |
타입: | discrete |
video-dynamic-range는 UA와 출력 장치의 비디오 플레인이 지원하는 최대 밝기, 색상 깊이, 명암비의 조합을 의미합니다.
지원 값은 dynamic-range와 동일합니다.
9. 스크립팅 미디어 기능
9.1. 스크립팅 지원: scripting 기능
이름: | scripting |
---|---|
대상: | @media |
값: | none | initial-only | enabled |
타입: | discrete |
scripting 미디어 기능은 자바스크립트와 같은 스크립팅 언어가 현재 문서에서 지원되는지 질의하는 데 사용됩니다.
- enabled
- 사용자 에이전트가 페이지의 스크립팅을 지원하며, 현재 문서에서 스크립팅이 문서의 수명 동안 활성화되어 있음을 나타냅니다.
- initial-only
-
사용자 에이전트가 페이지의 스크립팅을 지원하지만,
문서가 처음 로드될 때만 스크립팅이 활성화되고 이후에는 지원되지 않음을 나타냅니다.
예: 인쇄된 페이지, 서버에서 페이지를 렌더링해 거의 정적인 버전을 보내는 프리렌더링 네트워크 프록시 등.
UA가 initial-only를 주장하기 전에 명시적 최소 기준을 정해야 할까요? 기준이 있으면 작성자는 의존할 수 있는 기능을 알 수 있고 스크립트를 맞춰 작성할 수 있습니다. 하지만 기준을 정하는 게 어렵습니다: 너무 낮으면 실제 UA들이 더 많이 지원하더라도 작성자가 실용적으로 의존할 수 있는 기능이 제한될 수 있습니다. 너무 높게 잡으면 로딩 시 스크립팅을 지원하지만 조건/휴리스틱에 따라 제한하는 UA가 제외될 수 있습니다. 보수적으로 정의하면 모든 인라인 스크립트 실행과 DOMContentLoaded 이벤트 발생은 포함될 듯합니다. 하지만 실제로 대부분(혹은 모든) initial-only UA가 외부 스크립트(비동기, defer 포함)도 로드하고 load 이벤트도 발생시킨다면, 작성자가 여기에만 의존하는 것도 실용적이지 않을 수 있습니다. 반면 외부 스크립트 로드와 load 이벤트를 요구하면 Opera mini 등 일부 UA가 시간초과나 휴리스틱에 따라 실행하지 않을 수도 있으니 제외될 수 있습니다. [Issue #503]
- none
- 사용자 에이전트가 이 문서에서 스크립트를 실행하지 않을 것임을 나타냅니다; 스크립팅 언어를 지원하지 않거나, 현재 문서에서 지원이 활성화되어 있지 않은 경우입니다.
일부 사용자 에이전트는 스크립트별 또는 도메인별로 스크립팅 지원을 끌 수 있어, 특정 문서에서 일부만 스크립트를 실행할 수 있습니다. scripting 미디어 기능은 어떤 스크립트가 실행되는지 세밀하게 감지할 수 없습니다. 이런 경우 scripting 값은 문서와 동일 도메인에서 실행 가능한 스크립트가 있으면 enabled 또는 initial-only, 그렇지 않으면 none이어야 합니다.
참고: 향후 CSS 레벨에서는 어떤 스크립트가 실행되는지 더 세밀하게 감지할 수 있도록 이 미디어 기능을 확장할 수 있습니다.
10. 사용자 정의 미디어쿼리
미디어쿼리를 사용하는 문서를 설계할 때, 같은 미디어쿼리를 여러 곳(여러 @import 등)에 사용할 수 있습니다. 같은 미디어쿼리를 반복하면 수정 시 모든 복사본을 동일하게 수정해야 하므로, CSS에서 버그가 생기기 쉽습니다.
이를 완화하기 위해, 이 명세는 사용자 정의 미디어쿼리 정의 방법을 제시합니다. 사용자 정의 미디어쿼리는 더 길고 복잡한 미디어쿼리의 간단한 이름별 별칭입니다. 이렇게 하면 여러 곳에서 사용되는 미디어쿼리를 사용자 정의 미디어쿼리로 할당하여 어디서든 사용할 수 있고, 미디어쿼리를 수정할 때 한 줄만 수정하면 됩니다.
사용자 정의 미디어쿼리는 @custom-media 규칙으로 정의합니다:
@custom-media = @custom-media <extension-name> [ <media-query-list> | true | false ] ;
<extension-name>는 미디어 기능에서 사용할 수 있습니다. 반드시 부울 문맥에서 사용해야 하며, 일반 또는 범위 문맥에서 사용하면 구문 오류입니다. <media-query-list>가 주어지면, 사용자 정의 미디어쿼리는 해당 <media-query-list>가 true면 true, 그렇지 않으면 false로 평가됩니다. true 또는 false를 지정하면, 사용자 정의 미디어쿼리는 각각 true 또는 false로 평가됩니다.
/* --modern은 color 또는 hover를 지원하는 최신 장치를 타겟팅 */
@custom-media --modern ( color), ( hover);
@media ( --modern) and ( width > 1024 px ) {
.a { color : green; }
}
이는 아래와 동등합니다:
@media (( color) or ( hover)) and ( width > 1024 px ) {
.a { color : green; }
}
아래처럼 처리하는 것은 잘못입니다:
@media ( color), ( hover) and ( width > 1024 px ) {
.a { color : green; }
}
@custom-media 규칙은 다른 사용자 정의 미디어쿼리를 참조할 수 있습니다. 하지만 순환 참조는 금지되며, 사용자 정의 미디어쿼리는 자기 자신이나, 직접 또는 간접적으로 자신을 참조하는 다른 사용자 정의 미디어쿼리로 정의될 수 없습니다. 이런 식으로 순환 의존성을 가진 사용자 정의 미디어쿼리를 정의하려 하면, 루프에 속한 모든 사용자 정의 미디어쿼리 정의가 실패해야 합니다.
여러 @custom-media 규칙이 같은 <extension-name>을 선언하면, 진리값은 마지막 선언만 기준이 되며, 같은 <extension-name>의 이전 선언은 모두 무시합니다.
참고: 오류 처리 목적에서, 정의되지 않은 미디어 기능은 false로 평가된 미디어 기능과 다릅니다. 자세한 내용은 Media Queries 4 § 3.2 오류 처리 참고.
@custom-media --narrow-window (max-width: 30em); @media (--narrow-window) { /* 좁은 윈도우 스타일 */ } @media (--narrow-window) and (script) { /* 스크립트 허용 시 특수 스타일 */ } /* 등등 */
10.1. 스크립트 기반 사용자 정의 미디어쿼리
<script> CSS.customMedia.set('--foo', 5); </script> <style> @media (_foo: 5) { ... } @media (_foo < 10) { ... } </style>
11. 사용자 환경설정 미디어 기능
11.1. 페이지에서 움직임 감소를 원하는지 감지: prefers-reduced-motion 기능
이름: | prefers-reduced-motion |
---|---|
대상: | @media |
값: | no-preference | reduce |
타입: | discrete |
prefers-reduced-motion 미디어 기능은 사용자가 시스템에 애니메이션이나 움직임을 최소화하도록 요청했는지 감지하는 데 사용됩니다.
- no-preference
- 사용자가 시스템에 아무런 환경설정(preference)을 알리지 않았음을 의미합니다. 이 키워드 값은 부울 문맥에서 false로 평가됩니다.
- reduce
- 사용자가 인터페이스에서 움직임이나 애니메이션을 최소화해 주기를 원함을 시스템에 알렸음을 의미합니다. 가능하다면 필수적이지 않은 모든 움직임을 제거하는 것이 바람직합니다.
11.2. 페이지에서 투명도 감소를 원하는지 감지: prefers-reduced-transparency 기능
이름: | prefers-reduced-transparency |
---|---|
대상: | @media |
값: | no-preference | reduce |
타입: | discrete |
prefers-reduced-transparency 미디어 기능은 사용자가 시스템에 투명하거나 반투명한 레이어 효과를 최소화하도록 요청했는지 감지하는 데 사용됩니다.
- no-preference
- 사용자가 시스템에 아무런 환경설정(preference)을 알리지 않았음을 의미합니다. 이 키워드 값은 부울 문맥에서 false로 평가됩니다.
- reduce
- 사용자가 인터페이스에서 투명하거나 반투명한 레이어 효과를 최소화해 주기를 원함을 시스템에 알렸음을 의미합니다.
패턴 채우기나 배경 등과 같은 환경설정과 상호작용은 어떻게 이루어질까요? 투명도가 아니지만 형태 인식에 방해가 됩니다.
11.3. 페이지 요소의 색상 대비 증가/감소 요청 감지: prefers-contrast 기능
이름: | prefers-contrast |
---|---|
대상: | @media |
값: | no-preference | less | more | custom |
타입: | discrete |
prefers-contrast 미디어 기능은 사용자가 페이지에서 더 높거나 더 낮은 대비를 요청했는지 감지하는 데 사용됩니다. 예를 들어 인접한 색상 간의 대비 비율을 조정하거나, 요소의 테두리 등을 조정해 시각적으로 더 두드러지게 만들 수 있습니다.
- no-preference
- 사용자가 시스템에 아무런 환경설정(preference)을 알리지 않았음을 의미합니다. 이 키워드 값은 부울 문맥에서 false로 평가됩니다.
- less
- 사용자가 더 낮은 대비의 인터페이스를 원함을 시스템에 알렸음을 의미합니다.
- more
- 사용자가 더 높은 대비의 인터페이스를 원함을 시스템에 알렸음을 의미합니다.
- custom
-
사용자가 특정 색상 조합을 원하지만,
해당 색상에서 유도되는 대비가 more나 less에
해당하지 않을 때를 의미합니다.
참고: 이 값은 강제 색상 모드 사용자 중, 높은/낮은 대비에 해당하지 않는 팔레트를 선택한 경우 일치합니다. § 11.4 강제 색상 모드 감지: forced-colors 기능 참고.
단순
로 고대비 스타일을 적용하는 것은 잘못이며, 사용자가 반대 환경설정을 원할 때도 강제로 고대비가 적용되므로 바람직하지 않습니다.
하지만 고대비/저대비 모두에 대해 시각적 복잡성이나 색상 다양성을 줄이는 것은 흔한 대응입니다.
이런 경우
처럼 more나 less를 명시하지 않고 사용할 수 있습니다.
이럴 때 배경 이미지를 단색으로 바꾸거나,
장식적 그라디언트를 끄거나,
테두리 이미지를 단색 테두리로 바꾸는 등의 작업을 할 수 있습니다.
prefers-contrast: custom도 prefers-contrast: more 및 prefers-contrast: less처럼
부울 문맥에서 true로 평가되므로,
이런 단순화는 강제 색상 모드 사용자에게도 도움이 됩니다.
강제 색상 모드는 팔레트가 제한되므로 시각적 단순화가 필요합니다.
- 많은 사용자가 텍스트와 배경의 대비가 약하면 읽기 어려워 더 높은 대비를 원함.
- 편두통 환자는 강한 대비의 페이지가 시각적으로 고통스러워 저대비를 원함.
- 난독증이 있는 일부는 고대비 텍스트가 읽기 어렵고, 저대비가 더 편안하다고 느낌.
- 환경적 요인(예: 주변 밝기)에 따라 더 높거나 낮은 대비를 선호할 수 있음. § 11.7 사용자 환경설정 자동 처리 참고.
11.4. 강제 색상 모드 감지: forced-colors 기능
이름: | forced-colors |
---|---|
대상: | @media |
값: | none | active |
타입: | discrete |
- active
-
강제 색상 모드가 활성화됨을 나타냅니다.
사용자 에이전트가 페이지에 사용자 지정 제한된 색상 팔레트를 강제 적용합니다.
UA는 CSS 시스템 색상 키워드를 통해 작성자에게 색상 팔레트를 제공합니다.
자세한 내용은 CSS Color Adjust § 3 강제
색상 팔레트 참고.
이는 반드시 더 높은 대비를 선호하는 것을 의미하지는 않습니다. 색상은 사용자의 선호에 맞게 강제 조정되지만, 그 선호가 더 높거나 더 낮은 대비, 또는 그 중간일 수도 있습니다.
forced-colors: active일 때, UA는 사용자가 선택한 강제 색상 팔레트가 특별히 높은/낮은 대비이면 prefers-contrast: more 또는 prefers-contrast: less 중 하나에 일치해야 하며, 그렇지 않으면 prefers-contrast: custom에 일치해야 합니다.
마찬가지로, 사용자가 선택한 강제 색상 팔레트가 prefers-color-scheme에서 설명한 색상 체계에 해당하면, 해당 값도 일치해야 합니다.
- none
- 강제 색상 모드가 활성화되어 있지 않음.
11.5. 밝은/어두운 색상 테마 선호 감지: prefers-color-scheme 기능
이름: | prefers-color-scheme |
---|---|
대상: | @media |
값: | light | dark |
타입: | discrete |
prefers-color-scheme 미디어 기능은 사용자가 페이지에서 밝은/어두운 색상 테마를 원하는지 반영합니다.
- light
- 사용자가 밝은 테마(밝은 배경에 어두운 텍스트)를 선호함을 표시했거나, 별도의 적극적 선호를 표시하지 않은 경우(즉 "웹 기본값"으로 밝은 테마를 받음).
- dark
- 사용자가 어두운 테마(어두운 배경에 밝은 텍스트)를 선호함을 표시한 경우.
참고: 이 기능의 값은 앞으로 더 확장될 수 있습니다 (밝은 색상 테마에 더 적극적 선호를 표현하거나, "세피아" 등 다른 색상 테마 선호를 표현). 따라서 가장 미래 친화적으로 이 미디어 기능을 사용하는 방법은 (prefers-color-scheme: dark) 및 (not (prefers-color-scheme: dark))처럼 부정형을 사용하는 것입니다. 이렇게 하면 새 값이 추가되어도 스타일 블록 중 하나에는 반드시 들어가게 됩니다.
사용자가 환경설정을 표현하는 방식은 다양할 수 있습니다. 운영체제가 노출하는 시스템 전체 설정일 수도 있고, 사용자 에이전트에서 제어하는 설정일 수도 있습니다.
참고: 사용자 환경설정은 매체에 따라 달라질 수도 있습니다. 예: 사용자가 발광 화면에서는 어두운 테마를 선호하지만, 인쇄시에는 밝은 테마를 선호할 수 있습니다 (잉크 절약 및 인쇄 결과상 밝은 배경에 어두운 텍스트가 더 잘 인쇄됨). UA는 이런 차이를 고려해 prefers-color-scheme이 문맥에 맞는 환경설정을 반영하도록 해야 합니다.
만약 미래의 사용자 에이전트가 "선호 없음"과 "진짜로 밝은 화면을 원함"을 구분하고 싶다면, CSSWG에 연락해 논의해 주세요.
11.6. 페이지 로딩 시 데이터 사용량 감소 선호 감지: prefers-reduced-data 기능
이 기능은 지문 채취(fingerprinting)에 사용될 수 있어, 데이터가 제한된 저소득 계층에 편향될 수 있습니다. 이 명세에 프라이버시 및 보안 섹션이 추가되어야 하며, 이 문제를 다뤄야 합니다. [Issue #4832]
이름: | prefers-reduced-data |
---|---|
대상: | @media |
값: | no-preference | reduce |
타입: | discrete |
prefers-reduced-data 미디어 기능은 사용자가 페이지 렌더링 시 데이터 사용량이 적은 대체 콘텐츠를 선호하는지 감지하는 데 사용됩니다.
- no-preference
- 사용자가 시스템에 아무런 환경설정을 알리지 않았음을 의미합니다. 이 키워드 값은 부울 문맥에서 false로 평가됩니다.
- reduce
- 사용자가 가벼운 대체 콘텐츠를 선호함을 표시한 경우를 의미합니다.
사용자가 환경설정을 표현하는 방법은 다양할 수 있습니다. 운영체제가 노출하는 시스템 전체 설정일 수도 있고, 사용자 에이전트에서 제어하는 설정일 수도 있습니다.
참고: 사용자 에이전트는 Save-Data HTTP 요청 헤더를 설정할 때 사용하는 사용자 또는 시스템 환경설정에 따라 이 값을 설정할 수 있습니다.
.image { background-image: url("images/heavy.jpg"); } @media (prefers-reduced-data: reduce) { /* Save-Data: On */ .image { background-image: url("images/light.jpg"); } }
11.7. 사용자 환경설정 자동 처리
사용자 에이전트는 사용자에게 환경설정을 직접 지정할 수 있는 명시적 설정을 제공하거나, 운영체제의 환경설정을 기반으로 판정할 수 있습니다. 또한 사용자 에이전트는 장치, 환경 등에 대한 정보를 바탕으로 사용자의 환경설정을 자동으로 추론할 수도 있습니다. 이런 경우, 사용자가 자동 판정된 환경설정을 옵트아웃(비활성화)하거나 직접 재정의할 수 있는 방법도 함께 제공하는 것이 좋습니다.
예를 들어, 액정 디스플레이는 밝은 환경에서는 화면이 뿌옇게 보이고 읽기 매우 어려울 수 있습니다. 이런 화면과 주변광 센서를 가진 장치는 화면 읽기가 어려운 조건에서 prefers-contrast 값을 more로 자동 전환할 수 있습니다. e-ink 디스플레이는 밝은 낮에도 읽을 수 있으므로 이런 조정을 하지 않아도 됩니다.
반대로, LCD, OLED 등 발광 디스플레이와 주변광 센서를 가진 장치는 조도가 낮은 환경에서는 과도한 대비와 밝기가 방해가 될 수 있으므로 prefers-contrast를 less로, prefers-color-scheme를 dark로 자동 전환할 수 있습니다.
부록 A: 사용 중단된 미디어 기능
아래 미디어 기능은 사용 중단됨입니다. 하위 호환성을 위해 유지되지만, 새 스타일시트를 작성할 때는 적합하지 않으므로 사용해서는 안 됩니다. 사용자 에이전트는 명세대로 지원해야 합니다.
뷰포트(또는 페이지 미디어에서는 페이지 박스) 크기를 질의할 때는 width, height 및 aspect-ratio 미디어 기능을 사용해야 하며, device-width, device-height, device-aspect-ratio는 문서 레이아웃에 사용할 수 있는 공간과 무관하게 장치의 물리적 크기를 참조합니다. device-* 미디어 기능은 모바일 장치 감지에 프록시로 사용되는 경우도 있으나, 대신 스타일링하려는 장치의 특성을 더 잘 나타내는 미디어 기능을 사용하는 것이 좋습니다.
device-width
이름: | device-width |
---|---|
대상: | @media |
값: | <length> |
타입: | range |
device-width 미디어 기능은 출력 장치의 렌더링 표면 너비를 설명합니다. 연속 미디어의 경우, 웹 노출 화면 영역의 너비입니다. 페이지 미디어의 경우, 페이지 시트 크기의 너비입니다.
device-width는 음수 영역에서는 false입니다.
@media (device-width < 800px) { … }
위 예시에서 스타일시트는 길이가 800px 미만인 화면에만 적용됩니다. px 단위는 단위 섹션에서 설명된 논리적 단위입니다.
참고: 장치가 여러 방향(세로/가로)으로 사용될 수 있다면, device-* 미디어 기능은 현재 방향을 반영합니다.
device-height
이름: | device-height |
---|---|
대상: | @media |
값: | <length> |
타입: | range |
device-height 미디어 기능은 출력 장치의 렌더링 표면 높이를 설명합니다. 연속 미디어의 경우, 웹 노출 화면 영역의 높이입니다. 페이지 미디어의 경우, 페이지 시트 크기의 높이입니다.
device-height는 음수 영역에서는 false입니다.
<link rel="stylesheet" media="(device-height > 600px)" />
위 예시에서 스타일시트는 세로 픽셀 높이가 600보다 큰 화면에만 적용됩니다. px 단위는 CSS의 다른 부분과 동일하게 정의됩니다.
device-aspect-ratio
이름: | device-aspect-ratio |
---|---|
대상: | @media |
값: | <ratio> |
타입: | range |
'device-aspect-ratio 미디어 기능은 device-width 미디어 기능 값과 'device-height 미디어 기능 값의 비율로 정의됩니다.
@media (device-aspect-ratio: 16/9) { … } @media (device-aspect-ratio: 32/18) { … } @media (device-aspect-ratio: 1280/720) { … } @media (device-aspect-ratio: 2560/1440) { … }
부록 B: 프라이버시 및 보안 고려사항
이 섹션은 규범적이지 않습니다.
display-mode 미디어 기능은 출처(origin)가 사용자의 로컬 컴퓨팅 환경 일부에 접근할 수 있게 하며, 특히 애플리케이션 매니페스트 display 멤버 [APPMANIFEST]와 함께 사용할 때, 출처(origin)가 사용자 에이전트의 네이티브 UI 일부를 제어할 수 있게 합니다. CSS 미디어쿼리를 통해 스크립트가 웹앱의 display mode를 알 수 있습니다. 공격자는 이러한 경우 애플리케이션이 전체화면으로 표시되는 사실을 이용해 다른 애플리케이션의 UI를 모방할 수 있습니다.
변경사항
이 섹션은 규범적이지 않습니다.
2020-07-31 작업 초안 이후 변경사항
편집상의 변경 및 소소한 명확화 외에도, 다음과 같은 변경 및 추가가 2020-07-31 작업 초안 이후 본 모듈에 적용되었습니다:
-
display-mode를 [APPMANIFEST]에서 채택. (이슈 6343 참고)
-
bi-plane 구현에서 비디오 플레인의 기하에 대해 질의하는 미디어 기능(video-width, video-height, video-resolution)을 제거함. (이슈 5044 참고)
-
prefers-contrast의 값
high
와low
를 more와 prefers-contrast less로 이름 변경. (이슈 2943 참고) -
prefers-contrast와 forced-colors의 상호작용 재작업,
prefers-contrast: forced
폐기 및 custom 도입. (이슈 5433 및 이슈 6036 참고) -
horizontal-viewport-segments 및 vertical-viewport-segments 미디어 기능 추가. (이슈 6234 참고)
-
nav-controls 미디어 기능 추가. (이슈 6234 참고)
-
dynamic-range의 여러 값이 동시에 일치할 수 있도록 변경. (이슈 6793 참고)
2020-07-15 작업 초안 이후 변경사항
다음 추가사항이 2020-07-15 작업 초안 이후 본 모듈에 적용되었습니다:
- inverted-colors에 대한 UA 스타일시트 규칙 추가.
- prefers-contrast: forced 값 추가.
-
light-level
미디어 기능 제거(이는 prefers-contrast와 prefers-color-scheme과 중복됨); 해당 미디어 기능이 원래 반응할 것으로 기대된 요인을 기반으로 UA가 자동으로 추론하는 예시 추가.
2020-06-03 작업 초안 이후 변경사항
다음 추가사항이 2020-06-03 작업 초안 이후 본 모듈에 적용되었습니다:
- 레벨 4의 내용을 본 명세에 병합(이전에는 레벨 4와의 차이만 관리함).
- 소소한 편집적 수정.
2020-03-18 작업 초안 이후 변경사항
다음 추가사항이 2020-03-18 작업 초안 이후 본 모듈에 적용되었습니다:
- video-* 및 dynamic-range 미디어 기능 추가
- 'prefers-color-scheme: no-preference' 제거
최초 공개 작업 초안 이후 변경사항
다음 추가사항이 2020-03-03 최초 공개 작업 초안 이후 본 모듈에 적용되었습니다:
- 문서 내에 알려진 이슈를 인라인으로 강조.
Media Queries Level 4 이후 변경사항
다음 추가사항이 Media Queries Level 4 이후 최초 공개 작업 초안에 적용되었습니다:
- 이전 Media Queries Level 4 초안에서
light-level
, inverted-colors, 사용자 정의 미디어쿼리 섹션 복구. - prefers-reduced-motion, prefers-reduced-transparency, prefers-contrast, prefers-color-scheme, forced-colors 미디어 기능 추가
감사의 글
이 섹션은 규범적이지 않습니다.
이 명세는 W3C 작업 그룹에서 만든 CSS(계단식 스타일시트)에 관한 결과물입니다.
다음 분들의 의견이 Adam Argyle, Amelia Bellamy-Royds, Andreas Lind, Andres Galante, Arve Bersvendsen, Björn Höhrmann, Chen Hui Jing, Chris Lilley, Chris Rebert, Christian Biesinger, Christoph Päper, Elika J. Etemad (fantasai), Emilio Cobos Álvarez, François Remy, Frédéric Wang, Fuqiao Xue, Greg Whitworth, Ian Pouncey, James Craig, Jay Harris, Jinfeng Ma, Kivi Shapiro, L. David Baron, Masataka Yakura, Matt Giuca, Melinda Grant, Michael Smith, Nicholas C. Zakas Patrick H. Lauke, Philipp Hoschka, Rick Byers, Rijk van Geijtenbeek, Rik Cabanier, Roger Gimson, Rossen Atanassov, Sam Sneddon, Sigurd Lerstad, Simon Kissane, Simon Pieters, Steven Pemberton, Susan Lesch, Tantek Çelik, Thomas Wisniewski, Vi Nguyen, Xidorn Quan, Yves Lafon, akklesed, 그리고 張俊芝 이 명세를 개선하는 데 도움을 주었습니다.