CSS 폰트 모듈 레벨 4

W3C 워킹 드래프트,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2024/WD-css-fonts-4-20240201/
최신 공개 버전:
https://www.w3.org/TR/css-fonts-4/
편집자 초안:
https://drafts.csswg.org/css-fonts-4/
이전 버전:
히스토리:
https://www.w3.org/standards/history/css-fonts-4/
피드백:
CSSWG 이슈 저장소
명세 내 인라인
에디터:
Chris Lilley (W3C)
이전 에디터:
John Daggett (초청 전문가)
(애플(Apple Inc.) 전직)
명세 수정 제안:
GitHub 에디터
테스트 스위트:
https://wpt.fyi/results/css/css-fonts/

요약

이 명세서는 기존 CSS Fonts 3 명세의 수정 사항과 추가 기능들을 정의합니다.

CSS는 구조화된 문서(예: HTML 및 XML)를 화면, 인쇄물 등에서 렌더링하는 방법을 기술하는 언어입니다.

이 문서의 상태

이 섹션은 이 문서가 출판된 시점의 상태를 설명합니다. 현행 W3C 출판물 목록과 이 기술 보고서의 최신 버전은 W3C 기술 보고서 색인 https://www.w3.org/TR/에서 확인할 수 있습니다.

이 문서는 CSS 작업 그룹에서 워킹 드래프트권고 트랙을 이용해 공개되었습니다. 워킹 드래프트로 출판되었다고 해서 W3C 및 회원들의 보증을 의미하지 않습니다.

이 문서는 초안 문서이며 언제든지 업데이트, 대체 또는 폐기될 수 있습니다. 진행 중인 작업으로서 이 문서를 인용하는 것은 적절하지 않습니다.

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

이 문서는 2023년 11월 3일 W3C 프로세스 문서의 적용을 받습니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 해당 그룹 산출물에 대한 공개 특허 공개 목록을 유지합니다. 해당 페이지에는 특허 공개 방법도 포함되어 있습니다. 어떤 개인이 필수 청구권이 포함된 특허를 실제로 알고 있다고 판단하면, W3C 특허 정책 6항에 따라 정보를 공개해야 합니다.

다음 기능들은 위험 요소가 있어, CR 기간 중 삭제될 수 있습니다:

“위험”은 W3C 프로세스 용어일 뿐이며, 해당 기능이 실제로 삭제되거나 지연될 위험이 있다는 뜻은 아닙니다. 이는 WG가 기능의 상호운용 구현에 시기가 맞지 않을 수 있다고 판단할 때 제안 권고(Proposed Rec) 단계로의 전환 시, 기능을 별도의 후보 권고(Candidate Rec) 없이 삭제할 수 있도록 표시하는 것입니다.

1. 소개

이 명세서는 CSS3 Fonts 명세([CSS-FONTS-3])에서 설명된 기본 폰트 기능을 포함하고 확장합니다.

1.1. 값 정의

이 명세서는 CSS 속성 정의 관례를 따르며, [CSS2]에서의 값 정의 문법을 사용합니다([CSS-VALUES-3]). 이 명세서에서 정의되지 않은 값 타입들은 CSS Values & Units [CSS-VALUES-3]에서 정의됩니다. 다른 CSS 모듈과의 결합으로 이러한 값 타입의 정의가 확장될 수 있습니다.

속성 정의에 명시된 속성별 값 외에도, 이 명세서에서 정의된 모든 속성은 CSS 범용 키워드도 속성 값으로 허용합니다. 가독성을 위해 반복적으로 명시하지는 않았습니다.

2. 기본 폰트 속성

문자를 렌더링할 때 사용되는 특정 폰트 페이스는 해당 요소에 적용되는 폰트 패밀리와 기타 폰트 속성에 의해 결정됩니다. 이 구조는 각 설정을 독립적으로 변경할 수 있게 해줍니다.

2.1. 폰트 패밀리: font-family 속성

이름: font-family
값: [ <family-name> | <generic-family> ]#
초기값: 사용자 에이전트에 따라 다름
적용 대상: 모든 요소 및 텍스트
상속됨:
백분율: 해당 없음
계산값: 리스트, 각 항목은 문자열 및/또는 <generic-family> 키워드
정식 순서: 문법에 따름
애니메이션 타입: 이산(discrete)
테스트

이 속성은 우선순위가 지정된 폰트 패밀리 이름 또는 일반 패밀리 이름 목록을 지정합니다. 폰트 패밀리는 두께, 너비, 기울기 등이 다양한 여러 페이스 집합을 정의합니다. CSS는 패밀리 이름과 기타 폰트 속성의 조합을 사용하여 개별 페이스를 선택합니다. 이 선택 방식을 사용하면, 디자인 애플리케이션에서 스타일 이름으로 페이스를 선택하는 것과 달리, 폴백이 발생할 때 텍스트 표시의 일정한 규칙성을 어느 정도 보장할 수 있습니다.

구성 값은 대체를 나타내는 쉼표로 구분된 목록입니다. 사용자 에이전트는 패밀리 이름 목록을 순회하여 렌더링할 문자의 글리프를 포함하는 사용 가능한 폰트를 찾을 때까지 반복합니다. (§ 5.3 클러스터 매칭 참고.) 이를 통해 플랫폼별 사용 가능한 폰트의 차이와 개별 폰트의 지원 문자 범위 차이가 허용됩니다.

body {
    font-family: Helvetica, Verdana, sans-serif;
}

Helvetica가 있으면 렌더링에 사용됩니다. Helvetica와 Verdana 둘 다 없으면 일반 폰트 패밀리 sans-serif가 사용됩니다.

폰트 패밀리 이름에는 세 가지 종류가 있으며, 이 중 두 가지를 이 속성에서 사용할 수 있습니다:

<family-name>
폰트 패밀리 이름(예: 위 예시의 Helvetica 또는 Verdana)

이것은 로컬에 설치된 폰트일 수도 있고, 웹 폰트일 수도 있습니다.

<generic-family>
<generic-family> 키워드는 일반 폰트 선택을 나타내며, 지정된 일반 폰트 범주에 속하는 하나 이상의 로컬 설치 폰트의 잠재적 별칭으로 동작합니다. <generic-family>는 작성자의 더 구체적인 폰트 선택이 사용 불가할 때 폴백으로 사용할 수 있습니다.

일반 패밀리는 세 가지 유형이 있습니다:

  1. 모든 유니코드 문자에 적용되며 항상 로컬 설치 폰트와 매칭되는 일반 패밀리. 예: monospaced

  2. 모든 유니코드 문자에 적용되지만, 일부 시스템에서는 로컬 설치 폰트와 매칭되지 않을 수 있는 일반 패밀리. 예: ui-rounded

  3. 문자 시스템에 따라 적용되며, 일부 유니코드 문자 집합에만 적용되고, 일부 시스템에서는 로컬 설치 폰트와 매칭되지 않을 수 있는 일반 패밀리. 예: generic(fangsong)

작성자는 견고함을 높이기 위해 마지막 대안으로 일반 폰트 패밀리를 추가하는 것이 좋으며, 더 구체적인 일반 폰트 패밀리가 있다면 이를 사용하여 개별 폰트 패밀리의 사용 가능 여부에 관계 없이 특정 스타일을 우선시할 수 있습니다.

<generic-family> 키워드는 따옴표로 감쌀 수 없습니다 (따옴표로 감싸면 <family-name>으로 해석됨).

일반 패밀리 키워드 집합은 § 2.1.5 일반 폰트 패밀리에서 정의됩니다.

<system-family-name>
특정 제약이 적용되는 로컬 설치 시스템 폰트입니다. 특히 font-family 속성에서는 사용할 수 없지만, font 단축 속성과 함께 사용할 수 있습니다.

다음 값들은 시스템 폰트를 참조합니다:

caption
캡션 컨트롤(예: 버튼, 드롭다운 등)에 사용되는 폰트
icon
아이콘에 라벨을 지정할 때 사용되는 폰트
menu
메뉴(예: 드롭다운 메뉴 및 메뉴 리스트)에 사용되는 폰트
message-box
다이얼로그 박스에 사용되는 폰트
small-caption
작은 컨트롤을 라벨링할 때 사용되는 폰트
status-bar
윈도우 상태 표시줄에 사용되는 폰트
테스트

2.1.1. <family-name>의 문법

<family-name> = <string> | <custom-ident>+

일반 패밀리나 시스템 폰트 패밀리가 아닌 폰트 패밀리 이름은 <string>로 따옴표를 감싸거나, 따옴표 없이 하나 이상의 <custom-ident> 시퀀스로 지정해야 합니다.

참고: 즉, 따옴표 없는 폰트 패밀리 이름에서는 대부분의 구두점 문자와 토큰 시작의 숫자는 반드시 이스케이프 처리해야 합니다.

이를 보여주기 위해 아래 선언들은 잘못된 예시입니다:
font-family: Red/Black, sans-serif;
font-family: "Lucida" Grande, sans-serif;
font-family: Ahem!, sans-serif;
font-family: test@foo, sans-serif;
font-family: #POUND, sans-serif;
font-family: Hawaii 5-0, sans-serif;

font-family 값 정의에서 미리 정의된 키워드, 또는 CSS 범용 키워드와 혼동될 수 있는 식별자는 허용되지 않습니다.

참고: 만약 폰트 이름이 <generic-family> 이름, 시스템 폰트 이름, 또는 CSS 범용 키워드와 일치한다면 반드시 따옴표로 감싸야 합니다.

이를 보여주기 위해, 아래와 같이 특이한 폰트 패밀리 이름도 따옴표로 감싸면 유효합니다:
font-family: "sans-serif", sans-serif;
font-family: "default", sans-serif;
font-family: "initial", sans-serif;
font-family: "inherit", sans-serif;

식별자 시퀀스를 <family-name>로 지정하면, 계산된 값은 모든 식별자를 공백으로 연결한 문자열로 변환됩니다.

이스케이프 실수를 방지하려면 공백, 숫자 또는 하이픈 이외의 구두점 문자가 포함된 폰트 패밀리 이름은 따옴표로 감싸는 것이 좋습니다:

폰트 패밀리를 따옴표로 감싸면 이스케이프 실수를 방지할 수 있습니다.
body { font-family: "New Century Schoolbook", serif }

<body style="font-family: '21st Century', fantasy">

키워드 값(예: CSS 범용 키워드 inherit이나 <generic-family> 키워드 serif 등)과 동일한 폰트 패밀리 이름은 반드시 따옴표로 감싸 혼동을 방지해야 합니다. 사용자 에이전트는 이러한 키워드를 <family-name> 타입과 일치시키면 안 됩니다.

2.1.2. <generic-family>의 문법

<generic-family> = generic( <custom-ident>+ ) | <string> | <custom-ident>+
최근에 정의된 일반 폰트 패밀리는 함수 문법을 사용해 식별합니다:
body { font-family: "Adobe Fangsong Std R", generic(fangsong), serif}

위 예시에서 첫 번째 선택지는 Fang Song(仿宋) 스타일의 명명된 폰트입니다. 패밀리 이름에 공백이 포함되어 있으므로 따옴표로 감쌉니다. 두 번째는 최근 추가된 스크립트별 일반 폰트로, unicode-range에 따라 실제 설치된 폰트가 없을 수도 있지만, 존재한다면 요청된 스타일의 예가 됩니다. 세 번째는 모든 시스템에서 항상 매칭되는 범용 일반 폰트입니다.

2.1.3. <system-family-name>의 문법

<system-family-name> = caption | icon | menu | message-box | small-caption | status-bar

2.1.4. 페이스와 패밀리의 관계

폰트 패밀리 이름은 폰트 페이스 집합에 부여된 이름만 지정하며, 개별 페이스를 지정하지 않습니다.

예를 들어, 아래 폰트들이 있을 때, Futura는 매칭되지만 Futura Medium은 매칭되지 않습니다:
family and face names
패밀리와 개별 페이스 이름

참고: CSS에서 폰트 선택에 사용되는 속성 정의는 폰트 분류를 정의하려는 목적이 아닙니다. 타입 디자이너가 생각하는 패밀리는 종종 두께(font-weight), 너비(font-width), 기울기(font-style) 같은 표준 축 이외의 축을 따라 페이스가 다양해질 수 있습니다. 패밀리는 해당 패밀리에만 고유한 축을 따라 다를 수 있습니다. CSS 폰트 선택 메커니즘은 대체가 필요할 때 "가장 가까운" 매칭을 결정하는 방법만 제공합니다.

참고: 폰트들을 패밀리로 그룹화하는 방식은 플랫폼 폰트 관리 API에 따라 달라집니다. 예를 들어, Windows GDI API는 패밀리에 네 개의 페이스만 그룹화할 수 있지만, DirectWrite API, Core Text API, 기타 플랫폼들은 다양한 두께, 너비, 기울기를 가진 폰트 패밀리를 지원합니다 (자세한 내용은 부록 A: 플랫폼 폰트 속성을 CSS 속성으로 매핑 참고).

폰트 패밀리 이름이 어떻게 매칭되는지에 대한 정보는 아래 § 5.1 지역화 이름 매칭을 참고하세요.

2.1.5. 일반 폰트 패밀리

일반 폰트 패밀리는 CSS에서 정의된 표준 이름을 가지지만, 시스템에 존재하는 설치된 폰트 패밀리의 별칭입니다. 단, 하나의 일반 폰트 패밀리는 문자 유니코드 범위, 포함 요소의 콘텐츠 언어, 사용자 설정, 시스템 환경 등 다양한 요인에 따라 서로 다른 타입페이스를 조합한 복합 페이스일 수 있습니다. 서로 다른 일반 폰트 패밀리가 동일한 실제 폰트로 매핑될 수도 있습니다.

테스트

참고: 일반 폰트 패밀리는 임의의 <family-name>와 달리 여러 플랫폼에서 널리 구현되는 것이 목적입니다. 플랫폼마다 다른 폰트로 매핑될 수 있습니다. 작성자는 여러 플랫폼에서 특정 디자인을 따르길 원하지만, 구체적인 폰트에는 집착하지 않을 경우 이 일반 패밀리 이름을 사용할 수 있습니다.

사용자 에이전트는 일반 폰트 패밀리마다 해당 패밀리의 특성을 최대한 잘 표현하는 합리적인 기본 선택을 제공해야 하며, 가능한 경우 사용자가 일반 패밀리의 대체 페이스를 선택할 수 있도록 권장합니다.

serif
Serif 폰트는 글리프 끝에 마감선, 플레어/테이퍼 처리된 끝, 또는 실제 세리프(사각 세리프 등)가 있는 글리프를 나타냅니다. Serif 폰트는 일반적으로 비례적으로 간격이 지정됩니다. sans-serif 폰트보다 굵기 차이가 더 두드러지는 경우가 많습니다.

참고: serifsans-serif는 일부 소수 문자 시스템에만 적용됩니다. CSS에서 일반 폰트 패밀리로 사용된 것은 역사적 이유이며, 초창기 웹 개발의 라틴 중심적 성격을 반영합니다. 더 나은 이름은 "modulated"와 "monoline"일 수 있지만, 웹 호환성 문제로 이름을 바꿀 수 없습니다.

CSS에서는 "serif"를 모든 문자 시스템의 폰트에 적용하지만, 실제로는 Mincho(일본어), Sung/Song(중국어), Batang(한국어) 등 각 문자 시스템에서 더 익숙한 이름이 있을 수 있습니다. 아랍어의 경우 Naskh 스타일이 serif에 해당합니다.

serif는 반드시 하나 이상의 매칭된 폰트 페이스와 연결되어야 합니다.

참고: 해당 폰트 페이스의 문자 커버리지는 보장되지 않습니다. 따라서 serif가 매핑된 폰트가 모든 콘텐츠에 사용되지는 않을 수 있습니다.

sample serif fonts
세리프 폰트 샘플
sans-serif
CSS에서 사용하는 sans-serif 폰트의 글리프는 일반적으로 대비가 낮고(수직과 수평 줄기가 거의 같은 두께), 선 끝이 단순하며(플레어나 장식 없음) 보통 비례적으로 간격이 지정됩니다. 두께 차이가 적고 serif보다 단순합니다. CSS에서는 "sans-serif"를 모든 문자 시스템의 폰트에 적용하지만, 실제로는 Gothic(일본어), Hei(중국어), Gulim(한국어) 등 더 익숙한 이름이 있을 수 있습니다.

sans-serif는 반드시 하나 이상의 매칭된 폰트 페이스와 연결되어야 합니다.

참고: 해당 폰트 페이스의 문자 커버리지는 보장되지 않습니다. 따라서 sans-serif 가 매핑된 폰트가 모든 콘텐츠에 사용되지는 않을 수 있습니다.

sample sans-serif fonts
산세리프 폰트 샘플
cursive
Cursive 폰트의 글리프는 일반적으로 스크립트 스타일을 사용하며, 결과적으로 손으로 쓴 펜이나 붓 글씨와 더 유사합니다. CSS에서는 "cursive"를 모든 문자 시스템의 폰트에 적용하지만, Chancery, Brush, Swing, Script 등 폰트 이름이 쓰이기도 합니다.
sample cursive fonts
커서브 폰트 샘플
fantasy
Fantasy 폰트는 주로 장식적이거나 표현적인 폰트로, 장식적 또는 표현적인 글리프를 포함합니다. 실제 문자를 표현하지 않는 Pi나 그림 폰트는 포함하지 않습니다.
sample fantasy fonts
판타지 폰트 샘플
monospace
Monospace 폰트의 유일한 기준은 모든 글리프가 동일한 고정 폭을 가진다는 것입니다. 컴퓨터 코드 샘플에 자주 사용됩니다.

monospace는 반드시 하나 이상의 매칭된 폰트 페이스와 연결되어야 합니다.

참고: 해당 폰트 페이스의 문자 커버리지는 보장되지 않습니다. 따라서 monospace가 매핑된 폰트가 모든 콘텐츠에 사용되지는 않을 수 있습니다.

sample monospace fonts
모노스페이스 폰트 샘플
system-ui
이 일반 폰트 패밀리는 플랫폼에서 기본 UI 폰트(다른 § 2.1.5 일반 폰트 패밀리처럼 복합 폰트일 수 있음)로 텍스트를 렌더링합니다. 크로스 플랫폼 UA는 지원하는 각 플랫폼에서 서로 다른 폰트를 사용해야 합니다. system-ui의 목적은 웹 콘텐츠가 네이티브 OS의 룩앤필과 통합되도록 하는 것입니다.
테스트

실제 사용되는 폰트는 유니코드 커버리지, 콘텐츠 언어 등 다양한 요인에 따라 달라집니다.

다른 일반 폰트 패밀리와 마찬가지로, system-ui에 대해 실제 설치된 폰트로 대체해도 계산된 스타일에는 영향을 주지 않습니다.
<div id="system-text" style="font-family: system-ui"></div>
...
window.getComputedStyle(document.getElementById("system-text")).getPropertyValue("font-family");

위 스크립트는 system-ui가 시스템 UI 폰트 모음으로 확장되는 방식을 알아서는 안 됩니다. 특히, 모든 플랫폼에서 "system-ui"라는 결과가 나와야 합니다.

math
이 폰트 패밀리는 수식 표현에 사용됩니다.

이런 폰트는 계층적 수식 레이아웃에 도움이 되는 추가 데이터(예: OpenType MATH 테이블)를 포함할 수 있습니다. 특히, 수식 조판에 유용한 스타일 및 늘어나는 글리프 변형을 포함할 수 있습니다.

generic(fangsong)
이 폰트 패밀리는 중국어의 Fang Song(仿宋) 타입페이스에 사용됩니다. Fang Song은 Song(serif)과 Kai(generic(kai)) 사이의 중간 형태입니다. 보통 수평선이 기울어져 있고, 끝의 장식이 작으며, 획 두께 변이가 Song 스타일보다 적습니다. Fang Song은 중국 정부 공식 문서에 자주 사용됩니다.

참고: generic(fangsong)이 실제로 설치된 폰트와 매핑되지 않을 수도 있지만, 매핑된다면 Fang Song 스타일의 폰트입니다.

샘플 Fang Song 폰트로 표시된 중국어 텍스트
generic(kai)
이 폰트 패밀리는 간체 및 번체 중국어에 사용됩니다. 중국어 텍스트에 서예 스타일을 제공하는 주요 타입페이스입니다. 손글씨 특징이 뚜렷하게 나타납니다. Kai는 공식 문서와 교과서에 흔히 사용되며, 대만의 공식 문서 대부분은 Kai 전체 텍스트를 사용합니다. Kai는 다른 타입페이스와 조합하여 제목, 참고, 인용, 대화 등 콘텐츠에서 구분이 필요한 부분에도 사용됩니다.

참고: generic(kai)가 실제로 설치된 폰트와 매핑되지 않을 수도 있지만, 매핑된다면 Kai 스타일의 폰트입니다.

샘플 Kai 폰트로 표시된 중국어 텍스트
generic(nastaliq)
이 폰트 패밀리는 우르두어와 카슈미르어의 표준 서체이며, 페르시아어 등 다른 언어 텍스트에도 자주 선호되는 스타일입니다(특히 시 등 문학 장르). 주요 특징은 연결된 글자의 기울어진 기준선, 그리고 기본 글자와 발음 기호 모두에 복잡한 형태와 위치 지정입니다. 많은 글리프와 합자에 독특한 형태가 있습니다. 우르두어, 카슈미르어 등에서는 naskh 스타일로 폴백하면 안 됩니다.

참고: generic(nastaliq)가 실제로 설치된 폰트와 매핑되지 않을 수도 있지만, 매핑된다면 Nastaliq 스타일의 폰트입니다.

السلام علیکم
샘플 Nastaliq 폰트(Noto Nastaliq Urdu)로 표시된 우르두어 텍스트
السلام علیکم
폴백 Naskh 폰트(Scheherazade New)로 표시된 우르두어 텍스트
ui-serif
이 폰트 패밀리는 시스템 UI의 세리프 변형에 사용됩니다. ui-serif의 목적은 웹 콘텐츠가 네이티브 OS의 룩앤필과 통합되도록 하는 것입니다.

참고: ui-serif는 적절한 시스템 폰트가 없는 플랫폼에서는 폰트에 매핑되지 않을 수 있습니다.

sample ui-serif font
macOS Catalina 및 iOS 13의 샘플 ui-serif 폰트: New York
ui-sans-serif
이 폰트 패밀리는 시스템 UI의 산세리프 변형에 사용됩니다. ui-sans-serif의 목적은 웹 콘텐츠가 네이티브 OS의 룩앤필과 통합되도록 하는 것입니다.

참고: ui-sans-serif는 적절한 시스템 폰트가 없는 플랫폼에서는 폰트에 매핑되지 않을 수 있습니다.

sample ui-sans-serif font
macOS Catalina 및 iOS 13의 샘플 ui-sans-serif 폰트: San Francisco
ui-monospace
이 폰트 패밀리는 시스템 UI의 고정폭 변형에 사용됩니다. ui-monospace의 목적은 웹 콘텐츠가 네이티브 OS의 룩앤필과 통합되도록 하는 것입니다.

참고: ui-monospace는 적절한 시스템 폰트가 없는 플랫폼에서는 폰트에 매핑되지 않을 수 있습니다.

sample ui-monospace font
macOS Catalina 및 iOS 13의 샘플 ui-monospace 폰트: SF Mono
ui-rounded
이 폰트 패밀리는 시스템 UI의 라운드 변형에 사용됩니다. ui-rounded의 목적은 웹 콘텐츠가 네이티브 OS의 룩앤필과 통합되도록 하는 것입니다.

참고: ui-rounded 는 적절한 시스템 폰트가 없는 플랫폼에서는 폰트에 매핑되지 않을 수 있습니다.

sample ui-rounded font
macOS Catalina 및 iOS 13의 샘플 ui-rounded 폰트: SF Rounded

2.2. 폰트 두께: font-weight 속성

이름: font-weight
값: <font-weight-absolute> | bolder | lighter
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨:
백분율: 해당 없음
계산값: 숫자, 아래 참조
정식 순서: 문법에 따름
애니메이션 타입: 계산값 타입에 따라 다름
테스트

font-weight 속성은 폰트의 글리프 두께, 검정도 또는 획 두께를 지정합니다.

이 속성은 다음 값들을 허용합니다:

<font-weight-absolute> = [normal | bold | <number [1,1000]>]

각 값의 의미는 다음과 같습니다:

<number [1,1000]>
각 숫자는 이전 값보다 더 진한 두께를 나타냅니다. 1 이상 1000 이하의 값만 유효하며, 그 외 값은 잘못된 값입니다. 숫자 값은 일반적으로 아래와 같이 자주 쓰이는 두께 이름에 대응합니다.
  • 100 - Thin(얇음)
  • 200 - Extra Light (Ultra Light, 매우 얇음)
  • 300 - Light(가벼움)
  • 400 - Normal(보통)
  • 500 - Medium(중간)
  • 600 - Semi Bold (Demi Bold, 준 볼드)
  • 700 - Bold(볼드)
  • 800 - Extra Bold (Ultra Bold, 매우 볼드)
  • 900 - Black (Heavy, 매우 두꺼움)

참고: 폰트 내부적으로 자체 두께 이름 매핑을 제공할 수 있지만, CSS에서는 폰트 내부 매핑을 무시합니다.

normal
400과 동일함.
bold
700과 동일함.
bolder
상속값보다 더 굵은 두께를 지정합니다. § 2.2.1 상대적인 두께 참조.
lighter
상속값보다 더 가벼운 두께를 지정합니다. § 2.2.1 상대적인 두께 참조.

9단계 스케일이 아닌 다른 스케일을 사용하는 폰트 형식은 CSS 스케일에 맞게 매핑되어야 하며, 400은 Regular, Book, Roman 등으로 라벨링된 페이스와, 700은 Bold로 라벨링된 페이스와 대략 일치하도록 해야 합니다. 또는 스타일 이름에서 위 스케일과 대략 일치하는 값을 추론할 수도 있습니다. 스케일은 상대적이므로, 더 큰 두께 값의 페이스는 절대 더 가볍게 표시되면 안 됩니다. 스타일 이름에서 두께를 추론하는 경우, 로케일마다 스타일 이름이 다를 수 있으므로 주의해야 합니다.

2.2.1. 상대적인 두께

bolderlighter 값은 부모 요소의 두께에 상대적인 값을 의미합니다. 계산된 두께는 상속된 font-weight 값을 기준으로 아래 표에 따라 결정됩니다.

상속값 (w) bolder lighter
w < 100 400 변경 없음
100 ≤ w < 350 400 100
350 ≤ w < 550 700 100
550 ≤ w < 750 900 400
750 ≤ w < 900 900 700
900 ≤ w 변경 없음 700

참고: 위 표는 일반/볼드/얇음/굵은 페이스가 있는 폰트 패밀리에서 다음 상대적 bolder/lighter 페이스를 선택하는 것과 같습니다. 특정 요소에 원하는 정확한 두께를 지정하려면 상대값 대신 숫자 값을 사용하는 것이 더 정밀한 제어가 가능합니다.

2.2.2. 없는 두께

대부분의 경우 특정 폰트 패밀리에는 몇 가지 두께만 존재합니다. 지정한 두께의 페이스가 없으면, 가까운 두께의 페이스가 사용됩니다. 일반적으로 볼드 두께는 더 두꺼운 페이스에, 라이트 두께는 더 얇은 페이스에 매핑됩니다. (정확한 정의는 § 5 폰트 매칭 알고리즘 참조)

아래 예시들은 서로 다른 두께에 대해 어떤 페이스가 사용되는지 보여줍니다. 회색은 원하는 두께의 페이스가 없어서, 가까운 두께의 페이스가 사용됨을 나타냅니다.
weight mappings for a family with 400, 700 and 900 weights
400, 700, 900 두께 페이스만 있는 폰트 패밀리의 두께 매핑
weight mappings for a family with 300, 600 weights
300, 600 두께 페이스만 있는 폰트 패밀리의 두께 매핑

대부분의 사용자 에이전트는 폰트에 특정 두께가 있다고 모델링하며, 이는 위의 9단계 스케일 중 하나에 해당하는 경우가 많습니다. 대부분의 폰트에서는 그렇지만, 일부 폰트는 다양한 두께 범위를 지원하도록 설정될 수 있습니다. 이 경우, 사용자 에이전트는 요청된 두께에 가장 가까운 두께의 페이스를 사용합니다 (정확한 알고리즘은 § 5 폰트 매칭 알고리즘 참조). 특히, 다양한 두께를 지원하는 폰트를 사용할 때는 범위 내 각 두께별로 폰트가 존재하는 것처럼 동작해야 합니다. TrueType/OpenType 폰트에서 변형을 사용하는 경우, wght 변형을 통해 다양한 두께를 구현합니다. 소수점 두께도 유효합니다.

타이포그래퍼들은 선호하지 않지만, 실제 볼드 페이스가 없는 패밀리에서는 사용자 에이전트가 볼드 페이스를 합성하는 경우가 많습니다. 폰트 매칭 목적에서는 이러한 페이스도 패밀리 내에 실제로 존재하는 것처럼 취급해야 합니다. 작성자가 이 동작을 명시적으로 막으려면 font-synthesis 속성을 사용할 수 있습니다.

2.3. 글꼴 너비: font-width 속성

이름: font-width
값: normal | <percentage [0,∞]> | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨:
백분율: 해결되지 않음
계산값: 백분율, 아래 참조
정식 순서: 문법에 따름
애니메이션 타입: 계산값 타입에 따라 다름
테스트

font-width 속성은 글꼴 패밀리에서 보통, 압축, 확장 페이스를 선택합니다. 값은 백분율로 지정하거나, 아래 표에서 정의된 백분율로 매핑되는 키워드를 사용할 수 있습니다:

절대 키워드 값 숫자 값
ultra-condensed 50%
extra-condensed 62.5%
condensed 75%
semi-condensed 87.5%
normal 100%
semi-expanded 112.5%
expanded 125%
extra-expanded 150%
ultra-expanded 200%

<percentage [0,∞]> 값은 글리프의 비율 너비를 나타내며, 100%는 "보통" 글리프 너비(글꼴 디자이너가 정의한 값)를 의미합니다. 0% 미만의 값은 잘못된 값입니다.

특정 너비 페이스가 없을 때, 100% 미만 값은 더 좁은 페이스가 있으면 그 페이스로, 없으면 더 넓은 페이스로 매핑됩니다. 반대로 100% 이상 값은 더 넓은 페이스가 있으면 그 페이스로, 없으면 더 좁은 페이스로 매핑됩니다. 일부 글꼴은 다양한 너비 값을 지원할 수 있으며, 요청한 너비 값이 글꼴에서 지원되지 않으면 가장 가까운 지원 값을 사용합니다. 같은 매핑 규칙이 적용됩니다 (정확한 알고리즘은 § 5 글꼴 매칭 알고리즘 참조). TrueType / OpenType 글꼴에서 변형을 지원하는 경우, wdth 변형을 통해 다양한 너비를 구현합니다.

아래 그림은 아홉 개의 font-width 속성 설정이 다양한 개별 너비를 가진 글꼴 패밀리에서 글꼴 매칭에 미치는 영향을 보여줍니다. 회색은 해당 너비의 페이스가 없고 다른 너비로 대체된 경우를 나타냅니다:
width mappings for a family with condensed, normal and expanded faces
압축, 보통, 확장 너비 페이스가 있는 글꼴 패밀리의 너비 매핑

getComputedStyle() 은 값이 어떻게 지정되었든, 또는 키워드가 해당 값에 매핑되었든 관계없이 항상 값을 <percentage>로 직렬화합니다.

2.3.1. 글꼴 너비: font-stretch 레거시 이름 별칭

역사적 이유로, font-stretch 속성이 존재하며, 레거시 이름 별칭이고, font-width와 동일하게 동작합니다.

예를 들어, 아래에서는 레거시 font-stretch가 h1 요소(1단계 제목)에 사용되었습니다.
h1 {font-stretch: condensed; }

해당 제목의 font-width 지정값은 condensed로 설정됩니다.

예를 들어, 아래에서는 font-width가 h1 요소(1단계 제목)에 사용되었습니다.
h1 {font-width: condensed; }

해당 제목의 font-stretch 지정값은 condensed로 설정됩니다.

테스트

사용자 에이전트는 해당 페이스가 없는 글꼴 패밀리(너비 변형 축이 없는 경우)에 대해 압축 또는 확장 페이스를 합성해서는 안 됩니다. 특히, 사용자 에이전트는 해당 페이스를 기하학적으로 늘리거나 줄여서는 안 됩니다.

2.4. 글꼴 스타일: font-style 속성

이름: font-style
값: normal | italic | oblique <angle [-90deg,90deg]>?
초기값: normal
적용 대상: 모든 요소와 텍스트
상속됨:
백분율: 해당 없음
계산값: 지정된 키워드와, 지정된 경우 각도(도 단위)
정식 순서: 문법에 따름
애니메이션 타입: 계산값 타입에 따라; normaloblique 0deg로 애니메이션됨
테스트

font-style 속성은 이탤릭 또는 오블리크 페이스를 선택할 수 있게 해줍니다. 이탤릭 형태는 일반적으로 필기체 느낌이며, 오블리크 페이스는 보통 보통 페이스를 기울인 형태입니다.

Palatino "a"와 Baskerville "N"의 회색 인공 기울임 렌더링과 실제 이탤릭 버전을 비교해보세요:
artificial sloping vs. real italics
인공 기울임과 실제 이탤릭 비교

값의 의미는 다음과 같습니다:

normal
보통 페이스로 분류된 페이스와 매칭되며, 이탤릭이나 오블리크가 아닌 페이스입니다. 이는 oblique 값 "0"을 의미합니다.
italic
이탤릭 페이스로 라벨링된 폰트와 매칭되며, 없으면 오블리크 페이스와 매칭됩니다.
oblique <angle [-90deg,90deg]>?
오블리크 페이스 매칭을 제어합니다. 양수 각도는 시계 방향 기울임, 음수 각도는 반시계 방향 기울임을 의미합니다. <angle>이 없으면 14deg로 간주합니다. (글꼴 내부적으로 "oblique" 매핑을 제공할 수 있지만, CSS에서는 무시됩니다.) 소수점 및 음수 값도 허용되지만, -90deg 미만 또는 90deg 초과 값은 잘못된 값입니다. 오블리크 페이스가 없고 font-synthesis-style 값이 auto이면, 합성 오블리크 페이스가 생성됩니다.

글꼴 패밀리는 이탤릭/오블리크 페이스가 아예 없거나, 이탤릭만 있거나, 오블리크만 있거나, 둘 다 있거나, 다양한 각도의 여러 오블리크 페이스가 있거나, 여러 조합일 수 있습니다. 글꼴 매칭 루틴은 요청한 각도의 부호가 맞는 폰트를 선택하고, (여러 페이스가 있으면) 요청 각도에 가장 가까운 페이스를 선택합니다. 일반적으로 11deg 이상 각도를 요청하면 더 큰 각도 선호, 그 외에는 더 작은 각도 선호합니다. (자세한 알고리즘은 § 5 글꼴 매칭 알고리즘 참조) TrueType/OpenType 폰트의 변형에서는 slnt 변형으로 오블리크 값을, ital 변형(값 1)으로 이탤릭 값을 구현합니다.

참고: OpenType slnt 축은 양수 각도가 반시계 방향 기울임을 뜻하며, CSS와는 반대 방향입니다. CSS 구현에서는 변형을 사용할 때 이 점을 고려하여 오블리크 페이스를 생성합니다.

양수/음수 오블리크가 수직 쓰기 모드에서 어느 방향으로 기울여져야 할까요? 반대 차원(수직 쓰기 시 필요)으로 기울이는 방법은?

이탤릭/오블리크 페이스가 없으면, 오블리크 페이스는 보통 페이스를 인공적으로 기울여 합성할 수 있습니다. 이러한 인공 오블리크 페이스 사용은 font-synthesis 속성으로 비활성화할 수 있습니다.

참고: 오블리크 페이스는 보통 글리프를 인공적으로 기울여 시뮬레이션할 수 있지만, 이는 진짜 오블리크와는 다릅니다. 실제 오블리크는 기울기에도 시각적 획 두께가 제대로 유지됩니다. 합성 버전보다 실제 오블리크 폰트를 사용하는 것이 항상 더 낫습니다.

글꼴 매칭 목적에서는 사용자 에이전트가 italicoblique의 동의어로 취급할 수 있습니다. 이 값을 구분하는 UA에서는 italic에 대해 합성하지 않아야 합니다.

참고: 합성 방식은 키릴 문자처럼 이탤릭 형태가 완전히 다른 스크립트에는 적합하지 않을 수 있습니다. 합성 버전보다 실제 이탤릭 폰트를 사용하는 것이 항상 더 낫습니다.

참고: 많은 스크립트에는 보통 페이스에서 필기체를 혼합하는 전통이 없습니다. 중국어, 일본어, 한글 폰트는 거의 항상 이탤릭/오블리크 페이스가 없습니다. 여러 스크립트를 지원하는 폰트는 이탤릭 페이스에서 아랍어 등 특정 스크립트를 생략할 수도 있습니다. UA는 글꼴 합성 구현 시 페이스 간 문자 맵 가정에 주의해야 하며, 패밀리 내 이탤릭 페이스는 로마체 페이스와 문자 맵이 다를 수 있습니다.

2.5. 글꼴 크기: font-size 속성

이름: font-size
값: <absolute-size> | <relative-size> | <length-percentage [0,∞]> | math
초기값: medium
적용 대상: 모든 요소와 텍스트
상속됨:
백분율: 부모 요소의 글꼴 크기를 참조
계산값: 절대 길이
정식 순서: 문법에 따름
애니메이션 타입: 계산값 타입에 따라 다름
테스트

이 속성은 글꼴에서 글리프의 원하는 높이를 나타냅니다. 스케일 가능한 글꼴은 font-size가 글꼴의 EM 단위에 적용되는 배율입니다. 비스케일 글꼴은 font-size가 절대 단위로 변환되어, 글꼴의 선언된 크기와 같은 절대 좌표 공간에서 매칭됩니다.

참고: 글리프가 EM 박스에 얼마나 꼭 맞아야 하는지는 요구되지 않습니다. 각 글꼴은 같은 font-size로 렌더링될 때 시각적 크기가 다를 수 있습니다. 또한 글리프가 EM 박스 밖에 임의로 렌더링될 수도 있고, 컨테이닝 블록을 넘치면 잉크 오버플로우를 유발할 수 있습니다.

값의 의미는 다음과 같습니다:

<absolute-size>
<absolute-size> 키워드는 사용자 에이전트가 계산하고 유지하는 글꼴 크기 테이블의 항목을 참조합니다. § 2.5.1 절대 크기 키워드 매핑 테이블 참고.

가능한 값:

[ xx-small | x-small | small | medium | large | x-large | xx-large | xxx-large ]
<relative-size>
<relative-size> 키워드는 부모 요소의 계산된 font-size와 글꼴 크기 테이블을 기준으로 해석됩니다. 가능한 값:
[ larger | smaller ]

부모 요소가 절대 크기 키워드 매핑 테이블의 키워드 글꼴 크기를 가지면, larger는 다음 항목, smaller는 이전 항목으로 폰트 크기가 계산될 수 있습니다. 예: 부모가 font-size:medium이면, 자식에 larger를 지정하면 font-size:large가 될 수 있습니다.

이전 키워드 테이블의 다음/이전 항목 대신, UA는 간단한 비율로 부모 요소에 대해 폰트 크기를 늘리거나 줄일 수도 있습니다. 구체적인 비율은 미정이나, 대략 1.2~1.5 사이여야 합니다. 이 비율은 요소마다 다를 수 있습니다.

참고: 시각 장애 사용자는 더 큰 비율을 요청할 수 있어, 가독성에 도움이 됩니다. UA는 단락 텍스트와 제목 텍스트를 구분해 다른 비율을 사용할 수도 있습니다.

<length-percentage [0,∞]>
길이 값은 UA의 글꼴 테이블과 무관하게 절대 글꼴 크기를 지정합니다. 음수 길이는 잘못된 값입니다.

백분율 값은 부모 요소의 계산된 font-size에 대해 절대 글꼴 크기를 지정합니다. 음수 백분율은 잘못된 값입니다.

참고: 백분율 또는 글꼴 상대 길이(em, rem 등)를 사용하면 스타일시트가 더 견고하고 계단식 적용이 잘 됩니다.

math
수학적 스케일링 규칙을 적용해 font-size의 계산값을 결정해야 합니다.
아래 스타일시트는 글꼴 크기를 지정하는 다양한 방법을 보여줍니다.
p { font-size: 12pt; }
blockquote { font-size: larger }
em { font-size: 150% }
em { font-size: 1.5em }

참고: 이 속성의 사용 값은 font-size-adjust 때문에 계산값과 다를 수 있습니다. 하지만 자식 요소는 font-size 계산값을 상속받으며, 이 값은 font-size-adjust에 영향을 받지 않습니다(그렇지 않으면 font-size-adjust 효과가 누적될 수 있음).

특정 글꼴 크기 사용 불가로 인해 이 속성의 실제 값이 사용 값과 다를 수 있습니다.

font-size는 반응형 타이포그래피에 맞게 clamp로 제한할 수 있습니다.
font-size: clamp(10px, ..., 36px);

2.5.1. 절대 크기 키워드 매핑 테이블

아래 표는 사용자 에이전트가 절대 크기 스케일링 팩터 및 HTML 제목/절대 글꼴 크기와의 매핑에 대해 참고할 수 있는 가이드라인을 제공합니다. medium 값이 기준 중간값으로 사용됩니다. 사용자 에이전트는 다양한 글꼴 또는 다른 디스플레이 장치 유형에 맞게 이 값들을 미세 조정할 수 있습니다.

CSS 절대 크기 값 xx-small x-small small medium large x-large xx-large xxx-large
스케일링 팩터 3/5 3/4 8/9 1 6/5 3/2 2/1 3/1
HTML 제목 h6 h5 h4 h3 h2 h1
HTML font 크기 1 2 3 4 5 6 7

참고: CSS1에서는 인접 인덱스 간 권장 스케일링 팩터가 1.5였으며, 이는 사용자 경험상 너무 컸습니다. CSS2에서는 컴퓨터 화면에서 인접 인덱스 간 권장 스케일링 팩터가 1.2였는데, 작은 크기에서 문제가 있었습니다. 새로운 스케일링 팩터는 각 인덱스마다 달라져 가독성이 더 좋아집니다.

가독성을 유지하려면, 이 가이드라인을 적용하는 UA는 글꼴 크기가 EM 단위당 9 기기 픽셀 미만이 되지 않도록 해야 합니다.

2.6. 상대적 크기 조정: font-size-adjust 속성

이름: font-size-adjust
값: none | <number [0,∞]>
초기값: none
적용 대상: 모든 요소와 텍스트
상속됨:
백분율: N/A
계산값: 숫자 또는 키워드 none
정식 순서: 문법에 따름
애니메이션 타입: 계산값 타입에 따라 다름
테스트

임의의 글꼴 크기에서 텍스트의 시각적 크기와 실질적 가독성은 글꼴마다 다릅니다. 라틴, 키릴 문자 등 대소문자를 구분하는 2자체 스크립트에서는 소문자 높이(x-height)가 대문자와 비교해 얼마나 되는지가 가독성의 주요 요인입니다. 이를 흔히 aspect value(자체값)이라 하며, 글꼴의 x-height를 글꼴 크기로 나눈 값입니다.

참고: 발음 기호(디아크리틱)를 사용하는 텍스트에서, x-height가 너무 크면 발음 기호가 좁아져 오히려 가독성이 떨어질 수 있습니다.

글꼴 폴백이 발생할 때, 폴백 글꼴의 자체값이 원하는 글꼴 패밀리와 다를 수 있어, 가독성이 떨어질 수 있습니다. font-size-adjust 속성은 폰트 폴백 시 텍스트의 가독성을 유지하는 방법입니다. 이 속성은 글꼴이 무엇이든 x-height가 동일하도록 글꼴 크기를 조정합니다.

아래 스타일은 Verdana를 원하는 글꼴 패밀리로 정의하지만, Verdana가 없으면 Futura 또는 Times가 사용됩니다. 일부 단락은 font-size-adjust도 지정되어 있습니다.
p {
  font-family: Verdana, Futura, Times;
}
p.adj {
  font-size-adjust: 0.545;
}

<p>Lorem ipsum dolor sit amet, ...</p>
<p class="adj">Lorem ipsum dolor sit amet, ...</p>

Verdana는 자체값이 0.545로 상대적으로 높아, 소문자가 대문자에 비해 키가 크므로, 작은 크기에서도 텍스트가 잘 읽힙니다. Times는 자체값이 0.447로 낮아, 폴백 시 font-size-adjust를 지정하지 않으면 작은 크기에서 Verdana보다 가독성이 떨어집니다.

아래는 각 글꼴로 렌더링한 텍스트 비교입니다. 각 열은 Verdana, Futura, Times로 렌더링한 텍스트를 보여줍니다. 각 행에서 font-size 값은 동일하며, 빨간 선으로 x-height 차이를 표시했습니다. 윗부분은 각 행마다 동일한 font-size 값으로 렌더링됩니다. 아래 부분도 마찬가지지만, 아래쪽은 font-size-adjust 속성을 0.545로 설정해 실제 글꼴 크기가 각 행에서 Verdana의 x-height를 유지하도록 조정됩니다. 아래쪽 행에서는 작은 텍스트도 행마다 상대적으로 잘 읽힌다는 점에 주목하세요.

text with and without 'font-size-adjust'
font-size-adjust 사용 여부에 따른 텍스트

이 속성은 작성자가 요소에 aspect value를 지정해, 첫 번째 선택 글꼴의 x-height가 대체되든 아니든 효과적으로 유지되게 할 수 있습니다. 각 값의 의미는 다음과 같습니다:

none
글꼴의 x-height를 유지하지 않음.
<number [0,∞]>
아래 계산식에서 사용되는 aspect value를 지정합니다:
c  =  ( a / a' ) s

여기서:

s  =  font-size 값
a  =  aspect value, 'font-size-adjust' 속성에 지정
a' =  실제 폰트의 aspect value
c  =  사용될 조정된 font-size

음수 값은 잘못된 값입니다.

이 값은 선택된 모든 폰트에 적용되지만, 보통 첫 번째 font-family 글꼴의 aspect value를 기준으로 해야 합니다. 이 값이 정확하게 지정되면, 위 공식의 (a/a') 항은 첫 번째 폰트에 대해 1이 되어 조정이 일어나지 않습니다. 값이 부정확하게 지정되면, 첫 번째 폰트로 렌더링된 텍스트는 font-size-adjust를 지원하지 않는 구형 UA에서 다르게 표시될 수 있습니다.

font-size-adjust의 값은 font-size의 사용 값에 영향을 주지만 계산값에는 영향을 주지 않습니다. 글꼴 메트릭을 기반으로 하는 상대 단위(exch 등)의 크기에는 영향을 주지만, em 단위의 크기에는 영향을 주지 않습니다. line-height의 숫자 값은 font-size의 계산값을 참조하므로, font-size-adjustline-height의 사용 값에 영향을 주지 않습니다.

참고: CSS에서 작성자는 line-heightfont-size의 배수로 지정하는 경우가 많습니다. font-size-adjust 속성은 font-size의 사용 값에 영향을 주기 때문에, font-size-adjust를 사용할 때는 line-height 설정에 주의해야 합니다. 줄 간격을 너무 타이트하게 설정하면 이 상황에서 텍스트 줄이 겹칠 수 있습니다.

작성자는 동일한 내용을 가진 span을 서로 다른 font-size-adjust 속성으로 비교함으로써 해당 글꼴의 aspect value를 계산할 수 있습니다. 동일한 font-size를 사용하면 해당 글꼴에 맞는 font-size-adjust 값이 정확할 때 두 span이 일치합니다.

테두리가 있는 두 개의 span을 사용하여 글꼴의 aspect value를 결정합니다. font-size는 두 span에서 동일하지만, 오른쪽 span에만 font-size-adjust 속성이 지정되어 있습니다. 초기값으로 0.5를 시작하여, 두 글자의 테두리가 일치할 때까지 aspect value를 조정할 수 있습니다.

p {
  font-family: Futura;
  font-size: 500px;
}

span {
  border: solid 1px red;
}

.adjust {
  font-size-adjust: 0.5;
}

<p><span>b</span><span class="adjust">b</span></p>
Futura with an aspect value of 0.5
aspect value가 0.5인 Futura aspect value

오른쪽 박스가 왼쪽 박스보다 약간 크므로, 이 글꼴의 aspect value는 0.5보다 작습니다. 박스가 정확히 맞출 때까지 값을 조정하세요.

2.7. 글꼴 단축 속성: font 속성

이름: font
값: [ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-width-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | <system-family-name>
초기값: 개별 속성 참고
적용 대상: 모든 요소와 텍스트
상속됨:
백분율: 개별 속성 참고
계산값: 개별 속성 참고
정식 순서: 문법에 따름
애니메이션 타입: 개별 속성 참고
테스트

이 속성의 문법은 전통적인 타이포그래피 단축 표기법에서 여러 글꼴 관련 속성을 설정하는 데 기반합니다. 역사적 및 하위 호환성 이유로, 거의 단축 속성입니다.

font 속성은, 아래에 설명된 부분을 제외하면, font-style, font-variant, font-weight, font-width, font-size, line-height, font-family 를 스타일시트에서 동일한 위치에 설정하는 단축 속성입니다.

font-variant 속성 값도 포함할 수 있지만, CSS 2.1에서 지원하는 값만 가능합니다. CSS Fonts 3 또는 4에서 추가된 font-variant 값은 font 단축 속성에서 사용할 수 없습니다:

<font-variant-css2>= [normal | small-caps]

font-width 속성 값도 포함할 수 있지만, CSS Fonts 3에서 지원하는 값만 가능합니다. 이 명세서에서 추가된 font-width 값은 font 단축 속성에서 사용할 수 없습니다:

<font-width-css3>= [normal | ultra-condensed | extra-condensed | condensed |
  semi-condensed | semi-expanded | expanded | extra-expanded |
  ultra-expanded]

따라서 글꼴 관련 속성의 분류와 font 속성과의 상호작용은 다음과 같습니다:

명시적으로 설정

아래 속성들은 font 속성으로 설정할 수 있습니다:

암묵적으로 초기화

설정할 수 없지만, 초기값으로 리셋되는 속성:

독립적으로 계단식 적용

font 속성으로 설정하거나 초기화되지 않는 속성:

font 속성의 모든 하위 속성 중 명시적으로 설정암묵적으로 초기화 그룹은 우선 초기값으로 리셋됩니다.

그 후, 명시적으로 설정 그룹 중 font 단축 속성에서 명시적으로 값이 지정된 속성은 해당 값으로 설정됩니다. 허용되는 값과 초기값 정의는 각 개별 속성 정의를 참고하세요.

p { font: 12pt/14pt sans-serif }
p { font: 80% sans-serif }
p { font: x-large/110% "new century schoolbook", serif }
p { font: bold italic large Palatino, serif }
p { font: normal small-caps 120%/120% fantasy }
p { font: condensed oblique 12pt "Helvetica Neue", serif; }
p { font: condensed oblique 25deg 753 12pt "Helvetica Neue", serif; }

두 번째 규칙의 폰트 크기 백분율 값("80%")은 부모 요소의 계산된 font-size를 참조합니다. 세 번째 규칙의 줄 높이 백분율("110%")은 해당 요소의 폰트 크기를 참조합니다.

첫 번째 세 규칙은 font-variantfont-weight를 명시적으로 지정하지 않으므로, 이 속성들은 초기값(normal)을 갖게 됩니다. 폰트 패밀리 이름 "new century schoolbook"은 공백이 포함되어 있으므로 따옴표로 감싸야 합니다. 네 번째 규칙은 font-weightbold로, font-styleitalic로 설정하며, font-variant는 암묵적으로 normal로 설정됩니다.

다섯 번째 규칙은 font-variant (small-caps), font-size (부모 글꼴 크기의 120%), line-height (글꼴 크기의 120%), 그리고 font-family (fantasy)를 설정합니다. 따라서 키워드 normal은 나머지 두 속성인 font-stylefont-weight에 적용됩니다.

여섯 번째 규칙은 font-style, font-width, font-size, font-family를 설정하며, 나머지 글꼴 속성들은 초기값으로 설정됩니다.

일곱 번째 규칙은 font-styleoblique 25deg, font-weight753, font-widthcondensed로 설정합니다. 이 규칙에서 25deg는 반드시 "oblique" 키워드 바로 뒤에 와야 합니다.

font-width 속성은 CSS 2.1에서 정의되지 않았으므로, font-width 값을 font 규칙에서 사용할 때, 작성자는 구형 사용자 에이전트 호환 버전을 추가하는 것이 좋습니다:

p {
  font: 80% sans-serif;   /* 구형 UA용 */
  font: condensed 80% sans-serif;
}

시스템 폰트는 전체적으로만 설정할 수 있습니다. 즉, 폰트 패밀리, 크기, 두께, 스타일 등이 모두 동시에 설정됩니다. 이후 원하는 경우 개별적으로 값들을 변경할 수 있습니다. 만약 해당 특성을 가진 폰트가 플랫폼에 존재하지 않으면, UA는 지능적으로 대체(예: caption 폰트의 더 작은 버전을 small-caption 폰트로 사용할 수 있음)하거나, UA 기본 폰트를 대체로 사용해야 합니다. 일반 폰트의 경우, 시스템 폰트에서 개별 속성이 OS의 사용자 환경설정에 포함되어 있지 않으면, 해당 속성은 초기값으로 설정해야 합니다.

이 속성이 "거의" 단축 속성인 이유는, 시스템 폰트는 이 속성으로만 지정할 수 있고, font-family로는 직접 지정할 수 없기 때문입니다. 그래서 font는 서브속성의 합보다 더 많은 기능을 제공합니다. 단, font-weight 등 개별 속성들은 시스템 폰트에서 가져온 값이 할당되며, 독립적으로 수정할 수 있습니다.

위에 나열된 시스템 폰트에 사용되는 키워드는 처음 위치에 있을 때만 키워드로 취급됩니다. 다른 위치에서는 동일한 문자열이 폰트 패밀리 이름의 일부로 처리됩니다:

font: menu;        /* 시스템 메뉴용 폰트 설정 사용 */
font: large menu;  /* "menu"라는 폰트 패밀리 이름 사용 */
button { font: 300 italic 1.3em/1.7em "FB Armada", sans-serif }
button p { font: menu }
button p em { font-weight: bolder }

특정 시스템의 드롭다운 메뉴에 사용되는 폰트가 예를 들어 9포인트 Charcoal이고, 두께가 600이라면, BUTTON의 하위 P 요소는 아래 규칙이 적용된 것처럼 표시됩니다:

button p { font: 600 9pt Charcoal }

font 단축 속성은 명시적으로 값이 지정되지 않은 속성을 초기값으로 리셋하므로, 아래 선언과 동일한 효과를 가집니다:

button p {
  font-style: normal;
  font-variant: normal;
  font-weight: 600;
  font-size: 9pt;
  line-height: normal;
  font-family: Charcoal
}

2.8. 합성 폰트 페이스 제어

합성 폰트 페이스는 폰트 패밀리에 적합한 페이스가 없을 때, 요청된 폰트를 근사해 제공하기 위한 폴백 전략입니다.

예를 들어, 사용자 에이전트는 다음과 같은 합성을 할 수 있습니다:

합성은 폴백 전략입니다. 최종 결과물이 아무것도 없는 것보다는 나을 수 있지만, 목적에 맞게 디자인된 페이스의 품질 수준에는 도달하지 못합니다.

가변 폰트의 경우, 폰트 디자이너가 하나 이상의 변형 축을 제공했다면 이는 폰트 합성으로 간주되지 않으며, font-synthesis 속성의 영향을 받지 않습니다.

2.8.1. 합성 볼드 제어: font-synthesis-weight 속성

이름: font-synthesis-weight
값: auto | none
초기값: auto
적용 대상: 모든 요소 및 텍스트
상속됨:
백분율: 해당 없음
계산값: 지정된 키워드
정식 순서: 문법에 따름
애니메이션 타입: 불연속
미디어: 시각적
테스트

이 속성은 사용자 에이전트가 폰트 패밀리에 볼드 페이스가 없을 때, 볼드 폰트 페이스를 합성할 수 있는지 제어합니다.

auto
볼드 페이스 합성을 허용
none
볼드 페이스 합성을 허용하지 않음

2.8.2. 합성 오블리크 제어: font-synthesis-style 속성

이름: font-synthesis-style
값: auto | none
초기값: auto
적용 대상: 모든 요소 및 텍스트
상속됨:
백분율: 해당 없음
계산값: 지정된 키워드
정식 순서: 문법에 따름
애니메이션 타입: 불연속
미디어: 시각적
테스트

이 속성은 사용자 에이전트가 폰트 패밀리에 오블리크 페이스가 없을 때, 오블리크 폰트 페이스를 합성할 수 있는지 제어합니다.

auto
오블리크 페이스 합성을 허용
none
오블리크 페이스 합성을 허용하지 않음

수직 텍스트에서는, 양의 오블리크 각도일 때 글리프가 기울어져 line-over 엣지는 line-right 방향으로, line-under 엣지는 line-left 방향으로 이동합니다. 음의 오블리크 각도일 때는 line-over 엣지가 line-left 방향, line-under 엣지가 line-right 방향으로 이동합니다. 기울임 기준은 글리프의 중심입니다.

synthetic oblique in vertical text
수직 텍스트에서 합성 오블리크, 양의 오블리크 각도

2.8.3. 합성 스몰캡스 제어: font-synthesis-small-caps 속성

이름: font-synthesis-small-caps
값: auto | none
초기값: auto
적용 대상: 모든 요소 및 텍스트
상속됨:
백분율: 해당 없음
계산값: 지정된 키워드
정식 순서: 문법에 따름
애니메이션 타입: 불연속
테스트

이 속성은 사용자 에이전트가 폰트 패밀리에 스몰캡스 페이스가 없을 때, 스몰캡스 폰트 페이스를 합성할 수 있는지 제어합니다.

auto
스몰캡스 페이스 합성을 허용
none
스몰캡스 페이스 합성을 허용하지 않음

2.8.4. 합성 위첨자/아래첨자 제어: font-synthesis-position 속성

이름: font-synthesis-position
값: auto | none
초기값: auto
적용 대상: 모든 요소 및 텍스트
상속됨:
백분율: 해당 없음
계산값: 지정된 키워드
정식 순서: 문법에 따름
애니메이션 타입: 불연속
테스트

이 속성은 폰트에 font-variant-position에 해당하는 위첨자/아래첨자 글리프가 없을 때, 사용자 에이전트가 이를 합성해야 하는지 제어합니다.

auto
위첨자/아래첨자 형식 합성을 반드시 수행
none
위첨자/아래첨자 형식 합성을 허용하지 않음

2.8.5. 합성 페이스 제어: font-synthesis 단축 속성

이름: font-synthesis
값: none | [ weight || style || small-caps || position]
초기값: weight style small-caps position
적용 대상: 모든 요소 및 텍스트
상속됨:
백분율: 해당 없음
계산값: 지정된 키워드들
정식 순서: 문법에 따름
애니메이션 타입: 불연속
테스트

이 속성은 font-synthesis-weight, font-synthesis-style, font-synthesis-small-caps, 그리고 font-synthesis-position 속성들의 단축 속성입니다. 값은 다음과 같이 매핑됩니다:

font-synthesisfont-synthesis-weightfont-synthesis-stylefont-synthesis-small-capsfont-synthesis-position
none none none none none
weight auto none none none
style none auto none none
small-caps none none auto none
position none none none auto
weight style auto auto none none
weight small-caps auto none auto none
weight position auto none none auto
style small-caps none auto auto none
style position none auto none auto
small-caps position none none auto auto
weight style small-caps auto auto auto none
weight style position auto auto none auto
weight small-caps position auto none auto auto
style small-caps position none auto auto auto
weight style small-caps position auto auto auto auto
아래 스타일 규칙은 아랍어의 합성 오블리크 사용을 비활성화합니다:
*:lang(ar) { font-synthesis: none; }

3. 글꼴 렌더링 제어

3.1. 글꼴 렌더링 제어 소개

@font-face를 통해 웹 폰트를 다운로드하여 사용할 때, 사용자 에이전트는 폰트가 로딩 중일 때 어떻게 처리할지 알아야 합니다. 대부분의 웹 브라우저는 일정 시간 타임아웃을 적용합니다:

브라우저 타임아웃 폴백 스왑
Chrome 35+ 3초
Opera 3초
Firefox 3초
Internet Explorer 0초
Safari 3초

이러한 기본 동작은 합리적이지만, 브라우저마다 일관성이 부족합니다. 더 나쁜 점은 단일 접근 방식으로는 현대 현행 표준 사용자 경험 및 성능 요구를 모두 충족할 수 없다는 것입니다.

Font Loading API [CSS-FONT-LOADING-3]를 사용하면 개발자가 위 동작 일부를 오버라이드할 수 있지만, 이는 스크립트가 필요하며, 상당한 노력이 들고, 궁극적으로 모든 사례를 커버하기엔 충분하지 않습니다. 또한 개발자는 로딩 스크립트를 인라인하거나 외부 라이브러리를 로드해야 하므로, 폰트가 로딩되기 전 추가 네트워크 지연이 생기고, 텍스트 렌더링이 지연될 수 있습니다.

디자인/성능을 중시하는 웹 개발자는 특정 웹 폰트가 사용자 경험에 얼마나 중요한지 잘 알고 있습니다. 이 명세는 글꼴 타임아웃과 렌더링 동작을 제어할 수 있도록 해줍니다. 즉, 개발자는 다음을 할 수 있습니다:

3.2. 글꼴 표시 타임라인

사용자 에이전트가 특정 다운로드된 폰트 페이스를 페이지에서 처음 사용하려고 시도하는 순간, 폰트 페이스의 폰트 다운로드 타이머가 시작됩니다. 이 타이머는 폰트 페이스와 연관된 세 가지 시간 구간— block 기간, swap 기간, failure 기간— 을 거치며, 해당 폰트 페이스를 사용하는 요소의 렌더링 동작을 결정합니다:

특정 요소에 대해 폴백 폰트 페이스로 렌더링하려면, 사용자 에이전트는 해당 요소의 font-family 목록에서 이미 로드된 첫 번째 폰트 페이스를 찾아, 텍스트 렌더링에 이를 사용해야 합니다. 이 작업은 폴백 폰트 로드를 유발하지 않아야 합니다.

특정 요소에 대해 투명 폴백 폰트 페이스로 렌더링하려면, "폴백 폰트 페이스로 렌더링"에 따라 폰트 페이스를 찾습니다. 선택된 폰트 페이스와 동일한 메트릭을 가진 익명 폰트 페이스를 만들되, 모든 글리프가 "잉크"가 없는(보이지 않는) 상태로, 텍스트 렌더링에 이를 사용합니다. 이 작업은 폴백 폰트 로드를 유발하지 않아야 합니다.

fallbackoptional은 패밀리 내 일부 페이스는 사용되고, 일부는 폴백이 강제되어 '랜섬 노트'처럼 보일 수 있습니다. 패밀리 내 모든 폰트에 동일한 동작(모두 스왑 또는 모두 폴백)을 요구해야 할까요? 폰트 패밀리 단위로 동작 제어는 @font-feature-values도 참고하세요.

4. 폰트 리소스

4.1. @font-face 규칙

@font-face 규칙은 폰트를 연결할 수 있게 해줍니다. 폰트는 필요할 때 자동으로 가져와 활성화됩니다. 이를 통해 작성자는 특정 플랫폼에 설치된 폰트만 사용하는 것이 아니라, 페이지 디자인 목표에 더 잘 맞는 폰트를 선택할 수 있습니다. 폰트 디스크립터 집합은 폰트 리소스의 위치(로컬 또는 외부)와 개별 페이스의 스타일 특성을 정의합니다. 여러 @font-face 규칙을 이용해 다양한 페이스를 가진 폰트 패밀리를 만들 수 있습니다. CSS 폰트 매칭 규칙을 통해 사용자 에이전트는 필요한 텍스트에만 필요한 페이스를 선택적으로 다운로드할 수 있습니다.

문법은 다음과 같습니다:

@font-face {
  <declaration-list>
}
테스트

@font-face 규칙은 이 명세서에서 정의된 디스크립터를 허용합니다.

@font-face 규칙은 모든 폰트 디스크립터에 대해 값을 명시적 또는 암시적으로 지정합니다. 규칙에서 명시적으로 지정하지 않은 값은 각 디스크립터의 초기값을 사용합니다(이 명세서에 명시됨). 이러한 디스크립터는 해당 @font-face 규칙 내에서만 적용되며, 문서 언어 요소에는 적용되지 않습니다. 디스크립터가 어떤 요소에 적용되는지, 값이 자식 요소로 상속되는지 등의 개념은 없습니다. 하나의 @font-face 규칙에 디스크립터가 여러 번 등장하면, 마지막 디스크립터 선언만 사용되고, 앞선 선언들은 모두 무시됩니다.

다운로드 폰트 Gentium 사용 예시:
@font-face {
font-family: Gentium;
src: url(http://example.com/fonts/Gentium.woff);
}

p { font-family: Gentium, serif; }

사용자 에이전트는 Gentium을 다운로드하여 p 요소의 텍스트 렌더링에 사용합니다. 폰트 서버가 사용 불가일 경우 기본 serif 폰트가 사용됩니다.

특정 @font-face 규칙 집합은 해당 규칙을 포함한 문서에서 사용할 수 있는 폰트 집합을 정의합니다. 폰트 매칭 시, 이 규칙으로 정의된 폰트가 시스템의 다른 사용 가능한 폰트보다 먼저 고려됩니다.

다운로드된 폰트는 해당 폰트를 참조하는 문서에서만 사용할 수 있습니다. 이 폰트를 활성화하는 과정에서 다른 애플리케이션이나 해당 폰트를 직접 링크하지 않는 문서에는 사용할 수 없게 해야 합니다. 사용자 에이전트 구현자는 설치된 폰트 폴백 과정의 일부로 다른 문서에서 사용 가능한 폰트가 없을 때 다운로드 폰트를 사용하는 것이 편리할 수 있다고 생각할 수 있습니다. 하지만, 이는 보안상 위험이 있어 한 페이지의 내용이 다른 페이지에 영향을 줄 수 있으므로 공격자가 악용할 수 있습니다. 이러한 제한은 캐싱에는 영향이 없으며, 폰트는 다른 웹 리소스와 동일한 방식으로 캐싱됩니다.

이 at-rule은 CSS의 미래 호환 파싱 규칙을 따릅니다. 선언 블록의 속성처럼, 사용자 에이전트가 지원하지 않는 디스크립터의 선언은 무시되어야 합니다. @font-face 규칙은 font-family와 src 디스크립터를 필요로 하며, 둘 중 하나라도 없으면 @font-face 규칙은 폰트 매칭 알고리즘 수행 시 고려되지 않아야 합니다.

플랫폼 자원이 제한되거나, 다운로드 폰트 리소스 비활성화 기능을 구현한 경우, @font-face 규칙은 단순히 무시되어야 하며, 개별 디스크립터의 동작은 명세된 대로 변경되면 안 됩니다.

4.2. 폰트 패밀리: font-family 디스크립터

이름: font-family
대상: @font-face
값: <family-name>
초기값: N/A

이 디스크립터는 CSS 폰트 패밀리 이름 매칭에 사용될 폰트 패밀리 이름을 정의합니다. 이는 폰트 데이터 내부에 포함된 폰트 패밀리 이름을 오버라이드합니다. 폰트 패밀리 이름이 사용자의 환경에 이미 존재하는 폰트 패밀리 이름과 동일하다면, 해당 스타일시트를 사용하는 문서에서는 내부 폰트가 가려지게 됩니다. 웹 작성자는 사용자 환경에 존재하는 폰트 패밀리 이름과의 충돌을 걱정하지 않고 자유롭게 font-family 이름을 지정할 수 있습니다. 마찬가지로, 플랫폼 대체 폰트 패밀리는 사용되어서는 안 됩니다.

4.3. 폰트 참조: src 디스크립터

이름: src
대상: @font-face
값: <font-src-list>
초기값: N/A

이 디스크립터는 폰트 데이터가 포함된 리소스를 지정합니다. 값은 우선순위가 있는 콤마로 구분된 외부 참조 또는 로컬 설치 폰트 페이스 이름 목록입니다. 폰트가 필요할 때 사용자 에이전트는 나열된 참조를 순회하여 성공적으로 파싱 및 활성화할 수 있는 첫 번째 항목을 사용합니다. 이 디스크립터의 파싱은 다른 디스크립터보다 복잡합니다. 파싱 규칙은 § 4.3.1 src 디스크립터 파싱 참고. 폰트 활성화는 파일을 다운로드 또는 디스크에서 읽고, 파싱하고, 경우에 따라 추가적인 UA 의존 단계가 있을 수 있습니다. 데이터가 잘못된 폰트 또는 찾을 수 없는 로컬 폰트 페이스는 무시되고 목록의 다음 폰트를 UA가 로드합니다.

4.3.1. src 디스크립터 파싱

<font-src-list> 생성식을 파싱하려면, 목록 파싱 규칙을 따라 <font-src> 목록을 파싱합니다.

<font-src> = <url> [ format(<font-format>)]? [ tech( <font-tech>#)]? | local(<family-name>)
<font-format>= [<string> | collection | embedded-opentype | opentype
 | svg | truetype | woff | woff2 ]
<font-tech>= [<font-features-tech> | <color-font-tech>
 | variations | palettes | 
   incremental-patch | incremental-range | incremental-auto ]
<font-features-tech>= [features-opentype | features-aat | features-graphite]
<color-font-tech>= [color-COLRv0 | color-COLRv1 | color-SVG | color-sbix | color-CBDT ]
테스트

폰트 포맷 식별에는 키워드 사용이 권장되지만, 하위 호환성을 위해 아래 문자열도 허용됩니다. 이는 동등한 최신 문법을 사용한 것과 동일한 효과를 냅니다.

문자열 형식 동등 문법
format("woff2") format(woff2)
format("woff") format(woff)
format("truetype") format(truetype)
format("opentype") format(opentype)
format("collection") format(collection)
format("woff2-variations") format(woff2) tech(variations)
format("woff-variations") format(woff) tech(variations)
format("truetype-variations") format(truetype) tech(variations)
format("opentype-variations") format(opentype) tech(variations)
테스트

참고: CSS WG는 이 포맷 문자열 목록을 앞으로 확장할 계획이 없습니다.

컴포넌트 값이 올바르게 파싱되고 UA가 지원하는 폰트 포맷 또는 폰트 기술이라면, 지원 가능한 소스 목록에 추가합니다. 컴포넌트 값 파싱 오류가 발생하거나, 포맷/기술이 지원되지 않는다면, 지원 가능한 소스 목록에 추가하지 않습니다.

이 과정 마지막에 지원 가능한 항목이 없으면, src 디스크립터 값은 파싱 오류입니다.

이 파싱 규칙은 특정 폰트 기술이나 포맷을 지원하지 않는 사용자 에이전트에서도 폰트 폴백이 우아하게 이뤄지도록 해줍니다.

예시: 증분 전송을 지원하지 않는 경우, 폰트의 woff2 압축 버전을 제공해 최적의 성능을 냅니다. 그리고, range-request 방식을 사용하는 증분 전송에는 압축되지 않은 OpenType 폰트를 제공해 클라이언트가 바이트 범위 요청을 할 수 있게 합니다.
@font-face {
  font-family: "MyIncrementallyLoadedWebFont";
  src: url("FallbackURLForBrowsersWhichDontSupportIncrementalLoading.woff2") format("woff2");
  src: url("MyIncrementallyLoadedWebFont.otf") format(opentype)  tech(incremental-range);
}

4.3.2. 개별 src 디스크립터 항목 로딩

CSS 내 다른 URL처럼, URL은 상대경로일 수 있습니다. 이 경우 @font-face 규칙이 포함된 스타일시트 위치를 기준으로 해석됩니다. SVG 폰트의 경우, URL은 SVG 폰트 정의가 포함된 문서 내 요소를 가리킵니다. 요소 참조가 생략되면, 첫 번째로 정의된 폰트가 암시적으로 참조됩니다. 마찬가지로, 여러 폰트를 포함할 수 있는 폰트 컨테이너 포맷은 하나의 @font-face 규칙에 대해 반드시 하나의 폰트만 로딩해야 합니다. 로딩할 폰트는 프래그먼트 식별자(fragment identifier)를 이용해 지정하며, 이는 [RFC8081]에서 정의된 PostScript 이름을 사용합니다.

테스트

현행 표준 준수 UA는 프래그먼트 식별자가 알 수 없거나 지원되지 않으면 해당 폰트 리소스 다운로드를 건너뛰어야 합니다. 예를 들어, OpenType 콜렉션을 지원하지 않는 구형 UA는 목록의 다음 url로 넘어갑니다.

src: url(fonts/simple.woff);       /* simple.woff를 스타일시트 위치 기준으로 로드 */
src: url(/fonts/simple.woff);      /* 절대 경로에서 simple.woff 로드 */
src: url(fonts/coll.otc#foo);      /* coll.otc 컬렉션에서 foo 폰트 로드 */
src: url(fonts/coll.woff2#foo);    /* coll.woff2 woff2 컬렉션에서 foo 폰트 로드 */
src: url(fonts.svg#simple);        /* id가 'simple'인 SVG 폰트 로드 */

4.3.3. src 항목 선택

외부 참조는 URL과 그 URL이 참조하는 폰트 리소스 포맷을 설명하는 선택적 힌트로 구성됩니다. 현행 표준 준수 UA는 포맷 힌트가 미지원/알 수 없는 폰트 포맷을 나타내거나, 폰트 기술 중 어떤 것이든 UA가 지원하지 않는 경우, 해당 폰트 리소스 다운로드를 건너뛰어야 합니다. 포맷 힌트가 없으면, UA는 폰트 리소스를 다운로드해야 합니다.

예시: WOFF 2 폰트를 지원하면 로드, 아니면 WOFF 1, 아니면 OpenType 폰트 사용
@font-face {
font-family: bodytext;
src: url(ideal-sans-serif.woff2) format("woff2"),
    url(ideal-sans-serif.woff) format("woff"),
  url(basic-sans-serif.ttf) format("opentype");
}
이 예시에서 woff2가 지원되지 않으면, 지원하지 않는 가상의 "zebra" 포맷은 건너뛰고 opentype 폰트를 다운로드합니다:
src: url(ideal.woff2) format("woff2"),url(unsupported.zeb) format("zebra"),
url(basic.ttf) format("opentype");
여기서는 컬렉션 내의 개별 인스턴스를 로드하거나, 컬렉션이 지원되지 않으면 개별 폰트를 다운로드합니다.
@font-face {
  font-family: 源ノ角ゴシック Code JP;
  src: url(SourceHanCodeJP.otc#Regular) format("collection"),
    url(SourceHanCodeJP-Regular.ttf) format("opentype");
  }
4.3.3.1. 로컬 폰트 폴백

작성자가 특정 폰트의 로컬 복사본을 우선 사용하고, 없으면 다운로드하고 싶을 때 local()를 사용할 수 있습니다. local()의 로컬 설치 <family-name> 인자는 큰 패밀리 내에서 단일 폰트 페이스를 고유하게 식별하는 포맷별 문자열입니다. 이름은 따옴표로 감쌀 수도 있습니다. 따옴표가 없을 경우, 따옴표 없는 폰트 패밀리 이름 처리 규칙이 적용됩니다; 즉, 이름은 공백으로 구분된 식별자 시퀀스여야 하며, 이 식별자들을 한 칸으로 연결해 문자열로 변환됩니다; 따라서 CSS-wide 키워드 (예: inherit)이나 <generic-family> 키워드(예: serif)는 local() 내에 허용되지 않습니다.

/* Gentium의 일반 페이스 */
@font-face {
font-family: MyGentium;
src: local(Gentium),    /* 로컬 Gentium 우선 사용 */
  url(Gentium.woff);  /* 없으면 다운로드 */
}
예시: local()의 이런 사용은 오류입니다:
@font-face { 
  font-family: foo; 
  src: local(inherit);
}

OpenType 및 TrueType 폰트의 경우, 이 문자열은 로컬 폰트의 name table에서 Postscript 이름 또는 전체 폰트 이름만을 매칭하는 데 사용됩니다. 어떤 이름을 사용할지는 플랫폼과 폰트마다 다르므로, 플랫폼 간 올바른 매칭을 위해 두 이름을 모두 포함하는 것이 좋습니다. 플랫폼 대체(font substitution)는 사용되어서는 안 됩니다.

/* Gentium의 bold 페이스 */
@font-face {
font-family: MyGentium;
src: local(Gentium Bold),    /* 전체 폰트 이름 */
  local(Gentium-Bold),    /* Postscript 이름 */
  url(GentiumBold.woff);  /* 없으면 다운로드 */
font-weight: bold;
}

@font-face 규칙이 패밀리 내의 개별 폰트 특성을 지정하는 것처럼, local()에서 사용하는 고유 이름도 전체 패밀리가 아닌 개별 폰트만 지정합니다. OpenType 폰트 데이터 기준으로, Postscript 이름은 폰트의 name table의 nameID = 6 레코드에 있습니다 (자세한 내용은 [OPENTYPE] 참고). Postscript 이름은 OSX 모든 폰트와 Windows의 Postscript CFF 폰트에서 널리 사용되는 키입니다. 전체 폰트 이름(nameID = 4)은 Windows에서 TrueType 글리프를 가진 폰트의 고유 키로 사용됩니다.

여러 언어 로컬라이즈된 전체 폰트 이름을 가진 OpenType 폰트에서는, 미국 영어 버전(language ID = 0x409/Windows, 0/Macintosh)을 사용해야 하며, 미국 영어 이름이 없으면 첫 번째 로컬라이제이션을 사용해야 합니다 (OpenType 명세는 모든 폰트에 최소한 미국 영어 이름 포함을 권장). 시스템 지역이 네덜란드로 설정된 경우 네덜란드 이름을 매칭하는 등, 다른 전체 폰트 이름을 매칭하는 UA는 비준수로 간주됩니다.

참고: 이는 영어를 선호하기 위한 것이 아니라, 폰트 버전과 OS 로컬라이즈에 따라 매칭 불일치가 발생하는 것을 방지하기 위함입니다. 폰트 스타일 이름(예: "Bold")은 여러 언어로 번역되는 경우가 많고, 로컬라이즈 버전도 플랫폼과 폰트 버전마다 매우 다양하기 때문입니다.

패밀리 이름(nameID = 1)과 스타일 이름(nameID = 2)을 연결해 매칭하는 UA는 비준수로 간주됩니다.

참고: 이 방식은 큰 패밀리 내에서 참조할 수 없는 페이스를 참조할 수 있게 해줍니다.

로컬 폰트 사용 또는 다른 문서의 SVG 폰트 참조:
@font-face {
font-family: Headline;
src: local(Futura-Medium),
  url(images/fonts.svg#MyGeometricModern) format("svg");
}

다른 플랫폼의 일본어 로컬 폰트에 별칭 부여:

@font-face {
font-family: jpgothic;
src: local(HiraKakuPro-W3), local(Meiryo), local(IPAPGothic);
}

큰 패밀리 내에서 매칭할 수 없는 폰트 페이스 참조:

@font-face {
font-family: Hoefler Text Ornaments;
/* Hoefler Text Regular와 동일한 폰트 특성 */
src: local(HoeflerText-Ornaments);
}

로컬라이즈된 fullname은 절대 매칭되지 않으므로, 아래 헤더 스타일 규칙을 가진 문서는 시스템 지역이 핀란드어든 아니든 항상 기본 serif 폰트로 렌더링됩니다:

@font-face {
font-family: SectionHeader;
src: local("Arial Lihavoitu");  /* Arial Bold의 핀란드 fullname, 실패해야 함 */
font-weight: bold;
}

h2 { font-family: SectionHeader, serif; }

아래 예시에서, 현행 표준 준수 UA는 첫 번째 src 디스크립터 정의에 포함된 'gentium.eot'를 절대 로드하지 않습니다. 같은 @font-face 규칙 내 두 번째 정의가 첫 번째 정의를 오버라이드하기 때문입니다:

@font-face {
font-family: MainText;
src: url(gentium.eot);                     /* 구형 UA용 */
src: local("Gentium"), url(gentium.woff);  /* src 정의 오버라이드 */
}

4.4. 폰트 속성 기술자: font-style, font-weight, font-width 기술자

이름: font-style
대상: @font-face
값: auto | normal | italic | oblique [ <angle [-90deg,90deg]>{1,2} ]?
초기값: auto
이름: font-weight
대상: @font-face
값: auto | <font-weight-absolute>{1,2}
초기값: auto
이름: font-width
대상: @font-face
값: auto | <'font-width'>{1,2}
초기값: auto
테스트

이 기술자들은 폰트 페이스의 특성을 정의하며, 스타일을 특정 폰트 페이스에 매칭하는 과정에 사용됩니다. 여러 개의 @font-face 규칙으로 정의된 폰트 패밀리의 경우, 사용자 에이전트는 패밀리 내의 모든 페이스를 다운로드하거나 실제 문서에서 사용되는 스타일에 맞는 폰트 페이스만 선택적으로 다운로드할 수 있습니다. 이 기술자들의 값 의미는 해당 폰트 속성과 동일하나 상대 키워드는 허용되지 않습니다(bolder, lighter 제외). 기술자가 생략된 경우, 초기값이 적용됩니다. 지정된 값이 동일한 이름의 속성에서 허용되는 값의 범위를 벗어나면, 해당 기술자는 파싱 오류로 처리됩니다.

이 세 가지 기술자에는 단일 값 대신 범위 지정도 허용됩니다. 단일 값이 지정된 경우, 시작점과 끝점이 같은 범위와 동일한 의미를 가집니다. 사용자 에이전트는 범위의 시작점과 끝점 값을 교환하여 감소하는 범위를 금지해야 합니다. 두 끝점 모두 포함됩니다. 이 범위들은 아래 폰트 매칭 알고리즘에서 사용됩니다.

테스트

이 세 가지 기술자에 대해 auto 값은 다음과 같은 효과를 가집니다:

이 폰트 페이스 스타일 속성의 값은 기본 폰트 데이터에 의해 암시된 스타일 대신 사용됩니다. 이를 통해 저자는 페이스를 유연하게 조합할 수 있으며, 원래 폰트 데이터가 다르게 배열되어 있더라도 가능합니다. 합성 볼드 및 오블리크 스타일을 구현하는 사용자 에이전트는 폰트 데이터에 의해 암시된 스타일 대신 해당 기술자가 필요함을 암시하는 경우에만 합성 스타일을 적용해야 합니다. 단, '@font-face'로 정의된 폰트에 적용된 변형 값은 기술자에 지정된 값과 폰트 파일에서 지원하는 값 모두에 클램핑됩니다.

이 섹션에서 정의된 폰트 기술자는 @font-face 규칙으로 정의된 폰트 집합 내에서 폰트를 선택하는 데 사용됩니다.

단일, 일반 페이스만 포함된 패밀리를 살펴보면:

@font-face {
  font-family: BaskervilleSimple;
  src: url(baskerville-regular.woff2);
}

스타일이 없는 텍스트는 @font-face 규칙에서 정의된 일반 페이스를 사용하여 표시됩니다:

regular face display

하지만 이탤릭 텍스트는 대부분의 사용자 에이전트에서 별도의 이탤릭 페이스가 정의되어 있지 않으므로, 일반 페이스의 글리프에 합성 오블리크 처리를 하여 표시됩니다:

synthetic italics display

실제 이탤릭 페이스가 정의된 패밀리를 살펴보면:

@font-face {
  font-family: BaskervilleFull;
  src: url(baskerville-regular.woff2);
}

@font-face {
  font-family: BaskervilleFull;
  src: url(baskerville-italic.woff2);
  font-style: italic;
}

두 번째 @font-face 규칙은 폰트 리소스 baskerville-italic.woff에 normal weight, normal stretch, italic 스타일 속성을 부여합니다. 이탤릭 텍스트를 표시할 때, 사용자 에이전트는 이 폰트를 사용하므로 이탤릭 텍스트에 가장 적합한 폰트를 사용하게 됩니다. 따라서, 타입 디자이너가 직접 디자인한 글리프로 표시되며, 일반 페이스의 합성 오블리크 글리프가 아닌 실제 이탤릭 글리프가 사용됩니다:

real italics display

폰트 패밀리 내 특정 페이스 선택 과정에 대한 자세한 내용은 폰트 매칭 섹션을 참고하세요.

폰트는 font-weight, font-width, font-style 범위에 호환됨을 광고할 수 있습니다.
@font-face {
  font-family: Lastima;
  src: url(lastima-varfont.woff2);
  font-weight: 100 399;
}

위의 @font-face 규칙은 lastima-varfont.wofffont-weight가 100~399 사이일 때 사용되어야 함을 나타냅니다. 만약 @font-face 규칙이 font-family: Lastima를 지정한다면, lastima-varfont.wofffont-weight가 100~399 범위를 벗어난 값에도 사용될 수 있습니다. 자세한 내용은 § 5 폰트 매칭 알고리즘을 참고하세요.

위 예시처럼, 여러 @font-face 규칙을 하나의 패밀리로 합쳐 font-weight, font-width, font-style의 여러 범위를 지원할 수 있습니다:

@font-face {
  font-family: Lastima;
  src: url(lastima-varfont-lightrange.woff2);
  font-weight: 100 399;
}
@font-face {
  font-family: Lastima;
  src: url(lastima-varfont-heavyrange.woff2);
  font-weight: 400 700;
}

위의 @font-face 규칙은 lastima-varfont-lightrange.wofffont-weight가 100~399일 때 사용되어야 하며, lastima-varfont-heavyrange.woff는 font-weight가 400~700일 때 사용되어야 함을 의미합니다.

4.4.1. 폰트 폭: font-stretch 레거시 명칭 별칭

역사적 이유로, font-stretch 기술자가 존재하며, 레거시 명칭 별칭으로서 font-width와 동일하게 동작합니다.

4.5. 문자 범위: unicode-range 기술자

이름: unicode-range
대상: @font-face
값: <urange>#
초기값: U+0-10FFFF
테스트

이 기술자는 폰트 페이스가 지원할 수 있는 유니코드 코드포인트 집합을 정의합니다. 기술자 값은 유니코드 범위(<urange>)들의 쉼표로 구분된 목록입니다. 이 범위들의 합집합이 사용자 에이전트가 텍스트 런에 대해 폰트 리소스를 다운로드할지 결정할 때 사용하는 힌트가 됩니다.

<urange> 값은 "U+" 또는 "u+" 접두사 뒤에 아래 세 가지 형식 중 하나로 코드포인트 범위를 표기한 UNICODE-RANGE 토큰입니다. 이 형식에 맞지 않는 범위는 무효이며 선언이 무시됩니다.

단일 코드포인트 (예: U+416)
1~6개의 16진수로 표현된 유니코드 코드포인트
구간 범위 (예: U+400-4ff)
포함 시작점과 끝점 코드포인트를 하이픈(-)으로 구분하여 표현
와일드카드 범위 (예: U+4??)
뒤쪽 '?'가 임의의 16진수임을 뜻하는 코드포인트 집합

개별 코드포인트는 유니코드 문자 코드포인트에 대응하는 16진수로 표기합니다. 유니코드 코드포인트 값은 0~10FFFF까지 허용됩니다. 코드포인트의 숫자 값은 ASCII 대소문자 구분 없음입니다. 구간 범위의 시작점과 끝점은 위 범위 내에 있어야 하며, 끝점이 시작점보다 크거나 같아야 합니다.

'?'로 지정된 와일드카드 범위에서 처음에 숫자가 없는 경우(예: "U+???")도 허용되며, 이는 숫자 0이 붙은 와일드카드와 동일합니다(예: "U+0???" = "U+0000-0FFF"). 유니코드 코드포인트 범위를 넘는 와일드카드 범위는 무효입니다. 때문에, UNICODE-RANGE 토큰이 6개까지 허용하지만, 최대 5개의 '?'만 사용할 수 있습니다.

unicode-range 기술자 선언의 쉼표로 구분된 유니코드 범위 목록은 서로 겹칠 수 있습니다. 이 범위들의 합집합이 해당 폰트가 사용될 수 있는 코드포인트 집합을 정의합니다. 사용자 에이전트는 이 집합에 포함되지 않는 코드포인트에 대해 폰트를 다운로드하거나 사용해서는 안 됩니다. 에이전트는 동일한 코드포인트 집합을 나타내는 다른 목록으로 범위를 정규화할 수도 있습니다.

해당 폰트가 unicode-range 기술자에서 정의한 코드포인트 전체의 글리프를 포함하지 않을 수도 있습니다. 폰트가 사용될 때 유효 문자 맵unicode-range로 정의된 코드포인트와 폰트의 문자 맵의 교집합입니다. 이를 통해 저자는 실제 폰트가 지원하는 정확한 코드포인트 범위에 신경 쓰지 않고도 넓은 범위로 지원 범위를 정의할 수 있습니다.

4.5.1. 문자 범위를 활용한 복합 폰트 정의

서로 다른 unicode-range와 동일한 패밀리 및 스타일 기술자 값을 가진 여러 @font-face 규칙을 사용하여 여러 스크립트에 대해 서로 다른 폰트의 글리프를 혼합하는 복합 폰트를 만들 수 있습니다. 이는 한 스크립트(예: 라틴, 그리스, 키릴)만 포함된 폰트를 결합하는 데 쓰일 수도 있고, 저자가 자주 사용하는 문자와 덜 사용하는 문자별로 폰트를 분리하는 데 사용할 수도 있습니다. 사용자 에이전트는 필요한 폰트만 다운로드하므로 페이지 대역폭이 절감됩니다.

동일한 패밀리 및 스타일 기술자 값을 가진 @font-face 규칙끼리 unicode-range가 겹칠 경우, 규칙은 정의된 역순으로 적용됩니다. 마지막에 정의된 규칙이 우선적으로 해당 문자를 검사합니다.

특정 언어나 문자를 위한 예시 범위:

unicode-range: U+A5;
단일 코드포인트, 엔/위안(¥/元) 기호
unicode-range: U+0-7F;
기본 ASCII 문자 범위
unicode-range: U+590-5ff;
히브리어 문자 범위
unicode-range: U+A5, U+4E00-9FFF, U+30??, U+FF00-FF9F;
일본어 한자, 히라가나, 가타카나 문자 범위 및 엔/위안 기호
BBC는 다양한 언어로 뉴스 서비스를 제공하며, 많은 언어들이 모든 플랫폼에서 잘 지원되지 않습니다. @font-face 규칙을 사용하여 BBC는 이러한 언어에 맞는 폰트를 제공할 수 있습니다. 이미 수동 폰트 다운로드 방식으로 제공 중입니다.

@font-face {
  font-family: BBCBengali;
  src: url(fonts/BBCBengali.woff) format("woff");
  unicode-range: U+00-FF, U+980-9FF;
}
기술 문서에는 다양한 기호가 요구됩니다. STIX Fonts 프로젝트는 표준화된 방식으로 다양한 기술 및 수학 기호를 지원하는 폰트를 제공하는 프로젝트입니다. 아래 예시는 유니코드 내 여러 수학 및 기술 기호 범위의 글리프를 제공하는 폰트 사용법을 보여줍니다:
@font-face {
  font-family: STIXGeneral;
  src: local(STIXGeneral), url(/stixfonts/STIXGeneral.otf);
  unicode-range: U+000-49F, U+2000-27FF, U+2900-2BFF, U+1D400-1D7FF;
}
이 예시는 저자가 일본어 폰트의 라틴 문자 글리프를 다른 폰트의 글리프로 덮어쓰는 방법을 보여줍니다. 첫 번째 규칙은 범위를 지정하지 않아 전체 범위가 기본값으로 사용됩니다. 두 번째 규칙에서 지정된 범위가 겹치지만, 나중에 정의된 규칙이 우선 적용됩니다.
@font-face {
  font-family: JapaneseWithGentium;
  src: local(MSMincho);
  /* 범위 지정 없음, 전체 범위가 기본값 */
}

@font-face {
  font-family: JapaneseWithGentium;
  src: url(../fonts/Gentium.woff);
  unicode-range: U+0-2FF;
}
라틴, 일본어 등 각 문자별로 폰트 파일을 분리해 대역폭을 최적화하는 패밀리 예시:
/* 폴백 폰트 - 크기: 4.5MB */
@font-face {
  font-family: DroidSans;
  src: url(DroidSansFallback.woff);
  /* 범위가 지정되지 않음, 전체 범위로 기본값 설정됨 */
}

/* 일본어 글리프 - 크기: 1.2MB */
@font-face {
  font-family: DroidSans;
  src: url(DroidSansJapanese.woff);
  unicode-range: U+3000-9FFF, U+ff??;
}

/* 라틴어, 그리스어, 키릴 문자를 포함하여 일부
  구두점 및 기호 - 크기: 190KB */
@font-face {
  font-family: DroidSans;
  src: url(DroidSans.woff);
  unicode-range: U+000-5FF, U+1e00-1fff, U+2000-2300;
}

간단한 라틴 텍스트의 경우, 라틴 문자용 폰트만 다운로드됩니다:

body { font-family: DroidSans; }

<p>This is that</p>

이 경우 사용자 에이전트는 먼저 라틴 문자를 포함한 폰트(DroidSans.woff)의 unicode-range를 확인합니다. 위 문자가 모두 U+0-5FF 범위에 있으므로 폰트를 다운로드하고 해당 폰트로 텍스트를 렌더링합니다.

다음은 화살표 문자(⇨)를 사용하는 텍스트 예시:

<p>This &#x21e8; that<p>

사용자 에이전트는 먼저 라틴 문자 폰트의 unicode-range를 확인합니다. U+2000-2300에 화살표 코드포인트(U+21E8)가 포함되므로 폰트를 다운로드합니다. 그러나 라틴 폰트에 해당 글리프가 없으므로 폰트 매칭에 사용되는 유효 unicode-range에서 이 코드포인트는 제외됩니다. 다음으로 일본어 폰트를 평가합니다. 일본어 폰트의 unicode-range(U+3000-9FFF, U+ff??)에는 U+21E8이 포함되지 않으므로 해당 폰트는 다운로드하지 않습니다. 마지막으로 폴백 폰트를 고려합니다. @font-face 규칙은 unicode-range를 정의하지 않았으므로 전체 유니코드 코드포인트 범위가 기본값입니다. 폴백 폰트를 다운로드하여 화살표 문자를 렌더링합니다.

4.6. 폰트 기능 및 변형: font-feature-settingsfont-variation-settings 기술자

이름: font-feature-settings
대상: @font-face
값: normal | <feature-tag-value>#
초기값: normal
테스트
이름: font-variation-settings
대상: @font-face
값: normal | [ <string> <number>]#
초기값: normal
테스트

이 기술자들은 @font-face 규칙으로 정의된 폰트가 렌더링될 때 적용되는 초기 설정을 정의합니다. 폰트 선택에는 영향을 주지 않습니다. 값은 아래에 정의된 font-feature-settingsfont-variation-settings 속성에 정의된 것과 동일하나, CSS-wide 키워드는 제외됩니다. 여러 폰트 기능 기술자, 속성 또는 변형을 사용할 때, 명명된 인스턴스와 함께 사용할 수도 있으며, 텍스트 렌더링에 미치는 누적 효과는 아래 § 7 폰트 기능 및 변형 해석에서 자세히 설명합니다.

이 기술자들은 @font-face 규칙이 나타내는 폰트 객체에 기능 및 변형 값을 설정하며, 전체 요소가 아니라 폰트 객체에 적용됩니다. 따라서 이 기술자를 사용할 때는 § 5.3 클러스터 매칭에 의해, 요소 내 일부 글리프만 해당 기능으로 렌더링될 수 있습니다.

4.7. 가변 폰트의 명명된 인스턴스 사용: font-named-instance 기술자

이름: font-named-instance
대상: @font-face
값: auto | <string>
초기값: auto

font-named-instance 기술자가 auto가 아닌 값으로 설정되면, § 7 폰트 기능 및 변형 해석의 적절한 단계에서 폰트 파일을 검사하여 <string> 값과 동일한 지역화된 이름을 가진 첫 명명 인스턴스를 찾습니다. 해당 인스턴스가 없으면 이 기술자는 auto 값을 가진 것처럼 처리됩니다. 있으면 해당 명명 인스턴스의 변형 축 값이 § 7 폰트 기능 및 변형 해석에서 이 위치에 적용됩니다.

예를 들어, 아래 @font-face 블록은 "Grotesque"라는 인스턴스를 적용하지만 "XHGT" 축은 0.7 값으로 덮어씁니다.
@font-face {
  font-family: "AccuroVar";
  src: url("accurovar.otf") format("opentype");
  font-named-instance: "Grotesque";
  font-variation-settings: "XHGT" 0.7;
}

참고: font-weight, font-width, font-style 속성에 제공된 변형 축 값이 font-named-instance 기술자의 값보다 먼저 적용되므로, 명명된 인스턴스를 사용할 경우 해당 속성 값을 변경할 필요가 없습니다.

4.8. 폰트 요청 가이드라인

4.8.1. 폰트 로딩 가이드라인

@font-face 규칙은 문서 내에서 실제 사용될 때만 폰트 리소스를 지연 로딩(lazy loading)할 수 있도록 설계되었습니다. 스타일시트에는 여러 폰트 라이브러리의 @font-face 규칙을 포함할 수 있지만, 사용자 에이전트는 해당 페이지에 적용되는 스타일 규칙에서 참조되는 폰트만 다운로드해야 합니다. @font-face 규칙에 정의된 모든 폰트를, 실제 페이지에서 사용되는지 여부와 관계없이 다운로드하는 사용자 에이전트는 표준에 부합하지 않습니다. 폰트가 문자 폴백 상황에서 다운로드될 수 있는 경우, 사용자 에이전트는 해당 텍스트 런의 font-family의 계산된 값에 포함된 경우 폰트를 다운로드할 수 있습니다.

@font-face {
  font-family: GeometricModern;
  src: url(font.woff);
}

p {
  /* p 요소가 있는 페이지에서 폰트가 다운로드됨 */
  font-family: GeometricModern, sans-serif;
}

h2 {
  /* h2 요소가 있는 페이지에서, Futura가 로컬에 있어도 폰트가 다운로드될 수 있음 */
  font-family: Futura, GeometricModern, sans-serif;
}

다운로드 가능한 폰트가 준비되기 전에 텍스트 콘텐츠가 먼저 로드되는 경우, 사용자 에이전트는 해당 font-display 기술자에 따라 텍스트를 렌더링해야 합니다. 폰트 다운로드가 실패할 경우, 사용자 에이전트는 텍스트를 시각적으로 표시해야 합니다. 저자들은 페이지 리플로우가 크게 발생하지 않도록 다운로드 폰트와 메트릭이 유사한 폴백 폰트를 폰트 목록에 포함시키는 것이 권장됩니다.

4.8.2. 폰트 가져오기 요구사항

선택된 <url> url@font-face rule이 주어지면 폰트를 가져오기: fetch url을 실행하며, 스타일시트는 rule상위 CSS 스타일시트가 되고, destination은 "font", CORS 모드는 "cors", processResponse는 response res 및 null, 실패 또는 바이트 스트림 stream이 주어졌을 때 다음 단계:
  1. stream이 null이면, 반환한다.

  2. 타입에 따라 stream에서 폰트를 불러온다.

참고: 저자에게 미치는 영향은 폰트가 보통 교차 출처(cross-origin)로 로드되지 않으며, 교차 출처 로드를 허용하려면 저자가 별도로 허용 조치를 해야 한다는 점입니다. 사이트는 Access-Control-Allow-Origin HTTP 헤더를 이용해 폰트 데이터의 교차 사이트 로드를 명시적으로 허용할 수 있습니다. 기타 스킴에서는 fetch 알고리즘이 허용하는 범위 외에 명시적으로 교차 출처 로딩을 허용하는 메커니즘이 정의되거나 요구되지 않습니다.

테스트
아래 예시에서는 문서가 https://example.com/page.html에 위치한다고 가정하며, 모든 URL은 사용자 에이전트가 지원하는 유효한 폰트 리소스를 가리킵니다.

아래 src 기술자 값으로 정의된 폰트는 로드됩니다:

/* 동일 출처 (도메인, 스킴, 포트가 문서와 일치) */src: url(fonts/simple.woff);

/* 리디렉션 없는 data url은 동일 출처로 취급됨 */
src: url("data:application/font-woff;base64,...");

/* 교차 출처, 도메인 다름 */
/* Access-Control-Allow-Origin 응답 헤더가 '*'로 설정됨 */
src: url(http://another.example.com/fonts/simple.woff);

아래 src 기술자 값으로 정의된 폰트는 로드에 실패합니다:

/* 교차 출처, 스킴 다름 *//* 응답에 Access-Control-xxx 헤더 없음 */
src: url(http://example.com/fonts/simple.woff);

/* 교차 출처, 도메인 다름 */
/* 응답에 Access-Control-xxx 헤더 없음 */
src: url(http://another.example.com/fonts/simple.woff);

4.9. 폰트 페이스별 표시 제어: font-display 기술자

font-display 기술자는 @font-face에서 폰트 페이스가 언제, 어떻게 다운로드되어 준비되는지에 따라 표시 방법을 결정합니다.

이름: font-display
대상: @font-face
값: auto | block | swap | fallback | optional
초기값: auto
테스트

참고: 모든 값에 대해 사용자 에이전트는 지속 시간이나 동작을 조금씩 다르게 하거나, font-display 문법으로 직접 표현할 수 없는 고급 동작을 사용할 수 있습니다. 또한, 저자가 선택한 동작보다 더 바람직한 동작으로 사용자가 덮어쓰도록 허용할 수도 있습니다. 예를 들어, 모든 폰트에 대해 0s block period를 강제로 적용할 수 있습니다.

auto
폰트 표시 정책은 사용자 에이전트가 결정합니다.

참고: 많은 브라우저는 block과 유사한 기본 정책을 사용합니다.

block
폰트 페이스에 짧은 block period(대부분 3초 권장)와 무한 swap period를 부여합니다.

참고: 즉, 폰트가 로드되지 않은 경우 브라우저는 처음에 "투명" 텍스트를 그리고, 폰트가 로드되는 즉시 폰트 페이스로 교체합니다.

이 값은 특정 폰트로 텍스트를 렌더링해야지만 페이지 사용이 가능할 때만 사용해야 하며, 작은 텍스트에만 사용해야 합니다.

예를 들어, 잘못 설계된 "아이콘 폰트"는 "⎙"(프린터 아이콘)을 "P" 같은 관련 없는 문자에 할당할 수 있습니다. 폴백 폰트로 표시되면, 원하지 않는 문자가 페이지 곳곳에 나타나 혼란을 줄 수 있습니다. 이 경우 임시로 빈 공간을 만드는 것이 폴백 폰트를 사용하는 것보다 낫습니다.

(단, 결국에는 폴백 폰트가 사용되며, 혼란스러운 문자가 계속 표시되는 것보다는 링크 등이 전혀 표시되지 않는 것보다 낫기 때문입니다.)

더 나은 방법은 접근성 고려사항 섹션에서 설명합니다.

swap
폰트 페이스에 매우 짧은 block period(대부분 100ms 이하 권장)와 무한 swap period를 부여합니다.

참고: 즉, 폰트 페이스가 로드되지 않은 경우 브라우저는 즉시 폴백 폰트로 텍스트를 그리며, 폰트가 준비되는 즉시 교체합니다.

이 값은 특정 폰트로 텍스트를 렌더링하는 것이 매우 중요하지만, 어떤 폰트로 렌더링해도 올바른 메시지를 전달할 수 있을 때만 사용해야 하며, 작은 텍스트에만 사용해야 합니다.

예를 들어, 웹사이트가 로고를 렌더링하기 위해 커스텀 폰트를 사용하는 경우, 로고를 정확하게 렌더링하는 것이 브랜딩에 상당히 중요하지만, 어떤 폰트라도 혼란 없이 전달할 수 있다면 이 옵션을 사용할 수 있습니다.
fallback
폰트 페이스에 매우 짧은 block period(대부분 100ms 이하 권장)와 짧은 swap period(대부분 3초 권장)를 부여합니다.

참고: 즉, 로드되지 않으면 폴백으로 렌더링되며, 로드되는 즉시 교체됩니다. 하지만 시간이 너무 오래 지나면, 폴백 폰트가 페이지 전체 수명 동안 계속 사용됩니다.

이 값은 본문 텍스트나, 선택한 폰트를 사용하는 것이 유용하고 바람직하지만, 사용자가 폴백 폰트로 텍스트를 보는 것이 허용되는 경우에 사용해야 합니다. 많은 양의 텍스트에 적합합니다.

예를 들어, 본문과 같이 많은 양의 텍스트에서는 텍스트를 빠르게 렌더링하여 사용자가 즉시 읽을 수 있게 하는 것이 가장 중요합니다. 또한, 사용자가 읽기 시작한 후에는 새로운 폰트로 교체되어 텍스트가 갑자기 "이동"하는 현상을 방지해야 하며, 이는 집중력을 흐트러뜨리고 다시 위치를 찾아야 하는 불편을 줍니다.
optional
폰트가 "즉시" 로드될 수 있으면(텍스트의 "첫 페인트"에 사용할 수 있을 만큼), 폰트가 사용됩니다.

그렇지 않으면, block periodswap period가 모두 로드 완료 전에 만료된 것처럼 처리됩니다. 이로 인해 폰트가 사용되지 않으면, 사용자 에이전트는 폰트 다운로드를 중단하거나, 매우 낮은 우선순위로 다운로드할 수 있습니다. 사용자에게 유용하다고 판단되면, 폰트 다운로드 자체를 시작하지 않고 바로 폴백 폰트를 사용할 수도 있습니다.

optional 폰트는 로드 중 레이아웃이 "점프"하는 현상을 절대 일으켜서는 안 됩니다. 사용자 에이전트는 optional 폰트 사용 시 로컬 캐시에서 느리게 로드될 수 있으므로 렌더링을 약간 지연시킬 수도 있지만, 폴백 폰트로 그려진 후에는 페이지 전체 수명 동안 optional 폰트로 다시 렌더링해서는 안 됩니다.

이 값은 본문 텍스트나, 선택한 폰트가 단순 장식용인 경우에 사용해야 하며, 웹페이지가 첫 방문 시 빠르게 렌더링되는 것이, 모든 것이 완벽히 즉시 표시되는 것보다 더 중요할 때 사용해야 합니다.

예를 들어, 본문 텍스트는 브라우저 기본 폰트로도 잘 읽히지만, 다운로드 폰트 페이스가 더 예쁘고 사이트의 미관에 더 잘 맞을 수 있습니다. 사이트 첫 방문자는 즉각적으로 사이트를 사용할 수 있는 것이, 세부적인 표시보다 훨씬 더 중요하게 생각하므로 optional이 좋은 동작을 제공합니다. 만약 나중에 다시 방문한다면, 원래 의도한 폰트 페이스가 다운로드를 마쳐 "의도된" 경험을 제공할 수 있습니다.

아주 느린 네트워크 사용자는 "의도된" 경험을 아예 못 받을 수도 있지만, optional 덕분에 실제로 사이트를 사용할 수 있으며, 느려서 사이트를 떠나는 일이 줄어듭니다.

optional 폰트가 텍스트 렌더링에 제때 사용될 가능성을 높이기 위해, 사용자 에이전트가 휴리스틱을 사용하여 접근 속도를 높이거나, 일부 텍스트 렌더링을 지연할지 판단하는 것이 권장됩니다. 예를 들어, 폰트를 HTML에서 프리로드했는지 확인하거나, 스타일시트에서 발견되는 즉시 느린 캐시에서 빠른 메모리 캐시로 옮기는 등의 방법이 있을 수 있습니다 (페이지에서 실제 사용할지 모르더라도).

하지만 저자는 이러한 휴리스틱에 의존할 수 없으며, optional 값은 폰트가 아예 사용되지 않을 수도 있음을 이해해야 합니다. 폰트 사용 가능성을 좀 더 높이고 싶다면, fallback 값을 고려해야 합니다.

4.9.1. 폰트 패밀리별 표시 제어: @font-feature-values 이용

font-display 기술자는 @font-feature-values에서 폰트 패밀리 표시 방법을 결정하며, 해당 폰트 패밀리를 대상으로 하는 @font-face 규칙의 "기본" font-display 값을 설정합니다. @font-face 규칙에서 font-display가 생략되면, 사용자 에이전트는 해당 폰트 패밀리의 font-display 값을 @font-feature-values로 설정된 경우 그 값으로 사용하고, 그렇지 않으면 font-display: auto를 기본값으로 사용합니다.

이 메커니즘은 전체 폰트 패밀리의 표시 정책을 기본값으로 설정하는 데 사용할 수 있으며, 개발자가 직접 관리하지 않는 @font-face 규칙에도 표시 정책을 적용할 수 있게 해줍니다. 예를 들어, 서드파티 폰트 업체가 폰트를 제공하는 경우, 개발자는 @font-face 규칙을 제어할 수 없지만 해당 폰트 패밀리에 대한 기본 표시 정책은 설정할 수 있습니다. 폰트 패밀리 전체에 기본 정책을 설정하면 "랜섬 노트 효과"(즉, 폰트 페이스가 뒤섞임)를 방지하는 데도 유용합니다. 이 정책이 패밀리 전체에 적용되기 때문입니다.

이름: font-display
대상: @font-feature-values
값: auto | block | swap | fallback | optional
초기값: auto

4.10. 기본 폰트 언어 덮어쓰기: font-language-override 기술자

이름: font-language-override
대상: @font-face
값: normal | <string>
초기값: normal

이 기술자는 @font-face 규칙으로 정의된 폰트가 렌더링될 때 적용되는 초기 설정을 정의합니다. 폰트 선택에는 영향을 주지 않습니다. 값은 아래 font-language-override 속성에 정의된 것과 동일하나, inherit 값은 제외됩니다. 여러 폰트 기능 기술자, 속성 또는 변형을 사용할 경우, 텍스트 렌더링에 미치는 누적 효과는 아래 § 7 폰트 기능 및 변형 해석에서 설명합니다.

4.11. 기본 폰트 메트릭 덮어쓰기: ascent-override, descent-overrideline-gap-override 기술자

이름: ascent-override
대상: @font-face
값: normal | <percentage [0,∞]>
초기값: normal
테스트
이름: descent-override
대상: @font-face
값: normal | <percentage [0,∞]>
초기값: normal
테스트
이름: line-gap-override
대상: @font-face
값: normal | <percentage [0,∞]>
초기값: normal
테스트

ascent-override, descent-override, line-gap-override 기술자는 각각 폰트의 ascent metric, descent metric, line gap metric을 정의합니다.

기술자 값이 normal이면, 해당 메트릭 값은 폰트 파일에서 직접 가져옵니다.

참고: 사용자 에이전트는 폰트 파일의 다양한 위치에서 메트릭 값을 가져올 수 있으며, 이로 인해 텍스트 레이아웃이 달라질 수 있습니다.

기술자 값이 백분율일 경우, 해당 메트릭 값은 사용된 폰트 크기에 주어진 백분율을 곱하여 계산합니다. 음수 값은 파싱 시 무효입니다.

백분율은 요소마다 다른 폰트 크기에 따라 계산됩니다.
@font-face {
  font-family: overridden-font;
  ascent-override: 50%;
  ...
}

<span style="font-family: overridden-font; font-size: 20px;">
  Outer span content
  <span style="font-size: 150%;">Inner span content</span>
</span>

외부 span은 ascent 값으로 10px을 사용하며, 내부 span은 15px을 사용합니다.

로컬 폴백 폰트의 메트릭을 웹 폰트와 일치하도록 덮어쓸 수 있습니다. 이렇게 하면 폴백에서 기본 폰트로 전환 시 레이아웃 이동이 줄어듭니다.
@font-face {
  font-family: cool-web-font;
  src: url("https://example.com/font.woff");
}

@font-face {
  font-family: fallback-to-local;
  src: local(Some Local Font);
  /* cool-web-font와 메트릭 값을 맞추기 위해 덮어씀 */
  ascent-override: 125%;
  descent-override: 25%;
  line-gap-override: 0%;
}

<div style="font-family: cool-web-font, fallback-to-local">Title goes here</div>
<img src="https://example.com/largeimage" alt="A large image that you don’t want to shift">

이미지는 사용자 에이전트가 웹 폰트로 전환할 때 수직 이동되지 않습니다.

5. 폰트 매칭 알고리즘

아래 알고리즘은 폰트가 개별 텍스트 런에 어떻게 연관되는지 설명합니다. 런의 각 문자에 대해 폰트 패밀리가 선택되고, 해당 문자의 글리프를 포함하는 특정 폰트 페이스가 선택됩니다.

설치된 폰트의 집합은 폰트 매칭 알고리즘에서 명확히 정의되어 있지 않습니다.

설치된 폰트의 기본 집합은 UA, 플랫폼, 로케일에 따라 달라질 수 있습니다. 사용자가 웹 페이지 렌더링에 사용 가능한 설치된 폰트와 해당 폰트가 매핑되는 일반 폰트 패밀리(있는 경우)를 자유롭게 사용자 지정할 수 있어야 합니다.

UA는 모든 설치된 폰트를 웹에 노출하도록 선택할 수 있으며, 해당 폰트가 어떻게 설치되었는지와 관계없이 이렇게 하면 운영체제에 내장 폰트로 지원되지 않는 주 언어를 사용하는 사용자에게 좋은 국제화 특성을 제공할 수 있습니다.

또는 UA는 웹에서의 프라이버시 보호를 위해 처음에는 사용자 설치 폰트를 노출하지 않을 수도 있습니다. 사용자가 설치한 폰트 집합은 웹 전체에서 사용자를 추적하는 벡터로 자주 활용되기 때문입니다. 사용자는 자신의 필요에 따라 이 집합에서 폰트를 추가하거나 제거할 수 있습니다.

UA는 일부 사용자 설치 폰트만 국제화 목적으로 처음 노출하고, 나머지는 노출하지 않는 하이브리드 방식을 선택할 수도 있습니다. 이 경우에도 사용자가 시작 집합을 직접 커스터마이즈할 수 있습니다.

UA는 국제화와 프라이버시의 균형을 맞추기 위해 기본적으로 어떤 폰트를 웹에 노출할지 신중하게 결정해야 하며, 사용자가 자신의 필요에 맞게 폰트를 추가/제거할 수 있는 편리한 수단도 제공해야 합니다.

테스트

5.1. 로컬라이즈된 이름 매칭

일부 폰트 파일 형식은 특정 문자열(예: 패밀리명 또는 명명 인스턴스)의 여러 지역화 버전을 포함할 수 있습니다. UA는 이러한 모든 이름을 기본 플랫폼 로케일, 시스템 API, 문서 인코딩과 관계없이 인식하고 올바르게 매칭해야 합니다.

예를 들어, 아래 나열된 각 폰트에 대해, 저자는 font-family 속성에서 라틴 이름 또는 지역화된 이름을 사용할 수 있으며, 모든 시스템에서 결과는 동일합니다:
Localized family names 예시
로컬라이즈된 패밀리명

UA는 이러한 이름을 대소문자 구분 없이 매칭해야 하며, 유니코드 사양 [UNICODE]에 기술된 "Default Caseless Matching" 알고리즘을 사용해야 합니다. 이 알고리즘은 3.13 "Default Case Algorithms" 섹션에 자세히 설명되어 있습니다. 구체적으로, 알고리즘은 문자열을 정규화하지 않고, 언어별 맞춤을 적용하지 않고 사용해야 합니다. 이 알고리즘의 케이스 폴딩 방식은 Unicode Character Database의 CaseFolding.txt 파일에서 상태 필드가 "C" 또는 "F"인 케이스 매핑을 사용합니다.

참고: 저자에게 이는 폰트 패밀리 이름이 대소문자 구분 없이 매칭되며, 해당 이름이 플랫폼 폰트에 있든, 스타일시트의 @font-face 규칙에 있든 동일하다는 의미입니다. 저자는 실제 폰트 패밀리 이름의 문자 시퀀스와 일치하도록 이름을 지정해야 하며, 특히 발음 구별 기호와 같은 결합 문자를 사용할 때 주의해야 합니다. 예를 들어, 소문자 a(U+0061) 뒤에 결합 링(U+030A)이 있는 패밀리명은 겉보기엔 같아도 결합 시퀀스 대신 미리 조합된 소문자 a-ring(U+00E5)을 사용할 경우 매칭되지 않습니다.

참고: 구현자는 주어진 대소문자 구분 없는 문자열 비교 구현이 반드시 이 알고리즘을 사용하도록 확인해야 하며, 플랫폼 문자열 매칭 루틴이 이를 따를 것이라 가정해서는 안 됩니다. 많은 플랫폼 API가 로케일별 동작이나 문자열 정규화를 사용하기 때문입니다.

5.2. 폰트 스타일 매칭

텍스트 런의 각 문자에 대해 폰트를 선택하는 절차는 font-family 속성에 명시된 폰트 패밀리를 순회하며, 다른 폰트 속성을 바탕으로 적절한 스타일의 폰트 페이스를 선택하고, 해당 문자에 대한 글리프가 존재하는지 판단하는 과정입니다. 이는 폰트의 character map을 사용해 이루어지며, 이 데이터는 문자를 해당 문자에 대한 기본 글리프에 매핑합니다. 폰트가 특정 문자를 지원한다고 판단하려면 (1) 문자가 폰트의 character map에 포함되어 있어야 하며, (2) 해당 스크립트에서 요구하는 경우, 해당 문자를 위한 셰이핑 정보가 있어야 합니다.

일부 레거시 폰트는 character map에는 문자가 포함되어 있지만 해당 문자로 이루어진 텍스트 런을 올바르게 렌더링하는 데 필요한 셰이핑 정보 (예: OpenType layout tables 또는 Graphite tables) 가 없는 경우도 있습니다.

기본 문자 뒤에 결합 문자가 이어진 코드포인트 시퀀스는 약간 다른 방식으로 처리되며, 아래 클러스터 매칭 섹션을 참고하세요.

이 절차에서, 특정 폰트 패밀리의 기본 페이스는 모든 폰트 스타일 속성이 초기값으로 설정된 경우 선택될 페이스로 정의됩니다.

  1. 주어진 요소의 계산된 폰트 속성 값을 사용하여, 사용자 에이전트는 font-family 속성에 지정된 첫 번째 패밀리명부터 시작합니다.

  2. 패밀리명이 일반 패밀리 키워드일 경우, 사용자 에이전트는 사용할 적절한 폰트 패밀리명을 조회합니다. 사용자 에이전트는 포함 요소의 언어나 문자의 유니코드 범위에 따라 사용할 일반 폰트 패밀리를 선택할 수 있습니다.

  3. 기타 패밀리명의 경우, 사용자 에이전트는 @font-face 규칙에서 정의된 폰트 중에서 패밀리명을 먼저 찾고, 그 다음 사용 가능한 설치된 폰트(폰트 별칭 포함 가능) 중에서 찾으며, 위의 섹션에 명시된 § 5.1 로컬라이즈드 이름 매칭을 적용하여 이름을 매칭합니다. 만약 @font-face 규칙에서 정의된 페이스의 폰트 리소스가 사용 불가하거나 잘못된 폰트 데이터가 포함되어 있다면, 해당 페이스는 패밀리에 없는 것으로 취급해야 합니다. @font-face 규칙으로 정의된 패밀리에 아무런 페이스가 없으면, 해당 패밀리는 없는 것으로 취급하며; 이 경우 동일 이름의 플랫폼 폰트 매칭은 허용되지 않습니다.

  4. 폰트 패밀리 매칭이 이루어지면, 사용자 에이전트는 해당 패밀리의 폰트 페이스 집합을 구성한 뒤, 아래 순서대로 다른 폰트 속성을 사용하여 집합을 단일 페이스로 좁힙니다. 이 집합에는 font-width, font-style, font-weight 속성의 다양한 범위를 지원하는 폰트가 포함될 수 있습니다. 이 경우, 알고리즘은 지원되는 각 값 조합이 집합 내의 고유한 폰트인 것처럼 처리합니다. 최종적으로 이런 폰트가 선택된다면, font-width, font-style, font-weight의 특정 값을 레이아웃 또는 렌더링 전에 적용해야 하며, 이 값 적용은 § 7 폰트 기능 및 변형 해석에 명시된 폰트 매칭 변형 적용 단계에서 이루어져야 합니다. @font-face 규칙에서 동일한 폰트 기술자 값을 갖지만 unicode-range 값이 다른 페이스들의 집합은 이 단계에서 단일 합성 페이스로 간주합니다:

    테스트
    1. 먼저 font-width를 시도합니다. 폰트가 폭 값의 다양한 강도를 지원하지 않는 경우, 해당 폭 값은 속성 정의의 표에 따라 매핑됩니다. 매칭 집합에 원하는 font-width 값을 포함하는 폭 값이 있다면, 원하는 폭 값을 포함하지 않는 페이스는 집합에서 제거됩니다. 원하는 폭 값을 포함하는 페이스가 없다면, 아래 규칙에 따라 폭 값을 선택합니다:

      • 원하는 폭 값이 100% 이하라면, 원하는 폭 값보다 낮은 폭 값을 내림차순으로 먼저 확인하고, 그 후 원하는 폭 값보다 높은 폭 값을 오름차순으로 확인하여 일치하는 값을 찾을 때까지 반복합니다.

      • 그 외에는, 원하는 폭 값보다 높은 폭 값을 오름차순으로 먼저 확인하고, 그 후 원하는 폭 값보다 낮은 폭 값을 내림차순으로 확인하여 일치하는 값을 찾을 때까지 반복합니다.

      이 과정에서 가장 가까운 폭 값이 결정되면, 해당 폭 값을 포함하지 않는 페이스를 집합에서 제거합니다.

      이 검색 알고리즘은 거리 함수로 볼 수 있습니다. 폰트 패밀리에서 최소 거리 값을 가진 폰트가 선택되고, 해당 값을 포함하지 않는 폰트는 모두 제거됩니다.

      예시: A, B, C 세 개의 폰트가 있는 패밀리에서 각 폰트가 font-width 기술자로 지원하는 범위를 가졌다고 가정하면, "font-width: 125%"로 스타일링된 요소의 알고리즘은 아래와 같이 시각화됩니다:

      algorithm

      그래프에서 볼 수 있듯이, 폰트 B가 패밀리 내 최소 폭 값을 포함하므로 알고리즘에 의해 B가 선택됩니다. 만약 B가 제거된다면, C가 패밀리 내 최소 거리 값을 포함하므로 C가 선택됩니다.

      이전 예시와 유사하게, "font-width: 75%" 스타일 요소의 개념적 거리 그래프입니다:

      distance graph

      폰트 B가 패밀리 내 최소 폭 값을 포함하므로 B가 선택됩니다. B가 제거된다면, A가 최소 거리 값을 포함하므로 A가 선택됩니다.

    2. 다음으로 font-style을 시도합니다 (§ 5.2 폰트 스타일 매칭 참고). 폰트가 이탤릭 또는 오블리크 각도의 다양한 강도를 지원하지 않는 경우, 속성 정의에 따라 매핑됩니다.

      font-style 값이 italic일 경우:

      1. 매칭 집합에 italic 매핑 값을 포함하는 이탤릭 값이 있다면, 원하는 이탤릭 매핑 값을 포함하지 않는 페이스는 집합에서 제거합니다.

      2. 그렇지 않으면, 원하는 이탤릭 값보다 높은 값을 오름차순으로, 그 후 낮은 값을 내림차순으로 0까지 확인합니다. 이 단계에서는 양수 이탤릭 값만 확인합니다.

      3. 일치하는 값이 없으면, 11deg 이상의 오블리크 값을 오름차순으로, 그 후 11deg 미만 값을 내림차순으로 0까지 확인합니다. 이 단계에서는 양수 오블리크 값만 확인합니다.

        오블리크와 normal의 우선순위 임계값은 평균 각도보다 낮아야 합니다.

      4. 일치하는 값이 없으면, 0 이하의 이탤릭 값을 내림차순으로 일치할 때까지 확인합니다.

      5. 일치하는 값이 없으면, 0deg 이하의 오블리크 값을 내림차순으로 일치할 때까지 확인합니다.

        이전 예시와 유사하게, "font-style: italic" 스타일 요소의 개념적 거리 그래프입니다:

        distance graph

        폰트 D가 전체 패밀리 내 최소 이탤릭 값을 포함하므로 D가 선택됩니다. D가 제거되면, E, C, B(오블리크 값 우선), A 순으로 선택됩니다.

      font-style 값이 oblique이고 요청 각도가 11deg 이상일 경우,

      1. 매칭 집합에 원하는 오블리크 값을 포함하면, 포함하지 않는 페이스를 집합에서 제거합니다.

      2. 그렇지 않으면, 원하는 값보다 높은 오블리크 값을 오름차순, 그 후 낮은 값을 내림차순으로 0까지 확인합니다. 이 단계에서는 양수 오블리크 값만 확인합니다.

      3. 가변 폰트(slnt axis)에서는 지정된 오블리크 값으로 slnt 값을 설정하여 일치시킵니다. 아니면 font-synthesis-style 값이 auto이면, 지정된 오블리크 값으로 기하학적 시어링을 통해 폴백 일치를 생성합니다.

      4. 일치하는 값이 없으면, 1 이상 이탤릭 값을 오름차순, 그 후 1 미만 값을 내림차순으로 0까지 확인합니다. 이 단계에서는 양수 이탤릭 값만 확인합니다.

      5. 일치하는 값이 없으면, 0deg 이하의 오블리크 값을 내림차순으로 일치할 때까지 확인합니다.

      6. 일치하는 값이 없으면, 0 이하 이탤릭 값을 내림차순으로 일치할 때까지 확인합니다.

        이전 예시와 유사하게, "font-style: oblique 40deg" 스타일 요소의 개념적 거리 그래프입니다:

        distance graph

        폰트 D가 전체 패밀리 내 최소 오블리크 값을 포함하므로 D가 선택됩니다. D가 제거되면, E, C, B(이탤릭 값 우선), A 순으로 선택됩니다.

      font-style 값이 oblique이고 요청 각도가 0deg 이상 11deg 미만일 경우,

      1. 매칭 집합에 원하는 오블리크 값을 포함하면, 포함하지 않는 페이스를 집합에서 제거합니다.

      2. 그렇지 않으면, 원하는 값보다 낮은 오블리크 값을 내림차순으로 0까지, 그 후 높은 값을 오름차순으로 확인합니다. 이 단계에서는 양수 오블리크 값만 확인합니다.

      3. 가변 폰트(slnt axis)에서는 지정된 오블리크 값으로 slnt 값을 설정하여 일치시킵니다. 아니면 font-synthesis-style 값이 auto이면, 지정된 오블리크 값으로 기하학적 시어링을 통해 폴백 일치를 생성합니다.

      4. 일치하는 값이 없으면, 1 미만 이탤릭 값을 내림차순으로 0까지, 그 후 1 이상 값을 오름차순으로 확인합니다. 이 단계에서는 양수 이탤릭 값만 확인합니다.

      5. 일치하는 값이 없으면, 0deg 이하의 오블리크 값을 내림차순으로 일치할 때까지 확인합니다.

      6. 일치하는 값이 없으면, 0 이하 이탤릭 값을 내림차순으로 일치할 때까지 확인합니다.

      이전 예시와 유사하게, "font-style: oblique 13deg" 스타일 요소의 개념적 거리 그래프입니다:

      distance graph

      폰트 D가 전체 패밀리 내 최소 오블리크 값을 포함하므로 D가 선택됩니다. D가 제거되면, C, E, B(이탤릭 값 우선), A 순으로 선택됩니다.

      font-style 값이 oblique이고 요청 각도가 0deg 미만 -11deg 초과면 위 단계를 음수로, 방향 반대로 적용합니다. font-style 값이 oblique이고 요청 각도가 -11deg 이하라면 위 단계를 음수로, 반대로 적용합니다.

      font-style 값이 normal일 경우,

      1. 0 이상 오블리크 값을 오름차순으로 확인합니다.

      2. 일치하는 값이 없으면, 0 이상 이탤릭 값을 오름차순으로 확인합니다.

      3. 일치하는 값이 없으면, 0 미만 오블리크 값을 내림차순으로 일치할 때까지 확인합니다.

      4. 일치하는 값이 없으면, 0 미만 이탤릭 값을 내림차순으로 일치할 때까지 확인합니다.

      이전 예시와 유사하게, "font-style: normal" 스타일 요소의 개념적 거리 그래프입니다:

      distance graph

      폰트 C가 전체 패밀리 내 최소 오블리크 값을 포함하므로 C가 선택됩니다. C가 제거되면, B(이탤릭 값 우선), A 순으로 선택됩니다.

      위 검색에서 오블리크 각도가 발견되면, 해당 오블리크 각도를 포함하지 않는 페이스는 집합에서 제외합니다. 그렇지 않으면, 이탤릭 값이 발견되면 해당 이탤릭 값을 포함하지 않는 페이스를 제외합니다.

      사용자 에이전트는 이탤릭과 오블리크 폰트를 구분하지 않아도 됩니다. 이런 경우, 위 font-style 매칭 단계는 두 값을 공통 스케일에 매핑하여 수행합니다. 매핑 방식은 정의되지 않았으나, 이탤릭 값 1은 오블리크 각도 11deg와 반드시 동일하게 매핑되어야 합니다. @font-face 규칙으로 정의된 폰트 패밀리 내에서는, font-style 기술자 값을 사용하여 이탤릭과 오블리크 페이스를 구분해야 합니다.

      이탤릭 또는 오블리크 페이스가 없는 패밀리의 경우, font-synthesis 속성 값이 허용하면 합성 오블리크 페이스를 생성할 수 있습니다.

    3. 다음은 font-weight를 매칭합니다. 폰트가 다양한 굵기를 지원하지 않는 경우, 속성 정의의 목록에 따라 매핑합니다. bolder/lighter 등 상대 굵기가 사용되면, font-weight 속성 정의에 따라 상속된 값으로 유효 굵기를 계산합니다. 위 단계 이후 매칭 집합에 원하는 font-weight 값을 포함하는 페이스가 있다면, 원하는 값이 없는 페이스는 집합에서 제거합니다. 원하는 값이 없으면 아래 규칙에 따라 굵기를 선택합니다:

      • 원하는 굵기가 400~500 사이(포함)면, 목표 굵기 이상을 오름차순(500까지 확인)으로, 그 후 목표 굵기 미만을 내림차순으로, 그 후 500 초과를 오름차순으로 일치할 때까지 확인합니다.

      • 원하는 굵기가 400 미만이면, 원하는 값 이하를 내림차순으로, 그 후 원하는 값 초과를 오름차순으로 일치할 때까지 확인합니다.

      • 원하는 굵기가 500 초과면, 원하는 값 이상을 오름차순으로, 그 후 원하는 값 미만을 내림차순으로 일치할 때까지 확인합니다.

      이전 예시와 유사하게, "font-weight: 400" 스타일 요소의 개념적 거리 그래프입니다:

      distance graph

      폰트 B가 전체 패밀리 내 최소 거리 값을 포함하므로 B가 선택됩니다. B가 제거되면, C, D, A, E 순으로 선택됩니다.

      이전 예시와 유사하게, "font-weight: 450" 스타일 요소의 개념적 거리 그래프입니다:

      distance graph

      폰트 C가 전체 패밀리 내 최소 거리 값을 포함하므로 C가 선택됩니다. C가 제거되면, D, B, A, E 순으로 선택됩니다.

      이전 예시와 유사하게, "font-weight: 500" 스타일 요소의 개념적 거리 그래프입니다:

      distance graph

      폰트 D가 전체 패밀리 내 최소 거리 값을 포함하므로 D가 선택됩니다. D가 제거되면, B, C, B, A, E 순으로 선택됩니다.

      이전 예시와 유사하게, "font-weight: 300" 스타일 요소의 개념적 거리 그래프입니다:

      distance graph

      폰트 B가 전체 패밀리 내 최소 거리 값을 포함하므로 B가 선택됩니다. B가 제거되면, A, C 순으로 선택됩니다.

      이 과정에서 가장 가까운 굵기가 결정되면, 해당 굵기를 포함하지 않는 페이스를 집합에서 제거합니다.

      참고: [CSS-FONTS-3]와 이 명세 사이에는 font-weight 속성 애니메이션 동작에 작은 변화가 있습니다. 이전에는 font-weight의 보간값을 100 단위로 반올림해 알고리즘을 적용했지만, 이 명세에서는 모든 값을 허용하여 반올림 없이 바로 매칭합니다. 이는 알고리즘의 불연속적 특성에 따른 작은 동작 변화입니다.

    4. 마지막으로 font-size는 UA 의존적인 오차 범위 내에서 매칭되어야 합니다. (일반적으로, 스케일 가능한 폰트는 가장 가까운 픽셀로 반올림하며, 비트맵 폰트의 허용 오차는 20%까지 클 수 있습니다.) 추가 계산(예: em 값 등)은 사용된 font-size 값 기준으로 수행됩니다.

    위 단계 수행 후 매칭 집합에 여러 폰트가 남을 수 있습니다. 이 경우, 사용자 에이전트는 집합에서 한 폰트를 선택하고 해당 폰트로 단계를 계속합니다. 어떤 폰트를 선택할지는 에이전트 및 운영체제마다 다를 수 있지만, 동일 문서 내 두 요소에서는 달라지면 안 됩니다.

  5. 매칭된 페이스가 @font-face 규칙으로 정의된 경우, 사용자 에이전트는 다음 절차로 단일 폰트를 선택해야 합니다:

    1. 폰트 리소스가 로드되지 않았고, unicode-range 기술자 값이 해당 문자를 포함하면, 폰트를 로드합니다.

    2. 다운로드 후, 유효 문자 맵이 해당 문자를 지원하면 해당 폰트를 선택합니다.

    매칭된 페이스가 합성 페이스인 경우, 사용자 에이전트는 합성 페이스 내 각 페이스에 대해 위 절차를 @font-face 규칙 정의의 역순으로 수행해야 합니다.

    다운로드 중에는, 사용자 에이전트는 폰트가 로드될 때까지 기다리거나, 대체 폰트 메트릭으로 한 번 렌더링 후, 폰트가 다운로드되면 다시 렌더링해야 합니다.

  6. 매칭되는 페이스가 없거나, 매칭된 페이스에 렌더링할 문자의 글리프가 없으면, 다음 패밀리명을 선택하여 앞의 세 단계를 반복합니다. 패밀리 내 다른 페이스의 글리프는 고려하지 않습니다. 단, 사용자 에이전트는 font-synthesis 속성 값이 허용하는 경우, 기본 페이스가 해당 글리프를 지원하면 합성 오블리크 버전을 대체할 수 있습니다. 예를 들어, 이탤릭 페이스가 아랍어 글리프를 지원하지 않으면, 레귤러 페이스의 합성 이탤릭 버전을 사용할 수 있습니다.

  7. 평가할 폰트 패밀리가 더 없고, 매칭 페이스도 없으면, 사용자 에이전트는 렌더링할 문자에 가장 잘 맞는 폰트를 찾는 설치 폰트 폴백 절차를 수행합니다. 결과는 사용자 에이전트마다 다를 수 있습니다.

  8. 어떤 폰트로도 특정 문자를 표시할 수 없으면, 사용자 에이전트는 해당 문자가 표시되지 않음을 표시해야 하며, 글리프가 없는 문자를 상징적으로 나타내거나(예: Last Resort Font 사용), 기본 폰트의 글리프를 사용할 수 있습니다.

이 과정의 최적화는 구현이 알고리즘을 정확하게 따른 것처럼 동작한다면 허용됩니다. 매칭은 잘 정의된 순서로 이루어져 동일한 폰트 집합과 렌더링 기술이 주어졌을 때 사용자 에이전트 간 결과가 최대한 일관되게 보장됩니다.

첫 번째 사용 가능한 폰트는, 예를 들어 폰트 상대 길이(예: ex) 정의나 line-height 속성 정의에서 사용되며, U+0020(공백) 문자가 unicode-range에 의해 제외되지 않은 첫 번째 폰트로 정의됩니다. 이는 font-family 목록의 폰트 패밀리(또는 사용 가능한 것이 없으면 사용자 에이전트의 기본 폰트) 중에서 결정됩니다.

@font-face 규칙이 아닌, 패밀리명을 직접 참조한 설치된 폰트는 unicode-range가 전체 유니코드 코드 공간을 포함하는 것으로 간주됩니다.

테스트

참고: 해당 폰트가 실제로 공백 문자 글리프를 가지고 있는지는 중요하지 않습니다.

5.3. 클러스터 매칭

텍스트에 결합 기호와 같은 문자가 포함된 경우, 이상적으로는 기본 문자가 기호와 동일한 폰트로 렌더링되어야 하며, 이는 기호 위치가 올바르게 배치되도록 보장합니다. 이러한 이유로, 클러스터에 대한 폰트 매칭 알고리즘은 단일 문자 매칭의 일반적인 경우보다 더 특화되어 있습니다. 변형 선택자(variation selector)가 포함된 시퀀스의 경우, 해당 문자를 위한 정확한 글리프를 지정하므로, 사용자 에이전트는 항상 설치 폰트 폴백을 시도해 적절한 글리프를 찾은 후, 기본 문자의 기본 글리프를 사용합니다.

결합 기호나 기타 수정자를 포함하는 코드포인트 시퀀스는 그래프임 클러스터라 불립니다 (자세한 설명은 [CSS3TEXT][UAX29] 참고). 기본 문자 b와 결합 문자 시퀀스 c1, c2…가 포함된 클러스터의 경우, 전체 클러스터는 다음 단계로 매칭됩니다:

  1. 폰트 목록의 각 패밀리에 대해, 이전 섹션에 정의된 스타일 선택 규칙을 사용해 페이스를 선택합니다.
    1. 시퀀스 b + c1 + c2 …의 모든 문자가 폰트에서 완전히 지원된다면, 해당 폰트를 시퀀스에 선택합니다.
    2. 여러 코드포인트 시퀀스가 단일 문자와 정규적으로 동일하고, 폰트가 해당 문자를 지원한다면, 해당 폰트를 시퀀스에 선택하고, 전체 클러스터에는 정규적으로 동일한 문자에 연결된 글리프를 사용합니다.
  2. 1단계에서 폰트를 찾지 못한 경우:
    1. c1이 변형 선택자라면, 시스템 폴백을 사용해 b + c1 전체 시퀀스를 지원하는 폰트를 찾아야 합니다. 시스템의 어떤 폰트도 전체 시퀀스를 지원하지 않으면, 단일 문자 b를 일반 단일 문자 매칭 절차로 매칭하고 변형 선택자는 무시합니다. 참고: 변형 선택자가 2개 이상일 경우 인코딩 오류로 처리하며, 뒤쪽 선택자는 무시합니다. [UNICODE]
    2. 그 밖의 경우, 사용자 에이전트는 설치 폰트 폴백을 사용해 전체 클러스터를 지원하는 폰트를 매칭할 수 있습니다.
  3. 2단계에서 폰트를 찾지 못하면, 1단계의 매칭 시퀀스를 사용해 폰트 목록에서 완전히 지원되는 최장 시퀀스를 결정하고, 나머지 결합 문자는 단일 문자 규칙으로 각각 따로 매칭 시도합니다.

5.4. 문자 처리 이슈

CSS 폰트 매칭은 항상 유니코드 문자[UNICODE]가 포함된 텍스트 런에서 수행됩니다. 따라서 레거시 인코딩을 사용하는 문서는 폰트 매칭 전에 트랜스코딩된 것으로 간주합니다. 레거시 인코딩 및 유니코드에 대한 character map을 모두 포함한 폰트의 경우, 레거시 인코딩 character map 내용은 폰트 매칭 결과에 아무런 영향을 주지 않아야 합니다.

폰트 매칭 과정에서는 텍스트 런이 정규화 또는 비정규화 형태임을 가정하지 않습니다 (자세한 내용은 [CHARMOD-NORM] 참고). 폰트는 사전조합(precomposed) 형태만 지원할 수 있고, 분해(decomposed)된 기본 문자+결합 기호 시퀀스는 지원하지 않을 수 있습니다. 저자는 자신의 콘텐츠에 맞는 폰트를 항상 선택해야 하며, 콘텐츠가 정규화 또는 비정규화 문자 스트림을 포함하는지까지 고려해야 합니다.

특정 문자가 Private-Use Area 유니코드 코드포인트인 경우, 사용자 에이전트는 font-family 목록에 지정된, 일반 패밀리가 아닌 폰트 패밀리만 매칭해야 합니다. font-family 목록에 지정된 패밀리 중 해당 코드포인트의 글리프를 포함한 폰트가 없으면, 사용자 에이전트는 해당 문자에 대해 누락된 글리프 심볼을 반드시 표시해야 하며, 해당 코드포인트에 설치 폰트 폴백을 시도하면 안 됩니다. 대체 문자(U+FFFD)를 매칭할 때, 사용자 에이전트는 폰트 매칭 과정을 생략하고 즉시 누락된 글리프 심볼을 표시할 수 있으며, 폰트 매칭 과정에서 선택될 폰트의 글리프를 반드시 표시할 필요는 없습니다.

일반적으로, 특정 패밀리의 폰트들은 모두 동일하거나 유사한 character map을 갖습니다. 여기서 설명된 과정은 character map이 크게 다른 페이스가 포함된 폰트 패밀리도 처리할 수 있도록 설계되었습니다. 하지만, 저자는 이런 패밀리 사용이 예상치 못한 결과를 초래할 수 있음을 주의해야 합니다.

테스트

6. 폰트 기능 속성

최신 폰트 기술은 다양한 고급 타이포그래피 및 언어별 폰트 기능을 지원합니다. 이러한 기능을 활용하면, 하나의 폰트로 다양한 범위의 합자(ligature), 문맥적 및 스타일 대체 글리프, 표 및 구식 숫자, 스몰 캐피털, 자동 분수, 스와시, 특정 언어에 특화된 대체 글리프까지 제공할 수 있습니다. 저자가 이러한 폰트 기능을 제어할 수 있도록 font-variant 속성이 확장되었습니다. 이제 이 속성은 스타일 폰트 기능을 제어할 수 있는 속성 집합의 약어(shorthand)로 동작합니다.

6.1. 글리프 선택 및 배치

이 섹션은 규범적이지 않습니다

라틴 텍스트를 표시하는 간단한 폰트는 매우 기본적인 처리 모델을 사용합니다. 폰트에는 각 문자를 해당 글리프에 매핑하는 character map이 포함되어 있습니다. 이후 문자의 글리프는 단순히 텍스트 런을 따라 순서대로 배치됩니다. OpenType, AAT(Apple Advanced Typography) 등 최신 폰트 포맷은 더 풍부한 처리 모델을 사용합니다. 특정 문자의 글리프는 문자 코드포인트 자체뿐 아니라, 인접 문자, 언어, 스크립트, 텍스트에 활성화된 기능에 따라 선택 및 위치가 결정됩니다. 폰트 기능은 특정 스크립트에 반드시 필요한 기능일 수도 있고, 권장 기본 활성 기능일 수도 있으며, 저자가 직접 제어할 수 있는 스타일 기능일 수도 있습니다. 폰트 선택 및 배치가 전체 텍스트 처리 순서(예: 텍스트 변환, 방향, 정렬)에서 언제 발생하는지는 CSS Text 3 § A 텍스트 처리 작업 순서에서 설명되어 있습니다.

OpenType 폰트의 글리프 처리에 대한 자세한 설명은 [WINDOWS-GLYPH-PROC]을 참고하세요.

스타일 폰트 기능은 크게 두 범주로 나뉩니다: 주변 문맥과의 조화를 위한 글리프 형태에 영향을 주는 기능(커닝, 합자 등), 그리고 스몰캡, 첨자/아래첨자, 대체 글리프처럼 형태 선택에 영향을 주는 기능입니다.

아래에 나열된 font-variant의 하위 속성들은 이러한 스타일 폰트 기능을 제어하는 데 사용됩니다. 이들은 특정 스크립트 표시를 위해 반드시 필요한 기능(예: 아랍어나 인도계 언어 표시에 사용되는 OpenType 기능)까지는 제어하지 않습니다. 글리프 선택과 배치에는 영향을 주지만, 폰트 매칭 섹션에서 설명된 폰트 선택에는 영향을 주지 않습니다 (단, CSS 2.1과의 호환이 필요한 경우는 예외입니다).

사용자 에이전트 간 일관된 동작을 보장하기 위해, 개별 속성에 대해 등가 OpenType 속성 설정을 명시하며, 이는 규범적입니다. 다른 폰트 포맷을 사용할 때도 CSS 폰트 기능 속성 값을 특정 폰트 기능에 매핑하는 지침으로 활용해야 합니다.

6.2. 언어별 표시

OpenType은 언어별 글리프 선택 및 배치를 지원하므로, 언어가 특정 표시 동작을 요구하는 경우에도 텍스트를 올바르게 표시할 수 있습니다. 많은 언어들이 동일한 스크립트를 공유하지만, 특정 글자 형태는 언어에 따라 달라질 수 있습니다. 예를 들어, 일부 키릴 문자들은 러시아어와 불가리아어에서 형태가 다릅니다. 라틴 텍스트에서는 "fi"를 점 없는 합자(fi-ligature)로 렌더링하는 것이 일반적입니다. 하지만 터키어처럼 점 있는 i/dotless i를 모두 쓰는 언어에서는 이 합자를 사용하면 안 되거나, "i" 위에 점이 있는 특화 버전을 사용해야 합니다.

테스트

아래 예시는 스페인어, 이탈리아어, 프랑스어 정서법의 스타일 전통에 따른 언어별 변형을 보여줍니다:

언어별 형태, 스페인어
언어별 형태, 이탈리아어
언어별 형태, 프랑스어

요소의 콘텐츠 언어가 문서 언어 규칙에 따라 알려진 경우, 사용자 에이전트는 콘텐츠 언어에서 OpenType 언어 시스템을 추론하여 OpenType 폰트로 글리프 선택 및 배치 시 이를 사용해야 합니다. 쓰기 시스템이 명시적으로 지정된 경우, 콘텐츠 언어로 암시되는 관례적인 시스템보다 우선해야 합니다.

OpenType 폰트의 경우, 어떤 언어로 표시하더라도 다른 언어의 타이포그래피 관례를 사용하거나, 폰트가 특정 언어 지원을 명시하지 않지만 유사 관례를 지원하는 언어가 있을 때, 사용할 OpenType 언어를 명시적으로 지정해야 할 수도 있습니다. 이를 위해 font-language-override 속성을 사용합니다.

6.3. 커닝: font-kerning 속성

이름: font-kerning
값: auto | normal | none
초기값: auto
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속(discrete)
테스트

커닝은 글리프 간 간격을 문맥에 따라 조정하는 것입니다. 이 속성은 폰트에 포함된 조정 데이터를 활용하는 메트릭 커닝을 제어합니다.

auto
커닝 적용 여부는 사용자 에이전트의 재량에 따름
normal
커닝을 적용함
none
커닝을 적용하지 않음

커닝 데이터가 없는 폰트에서는 이 속성이 눈에 띄는 효과를 가지지 않습니다. OpenType 폰트로 렌더링할 때, [OPENTYPE] 명세는 기본적으로 커닝을 활성화할 것을 권장합니다. 커닝이 활성화되면, 관련 OpenType 커닝 기능이 활성화됩니다 (수평 타이포그래픽 모드 및 세로 타이포그래픽 모드에서 sideways typesettingkern 기능; upright typesetting이 적용된 세로 타이포그래픽 모드에서는 vkrn 기능). 사용자 에이전트는 kern 폰트 테이블에만 커닝 데이터가 포함된 폰트도 반드시 지원해야 하며, 자세한 내용은 OpenType 명세를 참고하세요. letter-spacing 속성이 정의된 경우, 커닝 조정은 기본 간격의 일부로 간주되며, letter-spacing 조정은 커닝 적용 에 이루어집니다.

값이 auto로 설정되면, 사용자 에이전트는 커닝 적용 여부를 여러 요소(텍스트 크기, 스크립트, 텍스트 처리 속도에 영향을 주는 기타 요소 등)에 따라 결정할 수 있습니다. 제대로 된 커닝을 원하는 저자는 normal을 명시적으로 사용해 커닝을 활성화해야 합니다. 반대로, 성능이 외형보다 중요할 때 커닝을 비활성화하는 것도 가능합니다. 하지만, 현대적이고 잘 설계된 구현에서는 커닝 사용이 텍스트 렌더링 속도에 큰 영향을 주지 않습니다.

6.4. 합자: font-variant-ligatures 속성

이름: font-variant-ligatures
값: normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속(discrete)
테스트

합자와 문맥적 형태는 글리프를 결합하여 더 조화로운 형태를 만드는 방법입니다.

<common-lig-values>        = [ common-ligatures | no-common-ligatures ]
<discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
<historical-lig-values>    = [ historical-ligatures | no-historical-ligatures ]
<contextual-alt-values>    = [ contextual | no-contextual ]

각 값의 의미는 다음과 같습니다:

normal
normal 값은 기본 공통 기능이 활성화됨을 지정합니다. 자세한 내용은 다음 섹션 참고. OpenType 폰트의 경우, 일반 합자와 문맥적 형태는 기본적으로 켜져 있으며, 임의 합자와 역사적 합자는 기본적으로 꺼져 있습니다.
none
이 속성이 다루는 모든 종류의 합자와 문맥적 형태가 명시적으로 비활성화됩니다. 합자가 필요하지 않은 상황에서, 이 설정은 텍스트 렌더링 속도를 향상시킬 수 있습니다.
common-ligatures
일반 합자 표시를 활성화합니다 (OpenType 기능: liga, clig). OpenType 폰트에서는 기본적으로 활성화되어 있습니다.
common ligature example
no-common-ligatures
일반 합자 표시를 비활성화합니다 (OpenType 기능: liga, clig).
discretionary-ligatures
임의 합자 표시를 활성화합니다 (OpenType 기능: dlig). 어떤 합자가 임의 또는 옵션인지는 타입 디자이너가 결정하므로, 저자는 해당 폰트의 문서를 참고하여 어떤 합자가 임의 합자인지 파악해야 합니다.
discretionary ligature example
no-discretionary-ligatures
임의 합자 표시를 비활성화합니다 (OpenType 기능: dlig).
historical-ligatures
역사적 합자 표시를 활성화합니다 (OpenType 기능: hlig).
historical ligature example
no-historical-ligatures
역사적 합자 표시를 비활성화합니다 (OpenType 기능: hlig).
contextual
문맥적 대체 표시를 활성화합니다 (OpenType 기능: calt). 엄밀히 말해 합자 기능은 아니지만, 합자처럼 주변 문맥과 글리프 형태를 조화시키는 데 많이 사용됩니다. OpenType 폰트에서는 기본적으로 활성화되어 있습니다.
contextual alternate example
no-contextual
문맥적 대체 표시를 비활성화합니다 (OpenType 기능: calt).

필수 합자는 복잡한 스크립트를 올바르게 렌더링하기 위해 필요하며, 위 설정(none 포함)에 영향을 받지 않습니다 (OpenType 기능: rlig).

6.5. 첨자 및 윗첨자 형태: font-variant-position 속성

이름: font-variant-position
값: normal | sub | super
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속(discrete)
테스트

이 속성은 타이포그래피 첨자 및 윗첨자 글리프를 활성화하는 데 사용됩니다. 이들은 동일 em-box 내에서 디자인된 대체 글리프로, 기본 글리프와 동일한 기준선에 배치되도록 만들어졌으며, 기준선의 크기나 위치를 조정하지 않고 레이아웃됩니다. 주변 텍스트와 잘 맞도록 명확하게 디자인되었으며, 줄 높이에 영향을 주지 않으면서 더 읽기 쉽게 만듭니다.

실제 첨자 글리프와 합성 첨자 비교

첨자 글리프(상단) vs. 일반적으로 합성된 첨자(하단)

각 값의 의미는 다음과 같습니다:

normal
아래에 나열된 기능이 활성화되지 않습니다.
sub
첨자 변형 표시를 활성화합니다 (OpenType 기능: subs).
super
윗첨자 변형 표시를 활성화합니다 (OpenType 기능: sups).

첨자와 윗첨자의 의미적 특성 때문에, 연속 텍스트 런에 sub 또는 super 값이 적용된 경우, 해당 런의 모든 문자에 대체 글리프가 없으면, 합성 글리프가 적용 기능 없이 사용되는 글리프의 축소 형태로 모든 문자에 대해 합성되어야 합니다. 이는 런 단위로 이루어져야 하며, 대체 글리프와 합성 글리프가 혼합되어 정렬이 맞지 않는 현상을 피하기 위함입니다. OpenType 폰트에 특정 문자의 첨자/윗첨자 글리프가 없는 경우, 사용자 에이전트는 반드시 적절한 첨자/윗첨자 글리프를 합성해야 합니다.

대체 윗첨자와 윗첨자 메트릭으로 합성된 글리프 비교

윗첨자 대체 글리프(왼쪽), 합성 윗첨자 글리프(가운데), 둘을 잘못 혼합한 경우(오른쪽)

텍스트 장식이 윗첨자 또는 첨자 글리프가 포함된 텍스트 런에만 적용되는 상황에서는, 합성 글리프를 사용해 장식 위치 문제를 피할 수 있습니다.

과거에는, 사용자 에이전트가 subsup 요소에 대해 font-size 및 vertical-align을 사용하여 첨자/윗첨자를 합성했습니다. 하위 호환 방식으로 첨자/윗첨자를 정의할 수 있도록, 저자는 조건부 규칙 [CSS3-CONDITIONAL]을 사용해 오래된 사용자 에이전트에서도 첨자/윗첨자가 기존 방식으로 렌더링되도록 하는 것이 좋습니다.

font-size: smaller가 해당 요소에 자주 쓰이므로, 첨자/윗첨자 텍스트에 적용되는 실제 스케일링 비율은 크기에 따라 달라집니다. 큰 텍스트에서는 폰트 크기를 1/3까지 줄이지만, 작은 텍스트에서는 더 적게 줄일 수 있습니다. 이를 통해 첨자/윗첨자가 작은 텍스트에서도 읽기 쉽습니다. 사용자 에이전트는 첨자/윗첨자 글리프 합성 시 이를 고려해야 합니다.

OpenType 폰트 포맷은 OS/2 테이블 [OPENTYPE]에 첨자/윗첨자 메트릭을 정의하지만, 실제로는 정확하지 않은 경우가 많으므로, 첨자/윗첨자 글리프 합성에 의존할 수 없습니다.

저자는 폰트가 일반적으로 폰트가 지원하는 모든 문자에 대해 첨자/윗첨자 글리프를 제공하는 것이 아니라는 점을 알아야 합니다. 예를 들어, 라틴 숫자에는 첨자/윗첨자 글리프가 자주 있지만, 문장부호나 문자에는 덜 제공됩니다. 이 속성에 대해 정의된 합성 폴백 규칙은 첨자/윗첨자가 항상 나타나도록 하려 하지만, 폰트가 모든 첨자/윗첨자에 적절한 대체 글리프를 제공하지 않으면 외형이 저자 기대와 다를 수 있습니다.

이 속성은 누적적이지 않습니다. 첨자/윗첨자 내 요소에 적용해도 첨자/윗첨자 글리프의 배치를 중첩시키지 않습니다. 이 속성 값이 sub 또는 super인 텍스트 런에 포함된 이미지는 normal 값일 때와 동일하게 그려집니다.

이러한 한계로 font-variant-position은 사용자 에이전트 스타일시트에서는 권장되지 않습니다. 저자는 첨자/윗첨자가 지정한 폰트가 지원하는 좁은 범위의 문자만 포함하는 경우에만 사용하는 것이 좋습니다.

대체 글리프는 기본 글리프와 동일한 기준선을 사용합니다. 기준선 위치가 이동하지 않으므로, 대체 글리프 사용이 인라인 박스 높이나 라인박스 높이에 영향을 주지 않습니다. 이는 윗첨자와 첨자 변형이 줄 간격(leading)이 일정하게 유지되어야 하는 다단 레이아웃 등에 이상적임을 의미합니다.

sub 요소에 대한 전형적인 사용자 에이전트 기본 스타일:

sub {  vertical-align: sub;
  font-size: smaller;
  line-height: normal;
}

font-variant-position 속성을 사용하여 타이포그래피 첨자를 지정하면서 오래된 사용자 에이전트에서도 첨자가 보이게 하는 방법:

@supports ( font-variant-position: sub ) {
  sub {
  vertical-align: baseline;
  font-size: 100%;
  line-height: inherit;
  font-variant-position: sub;
  }

}

font-variant-position 속성을 지원하는 사용자 에이전트는 첨자 변형 글리프를 선택해 기준선이나 폰트 크기를 조정하지 않고 렌더링합니다. 이전 사용자 에이전트는 font-variant-position 속성 정의를 무시하고 첨자에 대한 기본값을 사용합니다.

6.6. 대문자 변형: font-variant-caps 속성

이름: font-variant-caps
값: normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속
테스트

이 속성은 스몰캡, 프티캡, 타이틀용 대문자 등 대체 글리프 선택을 허용합니다. 이 글리프들은 주변 일반 글리프와 잘 어우러지도록 특별히 디자인되며, 단순히 크기를 줄여 맞추는 경우 발생하는 두께와 가독성 저하를 방지합니다.

각 값의 의미는 다음과 같습니다:

normal
아래 나열된 기능 중 아무 것도 활성화되지 않습니다.
small-caps
스몰 대문자 표시를 활성화합니다 (OpenType 기능: smcp). 스몰캡 글리프는 일반적으로 대문자 형태를 사용하지만 소문자 크기로 축소됩니다.
small-caps example
all-small-caps
대문자와 소문자 모두에 대해 스몰 대문자 표시를 활성화합니다 (OpenType 기능: c2sc, smcp).
petite-caps
프티캡 표시를 활성화합니다 (OpenType 기능: pcap).
all-petite-caps
대문자와 소문자 모두에 대해 프티캡 표시를 활성화합니다 (OpenType 기능: c2pc, pcap).
unicase
대문자에는 스몰캡, 소문자에는 일반 글리프가 혼합된 형태 표시를 활성화합니다 (OpenType 기능: unic).
titling-caps
타이틀용 대문자 표시를 활성화합니다 (OpenType 기능: titl). 대문자 글리프는 종종 소문자와 함께 쓰이도록 디자인됩니다. 모두 대문자인 타이틀 시퀀스에서는 너무 두꺼워 보일 수 있으므로, 타이틀 대문자는 이런 상황에 맞게 특별히 디자인됩니다.

이 글리프들의 사용 가능 여부는 해당 기능이 폰트의 기능 목록에 정의되어 있는지에 따라 결정됩니다. 사용자 에이전트는 스크립트별로 선택적으로 결정할 수 있지만, 문자별로 결정해서는 안 됩니다.

일부 폰트는 이 속성 설명에 해당하는 기능의 일부만 지원하거나 아예 지원하지 않을 수 있습니다. CSS 2.1과의 하위 호환을 위해, small-caps 또는 all-small-caps이 지정됐으나 해당 폰트에 스몰캡 글리프가 없으면, 사용자 에이전트는 스몰캡 폰트를 합성해서 보여야 하며, 예를 들어 일반 폰트에서 소문자 글리프를 대문자 글리프의 축소 버전으로 대체해야 합니다 (all-small-caps의 경우 대문자와 소문자 글리프 모두 대체).

synthetic vs. real small-caps

합성 vs. 실제 스몰캡

font-feature-settings 속성도 합성 스몰캡 폰트 사용 여부 결정에 영향을 줍니다 (CSS Fonts 3과 다름).

#example1 { font-variant-caps: small-caps; }#example2 { font-variant-caps: small-caps; font-feature-settings: 'smcp' 0; }

스몰캡을 지원하지 않는 폰트에서는 #example1과 #example2 모두 합성 스몰캡으로 렌더링해야 합니다. 하지만, 스몰캡을 지원하는 폰트에서는 #example1은 네이티브 스몰캡으로, #example2는 어떤 스몰캡(네이티브 또는 합성)도 없이 렌더링해야 합니다.

주변 텍스트와 맞추기 위해, 폰트가 케이스 없는 문자에 대해 대체 글리프를 제공할 수 있지만, 사용자 에이전트가 스몰캡을 합성할 경우 케이스 없는 코드포인트에 대해 대체를 합성 시도해서는 안 됩니다.

caseless characters with small-caps, all-small-caps enabled

스몰캡/올-스몰캡 활성화 시 케이스 없는 문자

petite-caps 또는 all-petite-caps이 해당 기능을 지원하지 않는 폰트에 지정되면, 해당 속성은 각각 small-caps 또는 all-small-caps가 지정된 것처럼 동작합니다. unicase가 해당 기능을 지원하지 않는 폰트에 지정되면, 해당 속성은 small-caps가 대문자 소문자에만 적용된 것처럼 동작합니다. titling-caps가 해당 기능을 지원하지 않는 폰트에 지정되면, 해당 속성은 아무런 시각적 효과가 없습니다. 합성 스몰캡 글리프가 사용되는 경우, 대소문자 구분이 없는 스크립트에서는 small-caps, all-small-caps, petite-caps, all-petite-capsunicase는 시각적 효과가 없습니다.

케이싱 변환을 사용해 스몰캡을 합성할 때, 케이싱 변환 규칙은 text-transform 속성에서 사용하는 규칙과 일치해야 합니다.

마지막 수단으로, 일반 폰트의 크기 조정되지 않은 대문자 글리프가 스몰캡 폰트의 글리프를 대체하여 텍스트가 모두 대문자로 보이게 할 수 있습니다.

using all-small-caps in acronym-laden text

두문자어가 많은 텍스트에서 스몰캡 활용 예시

인용구를 이탤릭으로, 첫 줄에만 스몰캡 적용:

blockquote            { font-style: italic; }blockquote:first-line { font-variant: small-caps; }

<blockquote>I’ll be honor-bound to slap them like a haddock.</blockquote>

6.7. 숫자 포맷팅: font-variant-numeric 속성

이름: font-variant-numeric
값: normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ]
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속
테스트

숫자 형태 제어를 지정합니다. 아래 예시는 이 값들을 조합하여 숫자 데이터가 들어 있는 표를 렌더링할 때 폰트가 지원하는 경우 어떻게 렌더링에 영향을 줄 수 있는지 보여줍니다. 일반 단락 텍스트에서는 비례 숫자를 사용하지만, 표 숫자에서는 숫자 열이 올바르게 정렬되도록 표 숫자가 사용됩니다:

combining number styles

숫자 스타일 활용

가능한 조합:

<numeric-figure-values>   = [ lining-nums | oldstyle-nums ]
<numeric-spacing-values>  = [ proportional-nums | tabular-nums ]
<numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]

각 값의 의미는 다음과 같습니다:

normal
아래 나열된 기능이 활성화되지 않습니다.
lining-nums
라이닝 숫자 표시를 활성화합니다 (OpenType 기능: lnum).
oldstyle-nums
올드스타일 숫자 표시를 활성화합니다 (OpenType 기능: onum).
proportional-nums
비례 숫자 표시를 활성화합니다 (OpenType 기능: pnum).
tabular-nums
표 숫자 표시를 활성화합니다 (OpenType 기능: tnum).
diagonal-fractions
라이닝 대각선 분수 표시를 활성화합니다 (OpenType 기능: frac).
diagonal fraction example
stacked-fractions
라이닝 누적 분수 표시를 활성화합니다 (OpenType 기능: afrc).
stacked fraction example
ordinal
서수 숫자에 사용되는 문자 형태 표시를 활성화합니다 (OpenType 기능: ordn).
ordinals example
slashed-zero
슬래시가 있는 0 표시를 활성화합니다 (OpenType 기능: zero).
slashed zero example

ordinal의 경우, 서수 형태가 종종 윗첨자 형태와 동일하지만, 마크업 방식이 다릅니다.

윗첨자의 경우, variant 속성은 윗첨자를 포함하는 하위 요소에만 적용됩니다:

sup { font-variant-position: super; }
x<sup>2</sup>

서수의 경우, variant 속성은 전체 서수 숫자에 적용되며, 접미사만 적용되는 것이 아니라(혹은 단락 전체에 적용되는 것이 아니라):

.ordinal { font-variant-numeric: ordinal; }
<span class="ordinal">17th</span>

이 경우 "th"만 서수 형태로 나타나고, 숫자는 변하지 않습니다. 사용 언어의 타이포그래피 관례에 따라 서수 형태가 윗첨자 형태와 다를 수 있습니다. 예를 들어, 이탈리아어에서는 서수 형태에 밑줄이 포함되는 경우가 있습니다.

자동 분수와 올드스타일 숫자를 활용한 간단한 스테이크 마리네이드 레시피:

.amount { font-variant-numeric: oldstyle-nums diagonal-fractions; }
<h4>Steak marinade:</h4>
<ul>
  <li><span class="amount">2</span> tbsp olive oil</li>
  <li><span class="amount">1</span> tbsp lemon juice</li>
  <li><span class="amount">1</span> tbsp soy sauce</li>
  <li><span class="amount">1 1/2</span> tbsp dry minced onion</li>
  <li><span class="amount">2 1/2</span> tsp italian seasoning</li>
  <li>Salt &amp; pepper</li>
</ul>

<p>Mix the meat with the marinade
and let it sit covered in the refrigerator
for a few hours or overnight.</p>

분수 기능은 값에만 적용되며, 단락 전체에는 적용되지 않습니다. 폰트는 이 기능을 슬래시('/') 문자 사용 맥락 규칙에 따라 구현하는 경우가 많으므로, 단락 스타일로 사용하기에는 적합하지 않습니다.

6.8. 대체 글리프 및 스와시: font-variant-alternates 속성

이름: font-variant-alternates
값: normal | [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ]
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속
테스트
<feature-value-name> = <ident>

특정 문자에 대해 폰트는 해당 문자 기본 글리프 외에도 다양한 대체 글리프를 제공할 수 있습니다. 이 속성은 이러한 대체 글리프 선택을 제어합니다.

아래에 나열된 속성 값들 중 다수는 여러 다른 대체 글리프가 제공됩니다. 대체 글리프의 수와 의미는 폰트마다 다르므로, 아래 값 정의에서 각각 폰트별로 표시됩니다. 이런 대체 글리프의 특성이 폰트별이기 때문에, @font-feature-values 규칙을 사용해서 특정 폰트 패밀리 또는 패밀리 집합에 대해 폰트별 숫자 <feature-index>와 커스텀 <feature-value-name>을 연결하여, 이 속성에서 원하는 대체 글리프를 선택할 때 사용합니다:

@font-feature-values Noble Script { @swash { swishy: 1; flowing: 2; } }

p {
  font-family: Noble Script;
  font-variant-alternates: swash(flowing); /* 스와시 대체 #2 사용 */
}

특정 <feature-value-name>이 해당 패밀리 또는 특정 기능 타입에 대해 정의되어 있지 않은 경우, 계산값은 정의된 것과 동일해야 합니다. 단, 이런 미정의 <feature-value-name> 식별자를 포함하는 속성 값은 글리프 선택 시 무시되어야 합니다.

/* 아래 두 스타일 규칙은 실질적으로 동일함 */

p { font-variant-alternates: swash(unknown-value); } /* 정의되지 않은 값이므로 무시됨 */
p { font-variant-alternates: normal; }

이 방식은 특정 폰트 집합에 대해 값이 정의되고 사용될 수 있지만 폴백이 발생하면 무시되게 해줍니다. 값이 해당 폰트에서 지원 범위를 벗어나면 무시됩니다. 이런 값은 일반 폰트 패밀리에는 적용되지 않습니다.

각 값의 의미는 다음과 같습니다:

normal
아래에 나열된 기능이 활성화되지 않습니다.
historical-forms
역사적 형태 표시를 활성화합니다 (OpenType 기능: hist).
historical form example
stylistic(<feature-value-name>)
스타일 대체 표시를 활성화합니다 (폰트별, OpenType 기능: salt <feature-index>).
stylistic alternate example
styleset(<feature-value-name>#)
스타일 세트로 표시합니다 (폰트별, OpenType 기능: ss<feature-index> OpenType은 현재 ss01~ss20 까지 정의).
styleset example
character-variant(<feature-value-name>#)
특정 문자 변형 표시를 활성화합니다 (폰트별, OpenType 기능: cv<feature-index> OpenType은 현재 cv01~cv99 까지 정의).
swash(<feature-value-name>)
스와시 글리프 표시를 활성화합니다 (폰트별, OpenType 기능: swsh <feature-index>, cswh <feature-index>).
swash example
ornaments(<feature-value-name>)
폰트에 제공된 경우 기본 글리프를 장식 글리프로 대체합니다 (폰트별, OpenType 기능: ornm <feature-index>). 일부 폰트는 다양한 문자에 대한 장식 글리프를 대체로 제공할 수 있으나, 임의 문자(예: 영숫자)를 장식으로 표시하는 것은 데이터의 의미를 왜곡하므로 권장되지 않습니다. 폰트 디자이너는 모든 장식(유니코드 딩벳 블록 등 명시적으로 인코딩된 경우 제외)은 글머리표(U+2022) 문자 대체로 인코딩하여, 저자가 ornaments()로 원하는 글리프를 선택할 수 있게 하는 것이 좋습니다.
ornaments example
annotation(<feature-value-name>)
대체 주석 형태 표시를 활성화합니다 (폰트별, OpenType 기능: nalt <feature-index>).
alternate annotation form example

6.9. 폰트별 대체 글리프 정의: @font-feature-values 규칙

위에 나열된 font-variant-alternates 값 중 일부에는 폰트별로 표시되어 있습니다. 폰트는 해당 기능에 대해 하나의 글리프만 정의하는 것이 아니라, 여러 글리프 변형을 정의하고, 각각 숫자 인덱스와 연결해 원하는 글리프를 선택할 수 있게 합니다.

이 숫자 인덱스는 각 페이스마다 고유합니다; 한 폰트 페이스에서 swsh 1 기능은 대문자 Q의 스와시 버전을 켤 수 있지만, 다른 폰트 페이스에서는 &의 스와시 버전을 켤 수도 있습니다. 따라서 font-feature-settings에서 인덱스를 지정하려면, 저자가 해당 요소에 어떤 폰트가 사용될지 정확히 알아야 하며, 폰트 폴백으로 폰트가 달라지면 원하는 것과 완전히 다른, 원치 않는 기능이 켜질 수 있습니다! 또한, 서로 다른 폰트를 가진 요소에 비슷한 기능을 쉽게 켤 수 없고, 각각 원하는 기능에 맞는 font-feature-settings 값을 개별적으로 지정해야 합니다.

이 문제를 해결하기 위해 @font-feature-values 규칙은 저자가 각 폰트 페이스별로 특정 기능 인덱스에 사람이 친숙한 이름을 할당하게 해줍니다. 이런 친숙한 이름을 사용하면, 저자는 폰트마다 해당 이름을 정의해두기만 하면 동일한 스타일 규칙으로 다양한 폰트의 비슷한 기능을 쉽게 켤 수 있고, 이름이 정의되지 않은 폰트는 아무런 동작도 하지 않으므로 원치 않는 기능이 켜질 염려도 없습니다.

공통 이름 값을 사용하면 저자가 각 폰트의 내부 셀렉터가 다르더라도 하나의 스타일 규칙으로 여러 폰트에 적용할 수 있습니다. 아래 예시에서 두 폰트 중 하나라도 있으면, 원 안 숫자 글리프가 사용됩니다:

@font-feature-values Otaru Kisa {
  @annotation { circled: 1; black-boxed: 3; }
}
@font-feature-values Taisho Gothic {
  @annotation { boxed: 1; circled: 4; }
}

h3.title {
  /* 두 폰트 모두에 circled 형태 정의됨 */
  font-family: Otaru Kisa, Taisho Gothic;
  font-variant: annotation(circled);
}

"circled" 형태를 두 폰트 중 하나에 명시적으로 켜려면, font-feature-values를 사용해야 하며, 저자가 확실히 어떤 폰트가 쓰일지 알아야 합니다; "Otaru Kisa"를 기대하고 font-feature-values: nalt 1;을 쓰면, Otara Kisa에서는 "circled" 문자가 켜지지만, 폰트가 Taisho Gothic으로 폴백되면 boxed 문자가 켜집니다. Taisho Gothic에서는 nalt 1이 boxed와 연결되어 있기 때문입니다!

6.9.1. 기본 문법

@font-feature-values 규칙의 프렐류드는 폰트 패밀리 이름 목록을 포함하며, 이어서 여러 feature-value-block이 포함된 블록이 옵니다. feature-value-block은 특별한 하위 at-rule 타입입니다. 각 feature-value-block에는 저자가 직접 선택한 식별하기 쉬운 이름(예: "flowing")을 관련 기능의 인덱스에 매핑하는 선언이 들어갑니다.

<font-feature-value>font-variant-alternates 속성의 해당 값과 동일한 의미를 가집니다.

@font-feature-values = @font-feature-values <family-name># { <declaration-rule-list> }

font-feature-value-type = <@stylistic> | <@historical-forms> | <@styleset> | <@character-variant>
  | <@swash> | <@ornaments> | <@annotation> 

@stylistic = @stylistic { <declaration-list> }
@historical-forms = @historical-forms { <declaration-list> }
@styleset = @styleset { <declaration-list> }
@character-variant = @character-variant { <declaration-list> }
@swash = @swash { <declaration-list> }
@ornaments = @ornaments { <declaration-list> }
@annotation = @annotation { <declaration-list> }
테스트

@font-feature-values 프렐류드는 <family-name> 정의와 일치하는 폰트 패밀리 이름을 쉼표로 구분한 목록입니다. 즉, 이름이 지정된 폰트 패밀리만 허용됩니다; 목록에 generic 또는 시스템 폰트가 포함되면 문법 오류입니다. 단, 사용자 에이전트가 generic 폰트를 특정 이름 폰트(예: Helvetica)로 매핑하면, 해당 패밀리 이름에 연결된 설정이 사용됩니다. <family-name> 목록에 문법 오류가 있으면 전체 @font-feature-values 규칙이 잘못된 것으로 간주되어 무시되어야 합니다.

@font-feature-values 블록은 <declaration-rule-list>를 내용으로 허용합니다; 이 목록 항목은 다음 중 하나입니다:

또는

동일한 <font-feature-value-type>을 여러 번 지정하는 것은 유효합니다; 그 내용은 함께 합성(cascade)됩니다. 각 <feature-value-block>선언 목록을 허용하며, 이 선언을 폰트 기능 값 선언이라 합니다. 선언의 이름은 어떤 식별자도 될 수 있으며, 값은 0 이상의 <integer> 하나 이상의 리스트여야 합니다.

<feature-value-block>은 어떤 선언 이름도 허용합니다; 이 이름은 표준 CSS 문법 규칙에 따라 식별자여야 하며, 대소문자를 구분합니다 (즉, foo: 1;FOO: 2는 다른 기능을 정의함). 각 선언의 값은 <integer [0,∞]>+ 문법을 따라야 하며, 그렇지 않으면 선언은 무효로 간주되고 무시되어야 합니다.

참고: 각 기능 이름은 하나의 <feature-value-block> 내에서만 고유합니다. 서로 다른 <feature-value-block> 또는 별도의 @font-feature-values 규칙의 동일 타입 <feature-value-block> 간에는 이름을 중복 사용해도 충돌하지 않습니다.

<family-name>@font-feature-values 프렐류드에 있는 경우, 각 폰트 기능 값 선언은 (패밀리명, 기능 블록명, 선언명) 튜플과 선언 값의 하나 이상의 정수 리스트 간의 매핑을 정의합니다. 동일한 튜플이 문서 내에 여러 번 나타나면 (예: 한 블록에) 마지막으로 정의된 것이 사용됩니다.

예를 들어, 아래 모두 동일한 폰트 기능 값을 정의합니다:
/* 기본 */
@font-feature-values foo {
    @swash { pretty: 1; cool: 2; }
}

/* 반복된 선언 이름 */
@font-feature-values foo {
    @swash { pretty: 0; pretty: 1; cool: 2; }
}

/* 동일 타입의 여러 블록 */
@font-feature-values foo {
    @swash { pretty: 1; }
    @swash { cool: 2; }
}

/* 동일 패밀리에 대한 여러 규칙 */
@font-feature-values foo {
    @swash { pretty: 1; }
}
@font-feature-values foo {
    @swash { cool: 2; }
}

폰트 기능 값 선언 내 문법 오류는 선언을 무효로 만들고 무시되지만, 발생한 폰트 기능 값 블록 전체를 무효화하지는 않습니다. @font-feature-values 블록 내에서 허용되지 않은 at-keyword를 사용하는 미지의 at-rule은 해당 at-rule을 무효로 만들고 무시되지만, @font-feature-values 규칙 전체를 무효화하지는 않습니다.

문법 오류 처리에 따라 동등한 규칙 예시:
@font-feature-values Bongo {
    @swash { ornate: 1; }
    annotation { boxed: 4; } /* @annotation이어야 함! */
    @swash { double-loops: 1; flowing: -1; } /* 음수 값 */
    @ornaments ; /* 정의 미완 */
    @styleset { double-W: 14; sharp-terminals: 16 1 } /* 세미콜론 누락 */
    redrum  /* 편집 실수 */
}

위 예시는 다음과 동일하게 처리됩니다:

@font-feature-values Bongo {
    @swash { ornate: 1; }
    @swash { double-loops: 1; }
    @styleset { double-W: 14; sharp-terminals: 16 1; }
}

특정 패밀리에 대해 여러 @font-feature-values 규칙이 정의되면, 결과 값 정의는 각 규칙에 포함된 정의의 합집합이 됩니다. 이를 통해 사이트 전체에 대해 특정 폰트 패밀리용으로 이름 값을 전역 선언하고, 페이지별로 추가 정의를 할 수 있습니다.

사이트 전체와 페이지별 기능 값을 모두 쓰는 예시:

site.css:

@font-feature-values Mercury Serif {
    @styleset {
        stacked-g: 3; /* g, a의 "two-storey" 버전 */
        stacked-a: 4;
    }
}

page.css:

@font-feature-values Mercury Serif {
    @styleset {
       geometric-m: 7; /* m의 대체 버전 */
    }
}

body {
    font-family: Mercury Serif, serif;

    /* stacked g와 대체 m 모두 활성화 */
    font-variant-alternates: styleset(stacked-g, geometric-m);
}

6.9.2. 다중 값 기능 값 정의

font-variant-alternates 속성의 대부분 폰트별 기능 값은 단일 값(e.g. swash())을 받아 해당 기능을 활성화합니다.

@font-feature-values Jupiter Serif {
  @swash {
    swishy: 5;     /* ss05 = 1 의미 */
    swirly: 2;     /* ss02 = 1 의미 */
  }
}

character-variant() 속성 값과 @character-variant 기술자는 두 개의 값을 허용하며, 첫 번째 값으로 기능을 활성화하고 두 번째 값으로 해당 기능에 값을 전달합니다.

@font-feature-values MM Greek {
  @character-variant { alpha-2: 1 2; }   /* cv01 = 2 의미 */
  @character-variant { beta-3: 2 3; }    /* cv02 = 3 의미 */
}

styleset() 속성 값과 @styleset 규칙에서는 여러 값이 스타일 세트 활성화를 의미합니다. 1~99 범위 값은 OpenType 기능 ss01~ss99를 활성화합니다. 단, OpenType 표준은 ss01~ss20만 공식 정의합니다. OpenType 폰트에서 99보다 크거나 0인 값은 파싱 시 문법 오류를 발생시키지 않지만, 어떤 OpenType 기능도 활성화하지 않습니다.

@font-feature-values Mars Serif {
  @styleset {
  alt-g: 1;        /* ss01 = 1 의미 */
  curly-quotes: 3; /* ss03 = 1 의미 */
  code: 4 5;       /* ss04 = 1, ss05 = 1 의미 */
  }

  @styleset {
  dumb: 125;        /* >99, 무시됨 */
  }

  @swash {
  swishy: 3 5;     /* swash에 값이 2개 이상, 문법 오류 */
  }
}

p.codeblock {
  /* ss03 = 1, ss04 = 1, ss05 = 1 의미 */
  font-variant-alternates: styleset(curly-quotes, code);
}

<@character-variant>에서는 1~99 사이의 단일 값이 OpenType 기능 cv01~cv99 활성화를 의미합니다. OpenType 폰트에서 99보다 크거나 0인 값은 무시되지만, 문법 오류는 아니며 어떤 기능도 활성화하지 않습니다. 두 개의 값이 나열되면 첫 번째 값이 기능, 두 번째 값이 해당 기능에 전달되는 값입니다. 한 이름에 두 개를 초과하는 값이 지정되면 문법 오류가 발생해 해당 기능 값 정의는 전체 무시됩니다.

@font-feature-values MM Greek {
  @character-variant { alpha-2: 1 2; }   /* cv01 = 2 의미 */
  @character-variant { beta-3: 2 3; }    /* cv02 = 3 의미 */
  @character-variant { epsilon: 5 3 6; } /* 2개 초과, 문법 오류로 정의 무시 */
  @character-variant { gamma: 12; }      /* cv12 = 1 의미 */
  @character-variant { zeta:   20 3; }   /* cv20 = 3 의미 */
  @character-variant { zeta-2: 20 2; }   /* cv20 = 2 의미 */
  @character-variant { silly: 105; }     /* >99, 무시됨 */
  @character-variant { dumb: 323 3; }    /* >99, 무시됨 */
}

#title {
  /* 세 번째 대체 beta, 첫 번째 대체 gamma 사용 */
  font-variant-alternates: character-variant(beta-3, gamma);
}

p {
  /* zeta-2가 zeta 뒤, cv20 = 2 의미  */
  font-variant-alternates: character-variant(zeta, zeta-2);
}

.special {
  /* zeta가 zeta-2 뒤, cv20 = 3 의미  */
  font-variant-alternates: character-variant(zeta-2, zeta);
}
비잔틴 인장에 맞춘 문자 변형 예시

비잔틴 인장 텍스트를 문자 변형으로 표시

위 그림에서 붉은색 텍스트는 8세기 비잔틴 인장에 나오는 문자 형태를 모방하는 문자 변형을 포함하는 폰트로 렌더링되었습니다. 아래 두 줄은 변형 없는 폰트로 표시된 동일한 텍스트입니다. 인장에 쓰인 U와 N이 각각 두 가지 변형으로 쓰인 점을 확인하세요.

@font-feature-values Athena Ruby {
  @character-variant {
  leo-B: 2 1;
  leo-M: 13 3;
  leo-alt-N: 14 1;
  leo-N: 14 2;
  leo-T: 20 1;
  leo-U: 21 2;
  leo-alt-U: 21 4;
  }
}

p {
  font-variant: discretionary-ligatures
  character-variant(leo-B, leo-M, leo-N, leo-T, leo-U);
}

span.alt-N {
  font-variant-alternates: character-variant(leo-alt-N);
}

span.alt-U {
  font-variant-alternates: character-variant(leo-alt-U);
}

<p>ENO....UP͞RSTU<span class="alt-U">U</span>͞<span class="alt-U">U</span>ΚΑΙTỤẠG̣IUPNS</p>

<p>LEON|ΚΑΙCONSTA|NTI<span class="alt-N">N</span>OS..|STOIBAṢ.|LIṢROM|AIO<span class="alt-N">N</span></p>

6.10. 동아시아 텍스트 렌더링: font-variant-east-asian 속성

이름: font-variant-east-asian
값: normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속
테스트

동아시아 텍스트에서 글리프 치환과 크기 제어를 할 수 있습니다.

<east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
<east-asian-width-values>   = [ full-width | proportional-width ]

각 값의 의미는 다음과 같습니다:

normal
아래 나열된 기능이 활성화되지 않습니다.
jis78
JIS78 형태로 렌더링합니다 (OpenType 기능: jp78).
JIS78 form example
jis83
JIS83 형태로 렌더링합니다 (OpenType 기능: jp83).
jis90
JIS90 형태로 렌더링합니다 (OpenType 기능: jp90).
jis04
JIS2004 형태로 렌더링합니다 (OpenType 기능: jp04).

다양한 JIS 변형은 일본 국가 표준에 정의된 글리프 형태를 반영합니다. 폰트에는 일반적으로 최신 국가 표준에 정의된 글리프가 포함되어 있지만, 경우에 따라 옛 형태를 사용해야 할 때가 있습니다 (예: 간판 등과 맞추기 위해).

simplified
간체 형태로 렌더링합니다 (OpenType 기능: smpl).
traditional
번체 형태로 렌더링합니다 (OpenType 기능: trad).

simplifiedtraditional 값은 시간이 지나면서 간소화된 문자에 대해 옛 형태(번체)가 여전히 일부 문맥에서 사용될 수 있도록 글리프 형태를 제어합니다. 어떤 문자와 글리프 형태가 포함되는지는 폰트가 설계된 문맥에 따라 조금씩 달라질 수 있습니다.

traditional form example
full-width
전각(풀-와이드) 형태로 렌더링합니다 (OpenType 기능: fwid).
proportional-width
비례폭 형태로 렌더링합니다 (OpenType 기능: pwid).
proportionally spaced Japanese example
ruby
루비 변형 글리프 표시를 활성화합니다 (OpenType 기능: ruby). 루비 텍스트는 일반적으로 본문보다 작기 때문에, 폰트 디자이너는 루비 전용 글리프를 별도로 디자인하여, 기본 글리프를 축소하는 것보다 더 읽기 쉽게 만들 수 있습니다. 글리프 선택만 영향을 받으며, 폰트 크기 조정이나 라인 레이아웃에 영향을 주는 변경은 없습니다.

아래 빨간색 루비 텍스트는 위는 기본 글리프(상단), 아래는 루비 변형 글리프로 표시됩니다. 획 두께에 약간 차이가 있음을 확인하세요.

ruby variant example

6.11. 폰트 렌더링 전체 약어: font-variant 속성

이름: font-variant
값: normal | none | [ [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ] || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ] || [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ] || [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] || [ sub | super ] || [ text | emoji | unicode ] ]
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속
테스트

font-variant 속성은 모든 font-variant 하위 속성에 대한 약어입니다:

normal 값은 font-variant의 모든 하위 속성을 초기값으로 재설정합니다. none 값은 font-variant-ligaturesnone으로 설정하고, 다른 모든 폰트 기능 속성은 초기값으로 재설정합니다. 다른 약어 속성과 마찬가지로, font-variant를 사용하면 명시하지 않은 font-variant의 하위 속성이 모두 초기값으로 재설정됩니다.

font-language-override, font-feature-settings, font-variation-settings의 값은 재설정되지 않습니다.

6.12. 로우레벨 폰트 기능 설정 제어: font-feature-settings 속성

이름: font-feature-settings
값: normal | <feature-tag-value>#
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 명시된 대로
정규 순서: 문법별
애니메이션 타입: 불연속
테스트

이 속성은 OpenType 폰트 기능을 로우레벨에서 제어할 수 있게 해줍니다. 널리 사용되지 않지만 특정 용도에 필요한 폰트 기능에 접근하는 용도로 설계되었습니다.

저자는 아래 표에 있는 폰트 기능을 설정할 때 font-feature-settings사용하지 말아야 합니다. 대신, 더 상위의 대체 속성을 사용하세요. 그 이유는:
  1. 상위 속성은 각각 개별적으로 캐스케이드됩니다. 전체 font-feature-settings 리스트를 설정하지 않아도 됩니다.
  2. 일부 상위 속성은 폰트가 해당 폰트 기능을 지원하지 않아도 합성해서 보여줄 수 있습니다.
이 폰트 기능을 설정하고 싶다면 font-feature-settings 대신 이것을 사용하세요 비고
장평(Kerning) (kern) 또는 세로 장평(Vertical Kerning) (vkrn) font-kerning: normal font-kerning 속성은 kern 또는 vkrn 기능을 writing-mode에 따라 설정합니다.
표준 합자(Standard Ligatures) (liga) 또는 문맥적 합자(Contextual Ligatures) (clig) font-variant-ligatures: common-ligatures
임의 합자(Discretionary Ligatures) (dlig) font-variant-ligatures: discretionary-ligatures
역사적 합자(Historical Ligatures) (hlig) font-variant-ligatures: historical-ligatures
문맥적 대체(Contextual Alternates) (calt) font-variant-ligatures: contextual
첨자(Subscript) (subs) font-variant-position: sub
윗첨자(Superscript) (sups) font-variant-position: super
스몰캡(Small Capitals) (smcp) font-variant-caps: small-caps
대문자에서 추출된 스몰캡(Small Capitals From Capitals) (c2sc) font-variant-caps: all-small-caps
프티캡(Petite Capitals) (pcap) font-variant-caps: petite-caps
대문자에서 추출된 프티캡(Petite Capitals From Capitals) (c2pc) font-variant-caps: all-petite-caps
유니케이스(Unicase) (unic) font-variant-caps: unicase
타이틀용 대문자(Titling) (titl) font-variant-caps: titling-caps
라이닝 숫자(Lining Figures) (lnum) font-variant-numeric: lining-nums
올드스타일 숫자(Oldstyle Figures) (onum) font-variant-numeric: oldstyle-nums
비례 숫자(Proportional Figures) (pnum) font-variant-numeric: proportional-nums
표 숫자(Tabular Figures) (tnum) font-variant-numeric: tabular-nums
분수(Fractions) (frac) font-variant-numeric: diagonal-fractions
대체 분수(Alternative Fractions) (afrc) font-variant-numeric: stacked-fractions
서수(Ordinals) (ordn) font-variant-numeric: ordinal
슬래시 0(Slashed Zero) (zero) font-variant-numeric: slashed-zero
역사적 형태(Historical Forms) (hist) font-variant-alternates: historical-forms
스타일 대체(Stylistic Alternates) (salt) font-variant-alternates: stylistic() 어떤 대체를 사용할지 지정하려면 @font-feature-values 규칙을 작성하세요
문자 변형 1~99(Character Variant 1 - Character Variant 99) (cv01 - cv99) font-variant-alternates: character-variant() 어떤 문자 변형을 사용할지 지정하려면 @font-feature-values 규칙을 작성하세요
스와시(Swash) (swsh) 또는 문맥적 스와시(Contextual Swash) (cswh) font-variant-alternates: swash() 어떤 스와시를 사용할지 지정하려면 @font-feature-values 규칙을 작성하세요
장식(Ornaments) (ornm) font-variant-alternates: ornaments() 어떤 장식을 사용할지 지정하려면 @font-feature-values 규칙을 작성하세요
대체 주석(Alternate Annotation Forms) (nalt) font-variant-alternates: annotation() 어떤 주석을 사용할지 지정하려면 @font-feature-values 규칙을 작성하세요
JIS78 형태(JIS78 Forms) (jp78) font-variant-east-asian: jis78
JIS83 형태(JIS83 Forms) (jp83) font-variant-east-asian: jis83
JIS90 형태(JIS90 Forms) (jp90) font-variant-east-asian: jis90
JIS2004 형태(JIS2004 Forms) (jp04) font-variant-east-asian: jis04
간체(Simplified Forms) (smpl) font-variant-east-asian: simplified
번체(Traditional Forms) (trad) font-variant-east-asian: traditional
전각(Full Widths) (fwid) font-variant-east-asian: full-width
비례폭(Proportional Widths) (pwid) font-variant-east-asian: proportional-width
루비 표기(Ruby Notation Forms) (ruby) font-variant-east-asian: ruby

예를 들어, 과학 첨자(화학식에서 사용되는 작은 숫자)를 제어하는 font-variant 값은 없습니다. 이들을 사용하면 가독성이 향상되므로 반드시 font-feature-settings로 활성화해야 합니다:

.chem {
  font-feature-settings: 'sinf'
}
화학식에서 과학 첨자 숫자
과학 첨자는 화학식의 가독성을 높여줍니다

전체 속성 값은 한 번에 설정됩니다. font-variant 속성과 달리, 상속된 값을 개별 기능을 추가하거나 제거하여 수정할 방법은 없습니다.

normal 값은 이 속성으로 인해 글리프 선택이나 위치가 변경되지 않음을 의미합니다.

기능 태그 값의 문법은 다음과 같습니다:

<feature-tag-value> = <opentype-tag> [ <integer [0,]> | on | off ]?
<opentype-tag> = <string>

<opentype-tag>는 대소문자를 구분하는 OpenType 기능 태그입니다. OpenType 명세 [OPENTYPE]에 따라, 기능 태그는 네 개의 ASCII 문자로 이루어집니다. 네 글자보다 길거나 짧거나, U+20–7E 코드포인트 범위를 벗어난 문자가 포함된 태그는 잘못된 값입니다. 기능 태그는 폰트에 정의된 태그와 일치하기만 하면 되므로, 반드시 명시적으로 등록된 OpenType 기능에 한정되지 않습니다. 커스텀 기능 태그를 정의하는 폰트는 OpenType 명세에서 정한 태그 이름 규칙을 따라야 합니다 [OPENTYPE-FEATURES].

폰트에 없는 기능 태그는 무시됩니다; 사용자 에이전트는 해당 기능 태그에 근거한 폴백 동작을 합성해서는 안 됩니다. 단 한 가지 예외로, 사용자 에이전트는 kerning 데이터가 kern 테이블에 있고 GPOS 테이블에 kern 기능 지원이 없는 경우, kern 기능을 합성적으로 지원할 수 있습니다.

일반적으로, kerning을 명시적으로 활성화/비활성화하고 싶을 때는 font-kerning 속성을 사용하는 것이 좋습니다. 이 속성은 kerning 데이터가 어느 방식이든 있는 폰트에 항상 적용됩니다.

값이 있으면 글리프 선택에 쓰이는 인덱스를 의미합니다. <integer> 값은 0 이상이어야 합니다. 값이 0이면 기능이 꺼집니다. 불리언 기능의 경우, 1이면 기능이 켜집니다. 불리언이 아닌 기능은 1 이상이면 기능이 켜지고 해당 선택 인덱스를 의미합니다. on은 1과 같고, off는 0과 같습니다. 값을 생략하면 1로 간주합니다.

font-feature-settings의 계산값은 맵(map) 형태이므로, 지정값에 중복된 기능 태그가 있으면 반드시 중복을 유지하지 않아야 합니다. 동일한 기능 태그가 여러 번 나타나면, 마지막에 지정된 값이 해당 축(axis)의 모든 이전 값을 대체합니다.

계산값에는 중복 제거된 기능 태그가 코드 유닛 오름차순으로 정렬되어 포함됩니다.

font-feature-settings: "sinf" 1;       /* sinf=1 과학 첨자 활성화 */
font-feature-settings: "sinf" on;      /* sinf=1 과학 첨자 활성화 */
font-feature-settings: 'sinf';         /* sinf=1 과학 첨자 활성화 */
font-feature-settings: "sinf" off;     /* sinf=0 과학 첨자 비활성화 */
font-feature-settings: "sinf", 'twid'; /* sinf=1, twid=1 과학 첨자와 Third Widths 활성화 */
font-feature-settings: "sinf" "twid";  /* 잘못된 문법, 콤마 구분 필요 */
font-feature-settings: "silly" off;    /* 잘못된 문법, 태그가 너무 김 */
font-feature-settings: "PKRN";         /* PKRN=1 커스텀 기능 활성화 */
font-feature-settings: sinf;           /* 잘못된 문법, 태그는 문자열이어야 함 */

폰트가 지원하는 범위를 넘어서는 값을 지정하면, 동작은 명확히 정의되지 않습니다. 불리언 기능의 경우 일반적으로 기능이 켜집니다. 불리언이 아닌 기능은 범위 밖 값이 일반적으로 0과 동등하게 처리됩니다. 하지만 두 경우 모두 실제 동작은 폰트의 설계 방식(특히 어떤 lookup 유형으로 기능을 정의했는지)에 따라 달라집니다.

OpenType 명세에서 항상 필수라고 규정한 기능(예: 필수 합자 "rlig")은 구현체가 끄는 요청을 무시할 수 있습니다.

테스트

font-feature-settings는 OpenType 기능 태그에 대해 정의되었지만, 폰트 기능을 지원하는 다른 최신 폰트 포맷에 대해서도 앞으로 추가될 수 있습니다. 가능한 경우, 다른 포맷에서 정의된 기능도 등록된 OpenType 태그 패턴을 따르도록 해야 합니다.

아래 일본어 텍스트는 반각 카나 문자로 렌더링됩니다:

body { font-feature-settings: "hwid"; /* 반각 OpenType 기능 */ }

<p>매일카레를 먹어도 질리지 않아요</p>

6.13. 폰트 언어 오버라이드: font-language-override 속성

이름: font-language-override
값: normal | <string>
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 지정된 문자열 또는 none 키워드
정규 순서: 문법별
애니메이션 타입: 불연속
테스트

일반적으로, 저자는 요소의 콘텐츠 언어를 설정해서 언어별 글리프 치환과 위치 제어를 할 수 있습니다. 위에서 설명한 대로:

<!-- S’gaw Karen 전용 기능으로 텍스트 표시 -->
<p lang="ksw">...</p>

경우에 따라, 저자는 콘텐츠 언어와 다른 언어 시스템을 지정해야 할 수 있습니다. 예를 들어, 다른 언어의 타이포그래피 전통을 모방해야 할 때. font-language-override 속성은 저자가 폰트의 언어 시스템을 명시적으로 지정할 수 있게 해주며, 콘텐츠 언어로 암시된 언어 시스템을 덮어쓸 수 있습니다.

각 값의 의미:

normal
OpenType 폰트로 렌더링할 때 요소의 콘텐츠 언어를 사용해 OpenType 언어 시스템을 추론함을 지정합니다
<string>
4글자, 대소문자 구분 OpenType 언어 시스템 태그 하나로, 요소의 언어 대신 사용할 OpenType 언어 시스템을 지정합니다. 문자열이 4글자보다 짧으면 끝에 공백(U+0020)으로 채워 4글자로 맞춘 후 매칭됩니다.

알 수 없는 OpenType 언어 시스템 태그는 조용히 무시되며, 글리프 선택 및 배치에 영향을 주지 않습니다.

7. 폰트 기능 및 변형 해석

앞에서 설명한 것처럼, 폰트 기능과 변형은 다양한 방식으로 활성화할 수 있습니다. 스타일 규칙에서 font-variant, font-feature-settings, fontfont-variation-settings를 사용하거나 @font-face 규칙 내에서 설정할 수 있습니다. 이 설정들의 합집합에 대한 해석 순서는 아래에 정의되어 있습니다. CSS 속성으로 정의된 기능은 레이아웃 엔진의 기본 기능 위에 적용됩니다.

7.1. 기본 기능

OpenType 폰트의 경우, 사용자 에이전트는 OpenType 문서에서 정의된 스크립트 및 문서 방향(writing mode)에 필요한 기본 기능을 반드시 활성화해야 합니다. 필수 합자, 일반 합자, 문맥적 형태는 기본값으로 활성화되어야 하며 (OpenType 기능: rlig, liga, clig, calt), 지역화 형태 (OpenType 기능: locl), 조합 문자 및 마크의 올바른 표시를 위한 기능 (OpenType 기능: ccmp, mark, mkmk)도 포함됩니다. 이 기능들은 항상 활성화되어야 하며, font-variantfont-feature-settings 속성 값이 normal일 때도 예외 없이 적용됩니다. 개별 기능은 저자가 명시적으로 오버라이드할 때만 비활성화됩니다. 예를 들어 font-variant-ligaturesno-common-ligatures로 설정한 경우입니다.

테스트

아랍어(Arabic)·몽골어(Mongolian)·데바나가리(Devanagari) 등 복잡한 스크립트를 처리하려면 추가 기능이 필요합니다. 세로 텍스트 내에서 직립 텍스트는 세로 대체(OpenType 기능: vert)가 반드시 활성화되어야 합니다.

7.2. 기능 및 변형 우선순위

일반 및 폰트별 폰트 기능 속성 설정은 아래 순서대로, 우선순위가 높은 방향으로 해석됩니다. 이 순서는 주어진 텍스트 런에 영향을 주는 폰트 기능을 합성 리스트로 만드는 데 사용됩니다.

  1. 기본적으로 활성화되는 폰트 기능이 적용됩니다. 여기에는 스크립트별로 요구되는 기능이 포함됩니다. 자세한 설명은 § 7.1 기본 기능을 참고하세요.

  2. font-weight, font-width, font-style 속성에 의해 활성화되는 폰트 변형이 적용됩니다.

    font-style 속성에 의해 활성화되는 값의 적용은 폰트 선택에 영향을 받습니다. 이 속성은 이탤릭 또는 오블리크 폰트를 선택할 수 있기 때문입니다. 적용되는 값은 폰트 스타일 매칭 알고리즘에 의해 결정된 가장 가까운 값입니다. 사용자 에이전트는 font-style 속성으로 한 가지 값만 적용해야 하며, "ital"과 "slnt" 값을 동시에 설정해서는 안 됩니다.

    선택된 폰트가 @font-face 규칙에서 정의된 경우, 이 단계에서 적용되는 값은 해당 @font-face 규칙의 font-weight, font-width, font-style 디스크립터 값에 클램프되어야 합니다.

    그리고 이 단계에서 적용된 값은 폰트에서 지원하는 값으로 다시 클램프되어야 합니다.

  3. lang/xml:lang의 상속된 값으로 지정한 언어가 적용됩니다.

  4. 폰트가 @font-face 규칙에서 정의된 경우, @font-face 규칙의 font-language-override 디스크립터가 암시하는 폰트 언어 오버라이드가 적용됩니다.

  5. 폰트가 @font-face 규칙에서 정의됐고, 그 @font-face 규칙에 font-named-instance 디스크립터가 하나 이상 있고 값이 none이 아니며, 로드된 폰트 리소스에 그 이름의 named instance가 § 5.1 로컬라이즈드 이름 매칭 규칙에 따라 있으면, 그 named instance가 나타내는 모든 변형 값이 적용됩니다. 이 값들은 폰트가 지원하는 값으로 클램프되어야 합니다.

  6. 폰트가 @font-face 규칙에서 정의된 경우, @font-face 규칙의 font-variation-settings 디스크립터가 암시하는 폰트 변형이 적용됩니다.

  7. 폰트가 @font-face 규칙에서 정의된 경우, @font-face 규칙의 font-feature-settings 디스크립터가 암시하는 폰트 기능이 적용됩니다.

  8. font-language-override 속성 값이 암시하는 폰트 언어 오버라이드가 적용됩니다.

  9. font-optical-sizing 속성 값에 의해 암시된 폰트 변형이 적용됩니다.

  10. font-variant 속성 값, 관련 font-variant 하위 속성, OpenType 기능을 사용하는 기타 CSS 속성(예: font-kerning) 값이 암시하는 폰트 기능이 적용됩니다.

  11. font-variant나 font-feature-settings가 아닌 다른 속성에 의해 결정되는 기능 설정이 적용됩니다. 예를 들어, letter-spacing 속성에 기본값이 아닌 값을 설정하면 선택적 합자가 비활성화됩니다.

  12. font-variation-settings 속성 값이 암시하는 폰트 변형이 적용됩니다. 이 값들은 폰트가 지원하는 값으로 클램프되어야 합니다.

  13. font-feature-settings 속성 값이 암시하는 폰트 기능이 적용됩니다.

테스트

이 순서 덕분에 저자는 @font-face 규칙에서 폰트에 대한 기본값 집합을 설정할 수 있고, 특정 요소에 대해 속성 설정으로 오버라이드할 수 있습니다. 일반 속성 설정이 @font-face 규칙 설정을 오버라이드하며, 로우레벨 폰트 기능 설정이 font-variant 속성 설정을 오버라이드합니다.

결합된 폰트 기능 설정 목록에 같은 기능에 대해 여러 값이 있으면, 마지막 값이 사용됩니다. 폰트가 특정 기본 기능을 지원하지 않는 경우, 텍스트는 해당 기능이 활성화되지 않은 것처럼 렌더링되고, 폰트 폴백이 발생하지 않으며, 명시적으로 특정 속성에서만 합성 처리가 시도됩니다.

7.3. 기능 우선순위 예시

아래 스타일에서는 숫자가 단락 내에서는 비례로, 가격표 테이블에서는 표 스타일로 렌더링됩니다:
body {
  font-variant-numeric: proportional-nums;
}

table.prices td {
  font-variant-numeric: tabular-nums;
}
@font-face 규칙은 @font-face 정의의 src 디스크립터에서 local()을 사용해 로컬 폰트의 폰트 기능에도 접근할 수 있습니다:
@font-face {
  font-family: BodyText;
  src: local("HiraMaruPro-W4");
  font-variant: proportional-width;
  font-feature-settings: "ital"; /* CJK 텍스트 내 라틴 이탤릭 기능 */
}

body { font-family: BodyText, serif; }

가능하다면, 일본어 폰트 "Hiragino Maru Gothic"이 사용됩니다. 텍스트 렌더링 시 일본어 카나는 비례폭으로, 라틴 텍스트는 이탤릭으로 표시됩니다. 폴백 serif 폰트로 렌더링된 텍스트는 기본 렌더링 속성을 사용합니다.

아래 예시에서, 임의 합자(discretionary ligatures)는 다운로드 폰트에만 활성화되고, "special" 클래스 span에서는 비활성화됩니다:
@font-face {
  font-family: main;
  src: url(fonts/ffmeta.woff) format("woff");
  font-variant: discretionary-ligatures;
}

body         { font-family: main, Helvetica; }
span.special { font-variant-ligatures: no-discretionary-ligatures; }

만약 아래처럼 임의 합자를 활성화하는 font-feature-settings 규칙을 추가한다면:

body         { font-family: main, Helvetica; }
span         { font-feature-settings: "dlig"; }
span.special { font-variant-ligatures: no-discretionary-ligatures; }

이 경우, "special" 클래스 span 내에서는 임의 합자가 표시됩니다. 이는 font-feature-settings와 font-variant-ligatures 속성이 모두 해당 span에 적용되기 때문입니다. font-variant-ligatures의 no-discretionary-ligatures 설정이 OpenType "dlig" 기능을 비활성화하지만, font-feature-settings가 그 뒤에 해석되므로, "dlig" 값이 임의 합자를 다시 활성화합니다.

8. 폰트 변형 속성

참고: 이 절에서 사용되는 기술은 "폰트 변형(font variations)"이라 불립니다. 이러한 폰트의 인스턴스를 "가변 폰트(variable font)"라고 합니다.

8.1. 광학 크기 제어: font-optical-sizing 속성

이름: font-optical-sizing
값: auto | none
초기값: auto
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 지정된 키워드
정규 순서: 문법별
애니메이션 타입: 불연속
테스트

타이포그래피적으로, 텍스트가 서로 다른 크기로 렌더링될 때 약간씩 다른 시각적 표현이 더 효과적일 때가 많습니다. 예를 들어, 작은 텍스트 크기에서는 읽기 편하도록 획이 더 두껍고 세리프가 더 크게 디자인됩니다. 큰 텍스트에서는 굵기 대비가 더 뚜렷하고 전체적으로 더 섬세한 형태를 갖습니다.

auto
사용자 에이전트는 font-size와 화면의 픽셀 밀도를 기준으로 글리프 형태를 수정할 수 있습니다. OpenType 및 TrueType 폰트에서 폰트 변형을 사용할 때, 이는 종종 "opsz" 폰트 변형을 통해 이루어집니다.
none
사용자 에이전트는 광학 크기 조절을 위해 글리프 형태를 수정해서는 안 됩니다.
서로 다른 광학 크기의 텍스트, 실제 크기를 맞춰서 비교
Century Expanded의 각 크기를 금속 활자 시절 그대로. 다른 광학 크기들은 여기서 같은 물리적 크기로 정규화되어 있지만, 스타일을 유지하고 가독성을 높이기 위한 디자인 변화를 담고 있습니다.

font-size는 "opsz" 축의 변형 값을 선택할 때 반드시 고려되어야 하며, 다른 신호 역시 고려될 수 있습니다.

참고: 사용자 에이전트는 "opsz" 축에 대해 font-size의 사용 값과 가까운 값을 제공해야 합니다. 그러나 사용자 에이전트는 화면의 픽셀 밀도, 또는 텍스트가 시야에 차지하는 실각(solid angle) 등 다른 요소도 고려할 수 있습니다. 실험 결과에 따르면 이런 부수적 요소를 무시하고 font-size만 사용하는 것이 사용자 에이전트가 이 값을 선택하는 데 가장 좋은 방법일 수 있습니다.

픽셀 밀도와 텍스트의 시각적 크기 모두 font-optical-sizing의 변형 값에 영향을 줄 수 있습니다. 픽셀 밀도나 텍스트의 시각적 크기가 사용자 조작이나 스타일 변경으로 인해 변할 때, 사용자 에이전트는 레이아웃이 변경되지 않는 한 새로운 변형 값을 선택해서는 안 됩니다. 어떤 변경이 레이아웃을 야기하는지 여부는 사용자 에이전트의 자유입니다.

참고: 예를 들어, 핀치-줌 같은 사용자 조작은 텍스트 재흐름이 없다면 레이아웃 변경이 아닌 것으로 간주할 수 있습니다. 하지만 접근성 목적으로 텍스트 크기를 키우는 등 텍스트가 재흐름될 경우엔 레이아웃 변경으로 간주할 수 있습니다. 마찬가지로 transform 속성은 일반적으로 텍스트 재흐름이 없으므로 레이아웃 변경이 아닌 것으로 간주할 수 있습니다. 각 사용자 에이전트는 각 동작이 레이아웃 변경인지 자유롭게 결정할 수 있습니다.

사용자 에이전트는 폰트가 직접 광학 크기 조절을 수행하지 않는 경우 광학 크기를 합성해서는 안 됩니다.

사용자 에이전트는 렌더링에 사용된 폰트가 지원하지 않는 "opsz" 축 값을 선택해서는 안 됩니다. 선택한 값은 폰트가 지원하는 범위로 클램프해야 합니다.

font-optical-sizingfont-size-adjust와 상호작용합니다. 광학 크기 조절을 적용할 때, 사용자 에이전트는 조정된 폰트 크기에 맞는 광학 크기 값을 위 규정에 따라 적용해야 합니다.

8.2. 로우레벨 폰트 변형 설정 제어: font-variation-settings 속성

이름: font-variation-settings
값: normal | [ <opentype-tag> <number>]#
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 키워드 normal 또는 각 항목이 문자열과 숫자 짝인 리스트
정규 순서: 문법별
애니메이션 타입: (상세 설명 참조)
테스트

이 속성은 OpenType 또는 TrueType 폰트 변형을 로우레벨에서 제어할 수 있게 해줍니다. 널리 사용되지 않지만 특정 용도에 필요한 폰트 변형에 접근하는 용도로 설계되었습니다.

저자는 아래 표에 있는 변형 축을 설정할 때 font-variation-settings사용하지 말아야 합니다. 대신, 더 상위의 대체 속성을 사용하세요. 그 이유는:
  1. 상위 속성은 각각 개별적으로 캐스케이드됩니다. 전체 font-variation-settings 리스트를 설정하지 않아도 됩니다.
  2. 일부 상위 속성은 폰트가 해당 폰트 변형을 지원하지 않아도 합성해서 보여줄 수 있습니다.
이 변형 축을 설정하고 싶다면 반드시 font-variation-settings 대신 이걸 사용하세요 비고
굵기(Weight) (wght) font-weight font-weight 속성이 wght 축을 설정합니다(있는 경우).
너비(Width) (wdth) font-width font-width 속성이 wdth 축을 설정합니다(있는 경우).
슬랜트(Slant) (slnt) 또는 이탤릭(Italic) (ital) font-style font-style 속성이 slnt 또는 ital 축을 설정합니다(값에 따라 다름).
광학 크기(Optical size) (opsz) font-optical-sizing font-optical-sizing 속성이 opsz 축을 설정합니다(있는 경우).

폰트 변형 설정을 사용해도 폰트 선택에는 영향을 주지 않으며, 폴백 폰트를 사용할 때, 같은 축에 대해 폰트 속성을 사용하면 폰트 선택에 영향을 줄 수 있습니다.

가능하다면, 저자는 일반적으로 폰트 변형 관련 다른 속성 (font-optical-sizing 등)을 사용해야 하며, 이 속성은 특별한 경우에만, 해당 폰트 변형을 유일하게 활성화할 방법일 때만 사용해야 합니다.

예를 들어, font-weight: 700을 사용하는 것이 font-variation-settings: "wght" 700보다 바람직합니다.

normal 값은 이 속성으로 인해 글리프 형태, 매칭, 위치가 변경되지 않음을 의미합니다.

<opentype-tag>는 대소문자 구분 OpenType 또는 TrueType 변형 축 이름입니다. OpenType / TrueType 명세에 따라, 축 이름은 네 개의 ASCII 문자로 이루어집니다. 축 이름이 네 글자보다 길거나 짧거나, U+20–7E 코드포인트 범위를 벗어난 문자가 포함된 경우는 잘못된 값입니다. 축 이름은 폰트에 정의된 태그와 일치하기만 하면 되므로, 반드시 등록된 OpenType / TrueType 변형 축에 한정되지 않습니다. 커스텀 축 이름을 정의하는 폰트는 OpenType 명세에서 정한 이름 규칙을 따라야 합니다.

폰트가 특정 축을 지원하지 않으면, 해당 값 설정은 무시되어 아무 효과가 없습니다; 사용자 에이전트는 이런 축 태그에 기반한 폴백 동작을 합성해서는 안 됩니다. 같은 CSS font-variation-settings 선언 내의 다른 축 값은 무시되지 않습니다.

폰트가 특정 변형 축을 지원하지만 지정된 값이 폰트의 사전 정의 범위보다 크거나 작으면, 폰트가 지원하는 가장 가까운 값으로 클램프됩니다.

값은 소수점이나 음수도 허용됩니다.

참고: 슬랜트된 글꼴(face)은 font-style 속성을 사용하는 게 바람직합니다. 하지만 slnt 축을 직접 font-variation-settings로 사용할 경우, 양수 각도가 반시계방향 슬랜트(즉, CSS와 반대 방향)임을 기억하세요.

같은 축 이름이 여러 번 나오면, 마지막에 지정된 값이 그 축의 모든 이전 값을 대체합니다. 이 중복 제거는 이 속성의 계산값을 통해 확인할 수 있습니다.

계산값에는 중복 제거된 축 이름이 코드 유닛 오름차순으로 정렬되어 포함됩니다.

OpenType / TrueType 변형에 대해 명시적으로 정의되어 있지만, 폰트 변형을 지원하는 다른 최신 폰트 포맷의 변형 축도 앞으로 추가될 수 있습니다. 가능한 경우, 다른 포맷에서 정의된 변형도 등록된 변형 축 패턴을 따르도록 해야 합니다.

font-variation-settings를 애니메이션하는 것은 아래 메커니즘을 통해 가능합니다. font-feature-settings 선언 두 개가 "like"할 때 애니메이션할 수 있습니다. "like" 선언이란 같은 속성 집합이(순서 상관없이) 등장하는 경우를 의미합니다. 연속된 중복 속성은 이전 중복 대신 적용되므로, 속성 개수가 달라도 "like"가 될 수 있습니다. 두 선언이 "like"이면 각각의 값 쌍끼리 애니메이션이 발생합니다. 그렇지 않으면 애니메이션할 수 없습니다. 이 경우, 애니메이션의 "from" 값이 애니메이션 도중에 "to" 값으로 전환됩니다(시점은 명확하지 않음).

9. 컬러 폰트 지원

컬러 폰트는 폰트 파일이 글리프의 윤곽뿐만 아니라, 글리프 내부에 있는 색상도 함께 기술할 수 있게 해줍니다.

다채로운 폰트 예시
Multicolore, Ivan Filipov 작품
다채로운 폰트 예시
Magical Unicorn Neue Pro, Arthur Reinders Folmer 작품

이모지 등 일부 용도에서는 폰트에 색상이 고정되어 있는 것이 적합합니다. 다른 용도에서는 스타일시트에서 사용되는 색상을 제어해야 할 필요가 있습니다.

테스트

CSS는 이를 위한 두 가지 방법을 제공합니다. font-palette 속성은 폰트에 포함된 여러 팔레트 중 하나를 선택할 수 있게 합니다. @font-palette-values 규칙은 팔레트 내부의 하나 이상의 색상을 오버라이드하거나, 완전히 새로운 팔레트를 만드는 것도 가능합니다.

9.1. 컬러 폰트 팔레트 제어: font-palette 속성

많은 컬러 폰트 파일 포맷은 글리프 내부의 색상을 파라미터로 지정할 수 있습니다. 이러한 폰트에서는 각 글리프의 기하학을 설명할 때 색상을 인덱스로 참조합니다. 이 인덱스는 폰트 내부의 룩업 테이블을 통해 현재 활성 팔레트에서 해석됩니다. 많은 폰트는 여러 팔레트를 포함하고 있으며, 각 팔레트는 폰트 디자이너가 보기 좋은 시각적 결과를 위해 선택한 보색 조합을 담고 있습니다.

또한 일부 컬러 폰트 파일 포맷은 일반(색상 없는) 글리프 외곽선도 제공하며, 컬러 버전도 함께 제공합니다.

이름: font-palette
값: normal | light | dark | <palette-identifier> | <palette-mix()>
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 지정된 키워드, 식별자 또는 <palette-mix()> 함수. <palette-mix()>가 결과적으로 동일한 팔레트라면 하나의 키워드 또는 식별자로 단순화해야 함.
정규 순서: 문법별
애니메이션 타입: 계산값 기준
테스트

palette-mix() 함수가 다음과 같이 정의된 상태에서:

<palette-mix()> = palette-mix(<color-interpolation-method> , [ [normal | light | dark | <palette-identifier> | <palette-mix()> ] && <percentage [0,100]>? ]#{2})
normal
color-scheme 속성이 normal 이외의 값으로 설정된 경우, 사용자 에이전트는 적절한 첫 번째 light 또는 dark 팔레트를 선택해야 합니다. 그렇지 않으면, 사용자 에이전트는 컬러 폰트를 기본 팔레트 또는 기본 글리프 색상화로 표시합니다.

컬러 폰트 포맷에서 전경색 사용이 필요한 경우, 사용자 에이전트는 color 속성의 계산값을 고려해야 합니다.

COLR [OPENTYPE] 테이블에서 color index 0xFFFF는 color 속성에 따라 렌더링해야 합니다.
COLR/CPAL [OPENTYPE] 폰트의 경우, font-palette: normal은 보통 폰트의 index 0에 있는 팔레트로 폰트를 렌더링함을 의미합니다.
light
일부 컬러 폰트 포맷은 특정 팔레트가 밝은(흰색에 가까운) 배경에 적합함을 나타내는 메타데이터를 포함합니다. 이 키워드는 사용자 에이전트가 폰트 파일에서 이렇게 표시된 첫 번째 팔레트를 사용하게 만듭니다. 폰트 파일 포맷에서 해당 메타데이터를 제공하지 않거나, 해당 표시가 된 팔레트가 없다면, 이 값은 normal과 동일하게 동작합니다.
dark
일부 컬러 폰트 포맷은 특정 팔레트가 어두운(검은색에 가까운) 배경에 적합함을 나타내는 메타데이터를 포함합니다. 이 키워드는 사용자 에이전트가 폰트 파일에서 이렇게 표시된 첫 번째 팔레트를 사용하게 만듭니다. 폰트 파일 포맷에서 해당 메타데이터를 제공하지 않거나, 해당 표시가 된 팔레트가 없다면, 이 값은 normal과 동일하게 동작합니다.
<palette-identifier>
이 값은 사용할 CSS에서 정의한 팔레트를 식별합니다. 사용자는 @font-palette-values 규칙을 사용해 팔레트를 정의할 수 있습니다. 적용 가능한 @font-palette-values 규칙이 없으면, 이 값은 normal과 동일하게 동작합니다.

<palette-identifier><dashed-ident>로 파싱됩니다.

참고: 이런 CSS에서 정의한 팔레트는 폰트에 이미 존재하는 팔레트를 참조하거나, 폰트에 존재하는 팔레트를 수정하거나, 완전히 새로운 팔레트가 될 수 있습니다.

<palette-mix()>
이 값은 <palette-identifier> 또는 팔레트 키워드 normal, light, dark, 또는 또 다른 <palette-mix()> 값을 통해 두 팔레트 값 사이의 보간 위치를 정의합니다.

폰트의 글리프는 첫 번째와 두 번째로 지정된 팔레트의 각 색상 인덱스 간에 매칭되는 색상 인덱스마다 보간하여 생성된 팔레트로 렌더링되어야 하며, 필요한 경우 <palette-mix()> 함수를 재귀적으로 해석합니다.

각 팔레트 색상에 대한 보간은 <color-mix()> 함수의 규칙을 따릅니다.

퍼센트 값은 CSS Color 5 § 2.1 퍼센트 정규화에 따라 정규화됩니다.

테스트

참고: lightdark 이름은 컬러 팔레트 자체의 색이 아니라, 그 팔레트가 사용될 배경을 설명합니다.

다크 모드일 때 다크 모드 팔레트 사용
@media (prefers-color-scheme: dark) {  .banner {font-palette: dark;
  }
}
팔레트 사이 애니메이션.
@font-palette-values --pink {
  font-family: Nabla;
  base-palette: 1;
}
@font-palette-values --yellow {
  font-family: Nabla;
  base-palette: 7;
}
@keyframes animate-palette {
  from {
    font-palette: --yellow;
  }
  to {
    font-palette: --pink;
  }
}
p {
  font-family: Nabla;
  animation: animate-palette 1.4s infinite alternate linear;
}
The word Animate animated between a pink and a yellow palette.
Nabla Color by typearture.com - 폰트의 팔레트 1과 7 사이를 애니메이션.
테스트

더 많은 예시와 그림을 추가하세요.

9.2. 사용자 정의 폰트 컬러 팔레트: @font-palette-values 규칙

@font-palette-values 규칙은 컬러 팔레트를 정의하고, 해당 컬러 팔레트를 특정 폰트에 연결합니다. 이를 통해 웹 저자는 컬러 폰트 내부의 기존 팔레트에 한정되지 않고, 임의의 <color>를 폰트 내부에 사용할 수 있습니다.

참고: OpenType CPAL 테이블은 sRGB 색상에만 제한됩니다. <color>@font-palette-values에서 모든 CSS 색상 사용이 가능합니다. 일부 구현은 현재 sRGB로 제한된 API를 사용하므로, 지정된 색상을 sRGB로 매핑할 수 있습니다. 이는 일시적인 제한이어야 하며, 저자는 이 sRGB 매핑에 의존하면 안 됩니다.

또한, 이 규칙이 특정 폰트와 연결되어 있기 때문에, 하나의 팔레트 이름이 폰트마다 다르게 적용될 수 있으며, 여러 폰트가 하나의 요소에서 함께 사용될 때(즉, 폰트 폴백), 여러 폰트에서 비슷한 색상을 사용할 수 있게 해줍니다.

참고: 웹 저자는 웹 콘텐츠에 여러 테마를 만들기 위해 하나의 폰트에 여러 팔레트를 만들 수 있습니다. 또한, 여러 폰트에 맞는 팔레트를 만들어 다양한 폰트에서도 일관된 디자인을 구현할 수 있습니다.

@font-palette-values 규칙은 폰트에서 사용되는 색상 팔레트를 나타냅니다. 팔레트는 색상의 순서 있는 집합입니다. @font-palette-values를 사용하면, 웹 저자는 폰트 내부의 팔레트를 참조하거나 저자가 지정한 색상으로 채워진 팔레트를 만들 수 있습니다. 또한, 폰트 내 팔레트의 일부 색상을 웹 저자가 지정한 색상으로 오버라이드할 수도 있습니다.

팔레트는 항상 완전해야 하며, 색상이 누락된 팔레트를 정의하는 것은 불가능합니다. 색상이 누락될 경우, base-palette 디스크립터로 지정된 폰트 내 팔레트에서 가져옵니다.

수학 함수(예: calc()), var(), env() 등도 @font-palette-values 규칙의 디스크립터 값에 사용할 수 있습니다. 이 함수들은 루트 요소 기준에서 평가됩니다. 상대 단위도 루트 기준에서 평가됩니다.

@font-palette-values 규칙은 @font-palette-values at-keyword 뒤에 디스크립터 선언 블록이 옵니다. 문법은 다음과 같습니다:

@font-palette-values <dashed-ident> {
    <declaration-list>
}
테스트

@font-palette-values 규칙은 이 명세에서 정의한 디스크립터만 허용합니다.

Bixa Color의 컬러 팔레트 변경.
@font-palette-values --Cooler {
    font-family: Bixa;
    base-palette: 1;
    override-colors:
        1 #7EB7E4;
}
overriding a color
Novo Typo의 Bixa Color. 위는 폰트의 원래 색상, 아래는 오렌지를 파란색으로 변경.
Handover Sans의 컬러 팔레트 변경
@font-palette-values --Augusta {
    font-family: Handover Sans;
    base-palette: 3;
    override-colors:
        1 rgb(43, 12, 9),
        3 var(--highlight);
}

이 디스크립터들은 해당 @font-palette-values 규칙 내에서만 적용되며, 문서의 언어 요소에는 적용되지 않습니다. 하나의 @font-palette-values 규칙 내에 특정 디스크립터가 여러 번 나오면, 마지막 선언만 사용되고 이전 선언은 모두 무시됩니다.

각 팔레트는 동일한 family name을 공유하는 각 @font-face에 적용됩니다.

두 컬러 폰트를 초록색 팔레트로 사용하고 싶을 때. 첫 번째 폰트 Bixxxa는 이미 쓸 수 있는 팔레트가 있고, Bungeehee는 초록 팔레트를 얻기 위해 한 색상을 덮어써야 합니다.
@font-face {
  font-family: Bixxxa;
  src: url('./bixxxa.woff') format('woff');
}

@font-face {
  font-family: Bungeehee;
  src: url('./bungeehee.woff') format('woff');
}

@font-palette-values --ToxicGreen {
  font-family: Bixxxa;
  base-palette: 3; /* 이것이 Bixxxa의 초록 팔레트 */
}


@font-palette-values --ToxicGreen {
  font-family: Bungeehee;
  base-palette: 7; /* 이것이 Bungeehee의 초록 팔레트... */
  override-colors: 2 lime; /* ...여기가 핑크인데 lime으로 덮어씀 */
}

h1 {
  font-family: Bixxxa;
  font-palette: --ToxicGreen;
}

h2 {
  font-family: Bungeehee;
  font-palette: --ToxicGreen;
}

예시: Roel Nieskens

참고: family name이 여러 실제 폰트에 공유될 때 (예: unicode-range로 복합 폰트를 만들 때), 폰트마다 팔레트가 다르면, @font-palette-values로 부분 팔레트를 지정하면 저자가 기대한 결과가 나오지 않을 수 있습니다. 이 경우에는 전체 팔레트 정의를 제공하는 것이 더 낫습니다.

위 예시에서, 두 개의 서로 다른 폰트 패밀리에 호환되는 팔레트 이름을 설정하면, 다음과 같이 작성할 수 있습니다:
h3 {
  font-family: Bixxxa, Bungeehee;
  font-palette: --ToxicGreen;
}

이렇게 하면 두 폰트가 팔레트 번호가 달라도, 원하는 팔레트가 각 폰트에 올바르게 적용됩니다.

주어진 @font-palette-values 규칙 집합이 해당 문서에서 사용할 수 있는 저자 정의 팔레트를 결정합니다.

저자 정의 폰트 컬러 팔레트는 해당 팔레트를 참조하는 문서에서만 사용할 수 있어야 합니다. 문서 외에서 저자 정의 컬러 팔레트를 쓰면 보안 누출이 발생하므로, 한 페이지의 내용이 다른 페이지에 영향을 줄 수 있고, 공격자가 이를 공격 벡터로 사용할 수 있습니다.

이 at-rule은 CSS의 미래 호환 파싱 규칙을 따릅니다. 선언 블록의 속성과 마찬가지로, 사용자 에이전트가 지원하지 않는 디스크립터 선언은 무시해야 합니다. @font-palette-values 규칙은 font-family 디스크립터가 필요합니다; 없으면 @font-palette-values 규칙 전체가 무효로 간주되어 무시됩니다.

사용자 에이전트가 플랫폼 리소스가 제한적이거나, 컬러 폰트 지원이 없거나, 컬러 폰트 비활성화 기능을 구현한 경우에는, @font-palette-values 규칙을 그냥 무시해야 하며, 이 명세에서 정의한 개별 디스크립터의 동작은 변경하지 않아야 합니다.

9.2.1. 폰트 패밀리: font-family 디스크립터

이름: font-family
적용 대상: @font-palette-values
값: <family-name>#
초기값: 해당 없음

이 디스크립터는 이 팔레트가 적용되는 폰트 패밀리를 정의하며, § 5 폰트 매칭 알고리즘과 동일한 폰트 패밀리 목록을 사용합니다. 이 팔레트는 오직 이 패밀리 이름을 가진 폰트에만 적용됩니다. 이 디스크립터의 값은 이름이 지정된 폰트 패밀리만 허용된다는 의미이며, 패밀리 목록에 generic 폰트가 포함된 규칙은 문법 오류가 됩니다. 폰트 패밀리 목록에 문법 오류가 있으면, 해당 디스크립터는 무시됩니다 (CSS OM에는 남아있지만 어떤 폰트 패밀리와도 매칭되지 않습니다).

9.2.2. 기본 팔레트 지정: base-palette 디스크립터

이름: base-palette
적용 대상: @font-palette-values
값: light | dark | <integer [0,∞]>
초기값: 해당 없음
light
일부 컬러 폰트 포맷은 특정 팔레트가 밝은(흰색에 가까운) 배경에 적합함을 나타내는 메타데이터를 포함합니다. 이 키워드는 폰트 파일에서 이렇게 표시된 첫 번째 팔레트를 식별합니다. 폰트 포맷이 해당 메타데이터를 포함하지 않거나, 해당 팔레트가 없으면, 이 값은 0처럼 동작합니다.
dark
일부 컬러 폰트 포맷은 특정 팔레트가 어두운(검은색에 가까운) 배경에 적합함을 나타내는 메타데이터를 포함합니다. 이 키워드는 폰트 파일에서 이렇게 표시된 첫 번째 팔레트를 식별합니다. 폰트 포맷이 해당 메타데이터를 포함하지 않거나, 해당 팔레트가 없으면, 이 값은 0처럼 동작합니다.
<integer>
폰트 내 (0부터 시작하는) 숫자 팔레트 인덱스를 식별합니다.
Banner Flag의 컬러 팔레트 변경
@font-palette-values --Festival {
    font-family: Banner Flag;
    base-palette: 1;
    override-colors:
        0 rgb(123, 64, 27),
        1 darkblue,
        2 var(--highlight);
}

이 디스크립터는 이 @font-palette-values 규칙에서 초기값으로 사용할 폰트 내 팔레트를 지정합니다. @font-palette-values 규칙에 <override-colors> 키가 없으면, 해당 @font-palette-values 규칙은 이 디스크립터의 값과 동일한 인덱스의 폰트 팔레트를 나타냅니다. <override-colors> 키가 있으면, 그 디스크립터 값의 각 항목이 이 @font-palette-values 블록이 나타내는 컬러 팔레트의 한 색상을 덮어씁니다.

Handover Sans의 3번째 컬러 팔레트 이름 지정
@font-palette-values --Augusta {
    font-family: Handover Sans;
    base-palette: 3;
}

이 디스크립터가 @font-palette-values에 없거나, 폰트에 base-palette 값의 인덱스가 없으면, 0이 지정된 것처럼 동작합니다. 폰트에 컬러 팔레트가 없으면, 해당 @font-palette-values 규칙이 나타내는 초기 컬러 팔레트에는 아무 색상도 포함되지 않습니다. 팔레트의 색상은 override-color 디스크립터를 사용해 덮어쓸 수 있습니다.

9.2.3. 팔레트의 색상 오버라이드: override-colors 디스크립터

이름: override-colors
적용 대상: @font-palette-values
값: [ <integer [0,∞]> <color> ]#
초기값: 해당 없음

이 디스크립터는 해당 @font-palette-values 규칙이 나타내는 초기 컬러 팔레트의 색상을 오버라이드합니다.

지정된 <color> 값은 절대 색상이어야 합니다.

override-colors 디스크립터는 팔레트 인덱스와 색상 값의 콤마로 구분된 리스트를 받습니다. 리스트의 각 아이템은 팔레트의 항목과 대체할 색상으로 이루어진 튜플을 나타냅니다.

이 디스크립터 값의 각 key/value 쌍마다, 초기 팔레트의 해당 key(즉 base-palette 디스크립터로 지정된 값)의 색상이 이 디스크립터 값에 지정된 색상으로 덮어씌워집니다. 초기 팔레트 인덱스 범위를 벗어난 key는 무시됩니다.

override-colors 디스크립터 내의 팔레트 인덱스 항목은 (0부터 시작하는) 팔레트 인덱스입니다.

정수값은 0부터 시작합니다.

다른 key/value 쌍이 같은 색상 인덱스(이름 또는 정수)로 지정된 경우, 렌더링 시에는 마지막 key가 적용됩니다. 단, 직렬화 시에는 두 쌍 모두 존재합니다.

참고: 이는 font-palette 속성에 같은 값을 두 요소에 사용해도, @font-palette-values 규칙 내부 변수 값이 두 요소의 컨텍스트에서 다르게 적용될 수 있어 실제로 사용되는 팔레트가 다를 수 있음을 의미합니다.

CSS에서 제공된 색상(오버라이드 또는 새 항목)은 지원되는 어떤 색공간도 사용할 수 있습니다.

Blaka Ink의 컬러 팔레트 변경
@font-palette-values --Festival {
  font-family: Blaka Ink;
  base-palette: 0;
  override-colors:
    0 oklch(0.63 0.12 105.7),
    1 color(display-p3 0.23 0.22 0.04),
    2 color(prophoto-rgb 0.37 0.27 0.09);
}

참고: CPAL 테이블 버전 0, 1에서 지정된 색상은 sRGB입니다.

9.3. 텍스트 표현 스타일 선택: font-variant-emoji 속성

이름: font-variant-emoji
값: normal | text | emoji | unicode
초기값: normal
적용 대상: 모든 요소 및 텍스트
상속됨: yes
백분율: 해당 없음
계산값: 지정된 키워드
정규 순서: 문법별
애니메이션 타입: 불연속
테스트

이 속성을 사용하면 웹 저자가 특정 emoji 코드 포인트에 대해 emoji 표현 또는 텍스트 표현을 사용할지 선택할 수 있습니다. 전통적으로 이러한 표현 스타일은 특정 코드 포인트 뒤에 Variation Selector 15 (U+FE0E) 또는 Variation Selector 16 (U+FE0F)을 붙여서 지정했습니다. 하지만 font-variant-emoji 속성을 사용하면 웹 저자가 기본 표현 스타일을 설정할 수 있어 variation selector를 대체할 수 있습니다.

이 속성의 영향을 받는 것은 Unicode에서 emoji 표현 시퀀스에 기여하는 것으로 리스트된 코드 포인트뿐입니다. 이 CSS 명세에서는 이러한 문자를 이모지 표현 참여 코드 포인트라고 합니다. 이 속성은 다른 문자에는 아무 영향도 없습니다.

이 속성은 폰트 폴백에도 영향을 줄 것으로 예상되지만, font-variant-emoji와 폰트 폴백의 상호작용은 명시적으로 지정하지 않습니다. 단, variation selector는 반드시 클러스터 매칭 절에서 정의한 대로 이전 클러스터에 포함되어야 합니다. 이 동작의 자연스러운 결과로, variation selector는 반드시 이전 문자와 같은 폰트로 렌더링되어야 하며 폰트 폴백이 해당 variation selector가 의도한 대로 동작하도록 만듭니다(값 설명 참고). 그 후 폰트 폴백, 즉 클러스터 폴백 규칙도 적용되며, 이 "붙인" variation selector의 표현 선호도도 고려해야 합니다.

font-variant-emoji를 사용하더라도, 요소의 내용에 Variation Selector 15 (U+FE0E) 또는 Variation Selector 16 (U+FE0F)이 있으면 font-variant-emoji에서 지정한 렌더링이 무시됩니다. 즉, font-variant-emoji는 텍스트가 렌더링될 때 기본 표현을 지정하지만, 실제 렌더링 시 이를 무시할 수도 있습니다.

참고: 플랫폼마다 emoji 표현 시퀀스 처리 방식이 다릅니다. 크로스 플랫폼 UA는 각 플랫폼의 관례를 따르거나, 모든 플랫폼에 같은 처리를 쓸 수 있습니다. emoji 스타일 렌더링 요청이 있을 때, UA는 컬러 테이블이 없는 폰트를 무시할 수도 있고, 또 다른 UA는 임의의 클러스터와 동일한 기계적 폴백 알고리즘을 사용할 수도 있습니다.

FE0E VARIATION SELECTOR-15, U+FE0F VARIATION SELECTOR-16을 제외한 variation selector는 폰트 선택에 아무 영향도 주지 않아야 합니다. 이 variation selector들이 있더라도 이전에 선택된 폰트가 지원하지 않으면, variation selector는 무시됩니다.

BCP47의 -u- 언어 태그 확장(lang 또는 xml:lang에서 사용)은 UA가 특정 문자에 대해 emoji 표현 또는 텍스트 표현을 쓸지 결정할 때 고려해서는 안 됩니다.

normal
사용자 에이전트는 이모지 표현 참여 코드 포인트를 emoji 스타일 또는 텍스트 스타일로 그릴 수 있습니다. 일반적으로 사용자 에이전트는 플랫폼 관례를 따릅니다.
text
코드 포인트마다 U+FE0E VARIATION SELECTOR-15가 붙은 것처럼 렌더링됩니다.
emoji
코드 포인트마다 U+FE0F VARIATION SELECTOR-16이 붙은 것처럼 렌더링됩니다.
unicode
[UTS51]에 따라 emoji-default, text-default, text-only로 각 이모지 표현 참여 코드 포인트의 Emoji, Emoji_Presentation 속성값에 따라 렌더링됩니다. FE0E VARIATION SELECTOR-15, U+FE0F VARIATION SELECTOR-16이 있으면 해당 코드 포인트의 기본 표현을 덮어씁니다.
U+1F6CB COUCH AND LAMP의 emoji 형태를 보여주려면, CustomEmoji.ttf가 해당 문자에 emoji 형태를 지원하도록 다음을 사용합니다:
@font-face {
  font-family: "Custom Emoji";
  src: url("CustomEmoji.ttf") format("truetype");
}
...
<div style="font-family: 'Custom Emoji'; font-variant-emoji: emoji;">&#x1F6CB;</div>

10. 폰트 분류

하나의 폰트는 다음 범주 중 하나 또는 여러 개에 속할 수 있습니다:

10.1. 설치된 폰트

폰트는 기기에 전역적으로 설치될 수 있습니다. 이런 폰트는 일반적으로 모든 애플리케이션에서 접근 가능하며, CSS 개념이 없는 애플리케이션에서도 사용됩니다. 폰트 객체를 뒷받침하는 파일들은 사용자의 기기에 존재하며, 원격 리소스가 아닙니다.

설치된 폰트는 웹 폰트가 되어서는 안 되며, 웹 폰트도 설치된 폰트가 되어서는 안 됩니다.

10.2. 웹 폰트

폰트는 원격 리소스를 통해 제공될 수 있으며, 반드시 사용자 에이전트의 리소스 페칭 인프라를 사용해 요청해야 합니다. 웹 폰트는 두 가지 메커니즘으로 표현됩니다:

웹 폰트는 해당 @font-face 규칙과 연결되었거나 FontFaceSet을 소유한 문서에서만 접근 가능해야 합니다. 기기의 다른 애플리케이션에서는 웹 폰트에 접근할 수 없어야 합니다.

설치된 폰트는 웹 폰트가 되어서는 안 되며, 웹 폰트도 설치된 폰트가 되어서는 안 됩니다.

웹 폰트는 설치된 폰트를 가립니다. 즉, 설치된 폰트와 웹 폰트가 같은 패밀리명을 가지고 있다면, 설치된 폰트는 접근할 수 없습니다.

10.3. 사전 설치 폰트와 사용자 설치 폰트

사용자는 기기에 폰트를 직접 설치할 수 있습니다. 사용자 설치 폰트는 "설치" 버튼 클릭, 또는 특정 디렉토리에 파일을 복사하는 등 사용자가 직접 실행하는 작업을 통해 설치됩니다. 이런 폰트는 사용자 설치 폰트이자 설치된 폰트입니다. 웹 콘텐츠 저자는 사용자 설치 폰트의 존재를 당연하게 생각해서는 안 됩니다. 왜냐하면 어떤 사용자가 특정 폰트를 설치했을지 확신할 수 없기 때문입니다.

사용자 설치 폰트가 폰트 매칭 알고리즘과 어떻게 상호작용하는지에 대해서는 폰트 매칭 알고리즘 설명을 참고하세요.

사용자 설치 폰트가 아닌 모든 설치된 폰트는 사전 설치 폰트입니다. 특정 운영체제의 특정 버전을 사용하는 모든 사용자가 동일한 사전 설치 폰트 집합을 가지고 있을 가능성이 높습니다. 따라서, 웹 콘텐츠 저자는 해당 OS를 대상으로 할 때 이들 폰트의 패밀리명을 font-family 속성에 사용할 수 있습니다.

10.4. 시스템 폰트

시스템 폰트는 system-ui 일반 폰트 패밀리명에서 사용되는 폰트입니다. 이는 사전 설치 폰트의 한 예입니다.

테스트

11. 폰트 기술 및 포맷

11.1. 폰트 기술

features-opentype, features-aat, features-graphite 기술은 폰트 기능 지원을 의미하며, [OPENTYPE]에서는 GSUB, GPOS 테이블, [AAT-FEATURES]에서는 morx, kerx 테이블, [GRAPHITE]에서는 Silf, Glat , Gloc , Feat , Sill 테이블 등과 같이 구현됩니다. § 6 폰트 기능 속성 절에서 이 기능들과 상호작용하는 속성을 설명합니다.

variations 기술은 폰트 변형 지원을 의미하며, [OPENTYPE]에서는 avar, cvar, fvar, gvar, HVAR, MVAR, STAT, VVAR 테이블, [AAT-FEATURES]에서는 avar, cvar, fvar, gvar 테이블 등이 해당됩니다. § 2 기본 폰트 속성§ 8 폰트 변형 속성 절에서 이 기능들과 상호작용하는 속성을 설명합니다.

color-colrv0, color-colrv1, color-svg, color-sbix, color-cbdt 기술들은 여러 종류의 컬러 폰트 파일 기술을 의미합니다. 각 기술은 [OPENTYPE] 또는 [AAT-FEATURES] 폰트 내부에 존재하는 COLR, SVG, sbix, CBDT 테이블을 의미하며, 해당 요구를 충족시키기 위해 반드시 지원해야 합니다.

palettes 기술은 폰트 팔레트 지원을 의미하며, [OPENTYPE], [AAT-FEATURES]에서는 CPAL 테이블로 구현됩니다. § 9 컬러 폰트 지원 절에서 이 기능들과 상호작용하는 속성을 설명합니다.

incremental-patch, incremental-range, incremental-auto 기술은 클라이언트의 점진적 폰트 전송 [IFT] 지원을 의미하며, patch-subset, range-request 또는 자동 협상 방식을 사용할 수 있습니다.

배경 자료로는 [PFE-report]를 참고하세요.

웹 저자는 @font-face src 디스크립터 내 tech 함수를 사용해 폰트의 올바른 렌더링에 필요한 지원을 지정할 수 있습니다. 이 메커니즘은 요청된 지원이 없을 때 보조 폰트로 우아하게 폴백하는 데 사용할 수 있습니다.

아래 @font-face 블록은 사용자 에이전트가 지원하는 경우 컬러 폰트를, 지원하지 않으면 컬러가 없는 폰트로 폴백하는 방법을 보여줍니다.
@font-face {
    font-family: "Trickster";
    src: url("trickster-COLRv1.otf") format(opentype) tech(color-COLRv1),
  url("trickster-outline.otf") format(opentype);
}

11.2. 폰트 포맷

이 명세에서 정의된 포맷 문자열은 아래와 같습니다. <font-format> 값은 아래 포맷의 동의어입니다.

문자열 폰트 포맷 일반 확장자 일반 미디어 타입
"collection" OpenType Collection .otc,.ttc font/collection
"embedded-opentype" Embedded OpenType .eot application/vnd.ms-fontobject
"opentype" OpenType .ttf, .otf font/otf, font/ttf
"svg" SVG 폰트 (폐지됨) .svg, .svgz image/svg+xml
"truetype" TrueType .ttf font/ttf
"woff" WOFF 1.0 (웹 오픈 폰트 포맷) .woff font/woff
"woff2" WOFF 2.0 (웹 오픈 폰트 포맷) .woff2 font/woff2
테스트

TrueType과 OpenType의 일반 사용이 겹치므로, "truetype"과 "opentype" 포맷 힌트는 동의어로 간주해야 합니다. "opentype"이라는 포맷 힌트가 폰트에 Postscript CFF 스타일 글리프 데이터가 들어 있거나 OpenType 레이아웃 정보가 들어 있음을 의미하지는 않습니다 (자세한 내용은 부록 A 참조).

12. 오브젝트 모델

@font-face@font-feature-values 규칙의 내용은 다음과 같이 CSS 오브젝트 모델에 대한 확장을 통해 접근할 수 있습니다.

테스트

12.1. CSSFontFaceRule 인터페이스

CSSFontFaceRule 인터페이스는 <@font-face> 규칙을 나타냅니다.

[Exposed=Window]
interface CSSFontFaceRule : CSSRule {
  readonly attribute CSSStyleDeclaration style;
};

12.2. CSSFontFeatureValuesRule 인터페이스

CSSRule 인터페이스는 아래와 같이 확장됩니다:

partial interface CSSRule {  const unsigned short FONT_FEATURE_VALUES_RULE = 14;
};

CSSFontFeatureValuesRule 인터페이스는 @font-feature-values 규칙을 나타냅니다.

[Exposed=Window]
interface CSSFontFeatureValuesRule : CSSRule {
  attribute CSSOMString fontFamily;
  readonly attribute CSSFontFeatureValuesMap annotation;
  readonly attribute CSSFontFeatureValuesMap ornaments;
  readonly attribute CSSFontFeatureValuesMap stylistic;
  readonly attribute CSSFontFeatureValuesMap swash;
  readonly attribute CSSFontFeatureValuesMap characterVariant;
  readonly attribute CSSFontFeatureValuesMap styleset;
};

[Exposed=Window]
interface CSSFontFeatureValuesMap {
  maplike<CSSOMString, sequence<unsigned long>>;
  undefined set(CSSOMString featureValueName,
         (unsigned long or sequence<unsigned long>) values);
};
fontFamily of type CSSOMString
특정 폰트 패밀리 집합에 대해 정의된 하나 이상의 폰트 패밀리 목록입니다.
value maps of type CSSFontFeatureValuesMap, readonly
특정 font-variant-alternates 값 타입에 대해 feature value 이름에 연결된 feature value의 맵입니다.

CSSFontFeatureValuesRule의 각 value map attribute는 해당 feature value block을 통해 정의된 값을 반영합니다. 즉, annotation attribute는 @annotation feature value block 내에 들어있는 값을 담고 있고, ornaments attribute는 @ornaments feature value block의 값을 담고 있습니다.

CSSFontFeatureValuesMap 인터페이스는 기본 map 클래스 메서드를 사용하지만, set 메서드는 다르게 동작합니다. 이 메서드는 unsigned integer의 시퀀스를 받아서 특정 featureValueName에 연결합니다. 이 메서드는 기본 map 클래스와 동일하게 작동하지만, 단일 unsigned long 값이 들어오면 단일 값 시퀀스로 처리합니다. 부적절한 개수의 값이 들어오면 예외를 발생시킵니다. 만약 연결된 feature value block이 허용하는 값의 개수가 제한되어 있다면, set 메서드는 입력 시퀀스가 제한을 초과하면 InvalidAccessError 예외를 던집니다. 각 타입의 feature value block별 허용 최대 개수는 다중 값 feature value 정의를 참고하세요. get 메서드는 항상 시퀀스를 반환합니다(단일 값이라도).

12.3. CSSFontPaletteValuesRule 인터페이스

[Exposed=Window]interface CSSFontPaletteValuesRule : CSSRule {
  readonly attribute CSSOMString name;
  readonly attribute CSSOMString fontFamily;
  readonly attribute CSSOMString basePalette;
  readonly attribute CSSOMString overrideColors;
};

fontFamilybasePalette 인터페이스는 해당 CSS 속성 문법에 따라 파싱됩니다.

13. 직렬화

13.1. 폰트 관련 속성 직렬화

개별 속성에 대해 특별히 명시된 경우를 제외하고, 이 모듈에서 정의된 속성들은 CSSOM § 6.7.2 CSS 값 직렬화의 원칙을 따릅니다.

테스트

13.2. 폰트 관련 at-rule 직렬화

개별 디스크립터에 대해 특별히 명시된 경우를 제외하고, 이 모듈에서 정의된 at-rule용 디스크립터들은 CSSOM § 6.7.2 CSS 값 직렬화의 원칙을 따릅니다.

특히, 더 짧은 표현 원칙에 따라: 값 범위를 허용하는 디스크립터의 경우, 시작 값과 끝 값이 같으면(범위가 0이면) 디스크립터는 범위 대신 단일 값으로 직렬화됩니다.

테스트
예를 들어, 다음 규칙은
@font-face {
  font-family: "foo";
  font-weight: 200 200;
}

다음과 같이 직렬화됩니다

@font-face {
  font-family: "foo";
  font-weight: 200;
}

또한, 마지막에 정의된 값만 유지하는 원칙과 더 짧은 표현 원칙을 따라, 여러 번 지정된 튜플과 여러 블록은 마지막에 지정된 값만 포함하는 단일 블록으로 직렬화됩니다.

예를 들어 다음 선언:
/* 선언 이름 반복, 동일 타입 블록 여러 개 */
@font-feature-values foo {
  @swash { pretty: 0; cool: 2; }
  @swash { pretty: 1; }
}

다음과 같이 직렬화됩니다:

/* 정규 직렬화 */
@font-feature-values foo {
    @swash { cool: 2; pretty: 1; }
}

부록 A: 플랫폼 폰트 속성과 CSS 속성 매핑

이 부록은 다른 섹션에서 설명된 문제와 상황에 대한 배경 자료입니다. 정보 제공용으로만 참고하세요.

CSS의 폰트 속성은 사용되는 폰트 포맷과 독립적으로 설계되었습니다; 비트맵 폰트, Type1 폰트, SVG 폰트, 그리고 일반적인 TrueType 및 OpenType 폰트 모두를 지정할 수 있습니다. 그러나 TrueType과 OpenType 포맷의 특성 때문에 저자들이 혼란을 겪거나 플랫폼별 구현에서 어려움이 발생하는 경우가 많습니다.

Apple에서 처음 개발된 TrueType [TRUETYPE]은 화면과 인쇄 모두를 위한 윤곽선 폰트 포맷으로 설계되었습니다. 이후 Microsoft가 Apple과 함께 TrueType 포맷을 개발했고, 두 플랫폼 모두 TrueType 폰트를 지원해왔습니다. TrueType 포맷의 폰트 데이터는 공통 4글자 태그명으로 구분되는 테이블 집합으로 구성되어 있으며, 각 테이블은 특정 종류의 데이터를 담고 있습니다. 예를 들어, 저작권 및 라이선스 정보를 포함한 이름 정보는 name 테이블에 저장됩니다. character map (cmap) 테이블은 문자 인코딩과 글리프의 매핑을 담고 있습니다. 이후 Apple은 향상된 타이포그래피 기능을 지원하기 위해 추가 테이블을 도입했고, 이를 Apple Advanced Typography(AAT) 폰트라고 부릅니다. Microsoft와 Adobe는 고급 타이포그래피용 별도의 테이블 집합을 개발해 OpenType [OPENTYPE] 포맷을 만들었습니다. OpenType 명세는 ISO에서 Open Font Format [OPEN-FONT-FORMAT]으로 표준화되어 있습니다.

많은 경우 Microsoft Windows나 Linux에서 사용하는 폰트 데이터는 Apple의 Mac OS X에서 사용하는 데이터와 약간 다릅니다. TrueType 포맷이 플랫폼별 명시적 변화를 허용했기 때문입니다. 여기에는 폰트 메트릭, 이름, character map 데이터가 포함됩니다.

특히, 폰트 패밀리 이름 데이터는 플랫폼마다 다르게 처리됩니다. TrueType 및 OpenType 폰트의 경우 이 이름들은 name 테이블의 name ID 1 레코드에 들어 있습니다. 로케일마다 여러 이름을 저장할 수 있지만, Microsoft는 항상 미국 영어 버전의 이름을 포함할 것을 권장합니다. Windows에서는 하위 호환성을 위해 폰트 패밀리 이름을 최대 4개 얼굴로 제한했습니다; 더 큰 그룹은 "preferred family"(name ID 16) 또는 "WWS family"(name ID 21)를 사용할 수 있습니다. OSX 같은 다른 플랫폼에는 이런 제한이 없어서, 패밀리 이름으로 모든 그룹을 정의할 수 있습니다.

다른 name 테이블 데이터는 패밀리 내에서 특정 페이스(face)를 고유하게 식별하는 이름을 제공합니다. 전체 폰트 이름(name ID 4)과 포스트스크립트 이름(name ID 6)은 단일 페이스를 고유하게 설명합니다. 예를 들어, Gill Sans 패밀리의 Bold 페이스는 전체 이름이 "Gill Sans Bold"이고 포스트스크립트 이름이 "GillSans-Bold"입니다. 하나의 페이스에 대해 여러 지역화된 전체 이름이 있을 수 있지만, 포스트스크립트 이름은 항상 제한된 ASCII 문자 집합으로 만들어진 고유한 이름입니다.

플랫폼마다 폰트를 검색할 때 사용하는 이름이 다릅니다. 예를 들어, Windows의 GDI CreateIndirectFont API에서는 패밀리 또는 전체 이름을 사용해 페이스를 찾을 수 있고, Mac OS X의 CTFontCreateWithName API 호출에서는 전체 이름과 포스트스크립트 이름을 사용해 페이스를 찾습니다. Linux에서는 fontconfig API가 이들 이름 중 아무거나 사용해 폰트를 검색할 수 있도록 허용합니다. 플랫폼 API가 자동으로 다른 폰트로 대체하는 상황에서는, 반환된 폰트가 지정한 이름과 일치하는지 확인할 필요가 있을 수 있습니다.

특정 페이스의 두께(weight)는 OS/2 테이블의 usWeightClass 필드로 결정하거나, 스타일 이름(name ID 2)에서 유추할 수 있습니다. 마찬가지로, 폭(width)은 OS/2 테이블의 usWidthClass 필드로 결정하거나, 스타일 이름에서 유추할 수 있습니다. Windows의 GDI API에서 200 이하의 두께에 대해 합성 볼딩(synthetic bolding)이 발생했던 역사적 이유로, 폰트 디자이너들은 때때로 OS/2 테이블의 값을 왜곡해 이런 두께를 피하기도 했습니다.

태국어, 아랍어, 데바나가리처럼 문맥적 셰이핑(contextual shaping)을 사용하는 복잡한 스크립트를 렌더링하려면 오직 OpenType 또는 AAT 폰트에만 있는 기능이 필요합니다. 현재는 Windows와 Linux에서는 OpenType 폰트 기능을 사용해 복잡한 스크립트 렌더링이 지원되고, Mac OS X에서는 OpenType과 AAT 폰트 기능이 모두 사용됩니다.

14. 보안 고려 사항

아래의 셀프 리뷰 설문지에서 9, 16, 17 항목을 참고하세요.

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

보안 및 개인정보 셀프 리뷰 설문지§ 10 폰트 분류를 기반으로:

15.1. 이 기능이 웹사이트나 다른 당사자에 노출할 수 있는 정보는 무엇이며, 그 노출이 필요한 목적은 무엇인가요?

이 명세는 웹 폰트 사용을 허용하며, 웹 폰트는 필요할 때 요청되지만 설치되지는 않습니다. 문서나 스타일시트가 웹 폰트와 다른 오리진인 경우, 네트워크 요청에서 Referer 헤더가 노출되어 폰트 제공자가 수집할 수 있습니다.

웹 폰트 외에도, 이 명세는 CSS1에서 도입된 대로 설치된 폰트(사전 설치 폰트와 사용자 설치 폰트 모두)의 사용도 계속 허용합니다.

웹 폰트는 플랫폼 간 일관성이라는 장점이 있지만, 설치된 폰트는 다운로드 시간이 없다는 장점이 있습니다.

특히 지원이 부족한 언어나 소수 언어의 경우, 설치된 폰트가 없으면 표시할 수 없는 정보를 보여줄 수 있습니다. 무료로 사용 가능한 웹 폰트가 없거나, 대기 시간 또는 다운로드 시간이 너무 길어 웹 폰트 사용이 어려운 경우(특히 글자 수가 많은 언어, 느린 네트워크 등) 그렇습니다.

참고: 설치된 폰트의 집합은 폰트 매칭 알고리즘에서 명시적으로 정의되어 있지 않습니다. 사용 가능한 폰트 집합은 트래커들이 사용자 지문(핑거프린팅)에 사용하여 개인정보를 침해합니다. 그러나 일부 설치된 폰트, 심지어 일부 사용자 설치 폰트도 언어 가독성을 위해 필요합니다. 사용자 에이전트는 언어 지원 및 디자인 일관성을 위해 모든 설치된 폰트를 제공할 수도, 개인정보 보호를 위해 일부 폰트를 제공하지 않을 수도 있습니다. 추가로, 사용자 에이전트는 사용자가 요청된 폰트를 명시적으로 허용/차단하도록 선택할 수 있는 인터페이스(사이트별 등)를 제공할 수도 있습니다. 동일한 운영체제에서도 사용자 에이전트마다 이 균형점이 다를 수 있습니다.

로컬 리소스를 렌더링하는 사용자 에이전트의 경우 (예: HTML/CSS를 PDF로 렌더링하거나 웹 기반 워드프로세서 등) 모든 설치된 폰트(사전 설치 및 사용자 설치 폰트 모두)에 접근해야 예상 기능을 제공할 수 있습니다.

공격자는 설치된 폰트를 조회하여 지문 정보를 얻을 수 있습니다. 과거 기술(특히 Adobe Flash는 설치된 폰트 전체 목록을 제공하고 HTTP 헤더로 전송)과 달리, 이런 탐색은 폰트마다 하나씩 해야 하며, 폰트 패밀리 이름을 제공하고 (스크립트로 혹은 unicode-range를 이용해 웹 폰트를 조건부 다운로드하면서) 특정 이름의 폰트가 특정 글자를 지원하는지 확인합니다. 이 과정은 시간이 걸리며, 수백 개 이상의 폰트를 확인하면 페이지 렌더링에 눈에 띄는 지연이 생깁니다.

특히 개인정보 보호가 중요한 환경에서는 웹 폰트를 아예 다운로드하지 않거나(몇몇 글자가 잘못 렌더링되거나 아예 보이지 않을 수 있음), 필요 여부와 상관없이 모든 웹 폰트를 항상 다운로드(매번 많은 불필요한 폰트 다운로드)하는 방법도 있습니다.

15.2. 이 명세는 기능 제공에 필요한 최소한의 정보만 노출하고 있나요?

최근 합의에 따르면 사용자 에이전트는 올바른 기능을 위해 사전 설치 폰트를 노출해야 하지만, 사용자 설치 폰트 노출에 대한 합의는 없습니다. 이 명세는 사용자 에이전트가 폰트 매칭 알고리즘에서 사용자 설치 폰트를 무시할 수 있도록 허용합니다. 이미 여러 사용자 에이전트가 이렇게 동작합니다.

최소 정보량은 사용자 유형에 따라 다르며 현재 논의 중입니다. 사용자 설치 폰트 사용자 분류약간 확장되었습니다.

허용적인 정보 노출은 지문 정보도 더 많이 노출될 수 있습니다. 제한적인 정보 노출은 지문 정보는 줄이지만 기능도 줄이고, 소수 언어 등에서는 웹 사용 자체가 불가능해질 수도 있습니다.

일부 또는 전체 사용자 설치 폰트 노출을 사용자별 또는 오리진별로 선택적으로 허용하는 기능에 대한 논의가 있습니다.

프라이버시 예산이라는 개념도 논의되었습니다. 악의적인 웹페이지가 많은 폰트를 테스트하면 페널티 또는 비활성화되지만, 소수만 테스트하는 경우 정상 동작하도록 하는 방식입니다.

일부 사용자 에이전트는 프라이빗 브라우징, 시크릿 모드, '지문 방지' 모드에서는 일반 모드보다 더 제한된 사전 설치 폰트 집합을 노출합니다.

15.3. 이 명세는 개인정보 또는 개인 식별 정보 혹은 그로부터 파생된 정보를 어떻게 처리합니까?

이 명세는 개인정보를 노출하지 않습니다.

일부 경우에는 개인 식별 정보가 노출될 수 있습니다. 예를 들어, 일본에서 조건부로 활성화된 일본어 폰트가 나열 가능해도 보통 큰 지문 위험이 아닙니다. 반면, 유럽에서 텍스트 입력 메뉴에 일본어 IME가 있으면 지문 위험이 됩니다.

15.4. 이 명세는 민감한 정보를 어떻게 처리합니까?

설치된 폰트에 대한 지문 추출은 일부 경우 민감한 정보를 노출할 수 있습니다. 예를 들어, 박해받는 소수민족은 해당 언어용 폰트를 사용함으로써 민감 정보를 노출할 위험이 있습니다. 제3자 서비스에서 웹 폰트를 요청하거나, 해당 언어와 관련된 사전 설치/사용자 설치 폰트를 노출함으로써 그렇습니다.

15.5. 이 명세는 브라우징 세션 간 오리진에 대한 새로운 상태를 도입합니까?

아닙니다.

특히, 웹 폰트는 해당 @font-face 규칙과 연결된 문서 또는 FontFaceSet을 소유한 문서 외에는 접근할 수 없어야 하며, 기기 내 다른 애플리케이션은 웹 폰트에 접근할 수 없어야 합니다. 이렇게 하면 오리진 간 정보 누출을 막을 수 있습니다.

마찬가지로, 폰트 팔레트 값은 참조한 문서에서만 사용할 수 있어야 합니다. 저자 정의 컬러 팔레트를 참조 문서 외에서 사용하면 한 페이지의 내용이 다른 페이지에 영향을 줄 수 있어 보안 누출이 되며, 공격자가 이를 공격 벡터로 쓸 수 있습니다.

15.6. 이 명세는 플랫폼의 어떤 정보(예: 설정 데이터)를 오리진에 노출합니까?

system-ui 키워드는 운영체제의 기본 시스템 UI 폰트를 지문 추출 메커니즘에 노출시킵니다.

15.7. 이 명세는 오리진이 사용자의 기기 센서에 접근할 수 있게 합니까?

아닙니다.

15.8. 이 명세는 오리진에 어떤 데이터를 노출합니까? 또한 동일/다른 맥락에서 다른 기능이 노출하는 데이터와 동일한 데이터도 문서화해주세요.

스타일시트를 통해 로드된 제3자 웹 폰트의 경우, 스타일시트 오리진이 Referer 헤더로 제3자에게 노출될 수 있습니다. 또한 unicode-range와 서로 다른 src url을 조합하면 제3자가 페이지에서 어떤 글자가 사용되는지 알 수 있어 CJK 등 글자 수가 많은 스크립트에서는 개인정보 위험이 됩니다.

HTML에서 미리 로드된 제3자 웹 폰트의 경우, 문서 오리진도 유사하게 노출될 수 있습니다.

15.9. 이 명세는 새로운 스크립트 실행/로드 메커니즘을 허용합니까?

아닙니다.

특히, SVG-in-OpenType 컬러 폰트의 경우, 글리프 정의에 사용된 SVG에 스크립트 요소가 있으면 실행되지 않아야 하며, 실제로 실행되지 않습니다.

15.10. 이 명세는 오리진이 다른 기기에 접근할 수 있게 합니까?

아닙니다.

15.11. 이 명세는 오리진이 사용자 에이전트의 네이티브 UI를 어느 정도 제어할 수 있게 합니까?

공격자가 운영체제를 판별해 해당 OS에 맞는 네이티브 스타일 폰트를 사용함으로써 네이티브 UI 기능을 위조(spoofing)할 위험이 있습니다.

15.12. 이 명세는 웹에 임시 식별자를 만들거나 노출합니까?

없습니다.

15.13. 이 명세는 1st-party와 3rd-party 맥락에서 어떻게 동작을 구분합니까?

폰트 로드의 경우, 사용자 에이전트는 [HTML] 명세에서 정의한 CORS를 지원하는 fetch 메서드를 사용해야 합니다. 폰트 페칭 시, 사용자 에이전트는 "익명(Anonymous)" 모드를 사용하고, referrer 소스를 스타일시트 URL로, 오리진을 문서 URL로 설정해야 합니다.

따라서, 저자가 교차 오리진 로드를 직접 허용하지 않으면 폰트는 일반적으로 교차 오리진으로 로드되지 않습니다.

15.14. 이 명세는 사용자 에이전트의 프라이빗 브라우징 또는 '시크릿' 모드에서 어떻게 동작합니까?

이 명세는 구분하지 않습니다.

일부 사용자 에이전트는 이들 모드에서 더 제한적인 설치된 폰트 집합을 노출할 수 있습니다.

15.15. 이 명세는 "보안 고려 사항"과 "개인정보 보호 고려 사항" 섹션을 포함합니까?

네.

15.16. 이 명세는 기본 보안 특성을 다운그레이드할 수 있게 합니까?

아닙니다.

15.17. 이 설문지는 무엇을 추가로 물었어야 하나요?

악의적인 페이로드가 애플리케이션을 크래시시키거나, 심지어 전체 운영체제 크래시, 원격 코드 실행도 야기할 수 있는지 물었어야 합니다.

실제로, 일부 플랫폼에서는 설치 및 렌더링된 폰트가 적절히 제작되면 이런 위험이 존재하며, 실전에서 악용된 사례도 있습니다.

실제 운용에서는, 해당 취약점이 있는 OS에서 실행되는 사용자 에이전트는 손상되거나 악의적으로 제작된 폰트를 감지해 사용하지 못하도록 폰트 소독(font sanitizer)을 사용합니다.

16. 접근성 고려 사항

텍스트의 시각적 렌더링을 위해 폰트를 사용하는 것은 일반적으로 접근성에 영향을 주지 않아야 합니다. 예를 들어, 텍스트를 음성으로 변환하는 스크린 리더를 사용하는 사람은 폰트를 다운로드하지 않으며, 폰트에 어떤 내용이 들어있든 상관없습니다.

다만, 폰트 글리프가 전달하는 의미와 문자가 전달하는 의미가 같다는 전제입니다.

역사적으로 항상 그런 것은 아니었습니다. 예를 들어 웹 초기에는 폰트(SYMBOL 등)를 사용해 라틴 문자를 그리스 글리프로 바꾸는 일이 흔했습니다. 이런 방식은 시각적으로는 동작했지만, 스크린 리더에는 동작하지 않았고 텍스트 검색이나 색인도 어려웠습니다. 왜냐하면 매핑이 폰트에 따라 다르기 때문입니다. 유니코드의 등장 이후에는 그리스 텍스트에 그리스 문자를 사용하고, 폰트의 그리스 글리프도 그리스 문자에 매핑하는 것이 표준 관행이 되었습니다.

불행하게도, 하지만 피할 수 있게, 이런 관행은 잘못 설계된 아이콘 폰트에서 계속되고 있습니다. 예를 들어, 라틴 문자 "P"에 프린터 아이콘을 배치하는 폰트가 있을 수 있습니다. 이런 방식은 텍스트에 의미 없는 문자를 흩뿌려 텍스트 검색/색인에 악영향을 주고, 아이콘 폰트가 로드되지 않으면 이해하기 어려운 렌더링이 나오며, 스크린 리더도 방해합니다. 잘 설계된 폰트는 이런 아이콘을 의미 있는 문자에 할당해야 합니다. 예를 들어, 프린터 아이콘을 "printer" 문자열이나 유니코드 🖨 U+1F5A8 (PRINTER)에 할당해야 합니다.

17. 감사의 글

CSS 워킹 그룹은 다음 분들께 감사드립니다:

Peter Constable - 다양한 언어 오류 수정.

Nick Sherman - 광학 크기 이미지 준비.

Richard Ishida - 우르두 샘플 준비.

Munira Tursunova와 Dominik Röttsches - font-palette 애니메이션 기능 개발.

John Hudson - OpenType 언어 태그의 미묘함을 설명해 주셨고, 비잔틴 인장에 텍스트를 표시할 때 문자 변형 예시를 제공해 주셨습니다.

Elika Etemad - '@font-feature-values' 규칙의 초기 디자인 아이디어 제공.

Tab Atkins Jr. 특별 감사 - 폰트 렌더링 제어 섹션과 font-display 디스크립터 섹션의 텍스트 제공. Ilya Grigorik, David Kuettel에게도 이 섹션 개발 지원에 특별 감사.

18. 변경 사항

18.1. 2021년 12월 21일 작업 초안에서 변경된 사항 21 December 2021 Working Draft

18.2. 2021년 7월 29일 작업 초안에서 변경된 사항 29 July 2021 Working Draft

18.3. 2020년 11월 17일 작업 초안에서 변경된 사항 17 November 2020 Working Draft

18.4. 2019년 11월 13일 작업 초안에서 변경된 사항 13 November 2019 Working Draft

18.5. 2018년 9월 20일 작업 초안에서 변경된 사항 20 September 2018 Working Draft

18.6. 2018년 4월 10일 작업 초안에서 변경된 사항 10 April 2018 Working Draft

18.7. 2018년 9월 20일 CSS Fonts 3 권고안에서 변경된 사항

이 부분은 CSS Fonts 4가 CSS Fonts 3과 비교해 변경된 내용을 요약합니다.

적합성(Conformance)

문서 규약(Document conventions)

적합성 요구사항은 설명적 주장과 RFC 2119 용어의 조합으로 표현됩니다. "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL"과 같은 핵심 용어는 규범적인 부분에서 RFC 2119에 따라 해석되어야 합니다. 단, 가독성을 위해 이 명세에서는 모든 단어를 대문자로 표기하지 않습니다.

이 명세의 모든 텍스트는 명시적으로 비규범(non-normative)으로 표시된 섹션, 예제, 노트를 제외하면 모두 규범적입니다. [RFC2119]

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

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

정보성 노트는 “Note”로 시작하며 class="note"로 규범 텍스트와 구분되어 표시됩니다. 예시:

Note, 이것은 정보성 노트입니다.

권고(advisement)는 특별한 주의를 유도하기 위해 스타일링된 규범 섹션이며, <strong class="advisement">로 구분됩니다. 예시: UA는 반드시 접근 가능한 대안을 제공해야 합니다.

테스트

이 명세의 내용과 관련된 테스트는 “Tests” 블록에 이와 같이 기록될 수 있습니다. 이런 블록은 모두 비규범적입니다.


적합성 클래스(Conformance classes)

이 명세에 대한 적합성은 세 가지 적합성 클래스로 정의됩니다:

스타일 시트(style sheet)
CSS 스타일 시트.
렌더러(renderer)
스타일 시트의 의미를 해석하고 해당 스타일 시트를 사용하는 문서를 렌더링하는 UA.
저작 도구(authoring tool)
스타일 시트를 작성하는 UA.

스타일 시트가 이 명세에 대해 적합성을 갖기 위해서는 이 모듈에서 정의된 문법을 사용하는 모든 선언문이, CSS 일반 문법과 이 모듈에서 정의된 각 기능의 개별 문법에 따라 유효해야 합니다.

렌더러가 이 명세에 대해 적합성을 갖기 위해서는 스타일 시트를 적합한 명세대로 해석할 뿐 아니라, 이 명세에서 정의된 모든 기능을 올바르게 파싱하고 문서를 그에 따라 렌더링해야 합니다. 단, UA가 장치의 한계로 인해 문서를 올바르게 렌더링하지 못하는 경우(예: 단색 모니터에서 색상 렌더링 불가), UA가 비적합하다고 할 수 없습니다.

저작 도구가 이 명세에 대해 적합성을 갖기 위해서는 스타일 시트를 CSS 일반 문법 및 이 모듈의 각 기능별 문법에 따라 문법적으로 올바르게 작성하고, 이 모듈에서 설명한 스타일 시트의 모든 다른 적합성 요구사항도 충족해야 합니다.

부분 구현(Partial implementations)

저자가 호환성 있는 파싱 규칙을 활용하여 폴백 값을 지정할 수 있도록, CSS 렌더러는 반드시 지원하지 않는 모든 at-rule, 속성, 속성값, 키워드, 기타 구문 구조를 무효로 처리(그리고 적절히 무시)해야 합니다. 특히, 사용자 에이전트는 선택적으로 지원하지 않는 구성 값만 무시하고 지원하는 값만 인정해서는 안 됩니다. 하나의 다중 값 속성 선언에서 어떤 값이라도 무효(즉, 지원하지 않는 값)로 간주되면, CSS는 전체 선언을 무시하도록 요구합니다.

불안정 및 독점 기능의 구현(Implementations of Unstable and Proprietary Features)

향후 안정적인 CSS 기능과 충돌을 피하기 위해, CSSWG는 최선의 구현 방법을 따라 불안정한 기능독점 확장을 구현할 것을 권장합니다.

실험적이 아닌 구현(Non-experimental implementations)

명세가 Candidate Recommendation 단계에 도달하면, 실험적이 아닌 구현이 가능해지며, 구현자는 명세에 따라 올바르게 구현된 CR 수준의 기능을 접두어 없이 공개해야 합니다.

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

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

색인

이 명세서에서 정의한 용어

참조로 정의된 용어

참고문헌

규범적 참고문헌

[AAT-FEATURES]
Apple Advanced Typography Font Feature Registry. URL: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html
[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-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS Color Module Level 4. 2022년 11월 1일. CR. URL: https://www.w3.org/TR/css-color-4/
[CSS-COLOR-5]
Chris Lilley; et al. CSS Color Module Level 5. 2022년 6월 28일. WD. URL: https://www.w3.org/TR/css-color-5/
[CSS-COLOR-ADJUST-1]
Elika Etemad; et al. CSS Color Adjustment Module Level 1. 2022년 6월 14일. CR. URL: https://www.w3.org/TR/css-color-adjust-1/
[CSS-ENV-1]
CSS Environment Variables Module Level 1. 편집자 초안. URL: https://drafts.csswg.org/css-env-1/
[CSS-FONTS-4]
John Daggett; Myles Maxfield; Chris Lilley. CSS Fonts Module Level 4. 2021년 12월 21일. WD. URL: https://www.w3.org/TR/css-fonts-4/
[CSS-INLINE-3]
Dave Cramer; Elika Etemad. CSS Inline Layout Module Level 3. 2023년 4월 1일. WD. URL: https://www.w3.org/TR/css-inline-3/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS Syntax Module Level 3. 2021년 12월 24일. CR. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-TEXT-4]
Elika Etemad; et al. CSS Text Module Level 4. 2023년 10월 20일. WD. URL: https://www.w3.org/TR/css-text-4/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 2022년 12월 1일. CR. URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2023년 12월 18일. 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/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019년 7월 30일. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS21/
[CSS22]
Bert Bos. Cascading Style Sheets Level 2 Revision 2 (CSS 2.2) Specification. 2016년 4월 12일. WD. URL: https://www.w3.org/TR/CSS22/
[CSS3TEXT]
Elika Etemad; Koji Ishii; Florian Rivoal. CSS Text Module Level 3. 2023년 9월 3일. CR. URL: https://www.w3.org/TR/css-text-3/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021년 8월 26일. WD. URL: https://www.w3.org/TR/cssom-1/
[FETCH]
Anne van Kesteren. Fetch Standard. 현행 표준. URL: https://fetch.spec.whatwg.org/
[GRAPHITE]
Graphite technical overview. 2012년. URL: https://scripts.sil.org/cms/scripts/page.php?site_id=projects&item_id=graphite_techAbout
[HTML]
Anne van Kesteren; et al. HTML 표준. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[I18N-GLOSSARY]
Richard Ishida; Addison Phillips. Internationalization Glossary. 2024년 1월 23일. NOTE. URL: https://www.w3.org/TR/i18n-glossary/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 현행 표준. URL: https://infra.spec.whatwg.org/
[OPENTYPE]
OpenType 명세(OpenType specification). URL: http://www.microsoft.com/typography/otspec/default.htm
[OPENTYPE-FEATURES]
OpenType 기능 레지스트리(OpenType feature registry). URL: http://www.microsoft.com/typography/otspec/featurelist.htm
[RFC2119]
S. Bradner. RFC에서 요구 수준을 표시하는 데 사용하는 키워드(Key words for use in RFCs to Indicate Requirement Levels). 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC8081]
C. Lilley. "font" 최상위 미디어 타입(The "font" Top-Level Media Type). 2017년 2월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc8081
[UNICODE]
유니코드 표준(The Unicode Standard). URL: https://www.unicode.org/versions/latest/
[UTS51]
Mark Davis; Ned Holbrook. Unicode Emoji. 2023년 9월 5일. Unicode Technical Standard #51. URL: https://www.unicode.org/reports/tr51/tr51-25.html
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 현행 표준. URL: https://webidl.spec.whatwg.org/

정보성 참고문헌

[CHARMOD-NORM]
Addison Phillips; et al. 월드 와이드 웹의 문자 모델: 문자열 매칭(Character Model for the World Wide Web: String Matching). 2021년 8월 11일. NOTE. URL: https://www.w3.org/TR/charmod-norm/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 3. 2023년 3월 30일. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-FONT-LOADING-3]
Tab Atkins Jr.. CSS Font Loading Module Level 3. 2023년 4월 6일. WD. URL: https://www.w3.org/TR/css-font-loading-3/
[CSS-FONTS-3]
John Daggett; Myles Maxfield; Chris Lilley. CSS Fonts Module Level 3. 2018년 9월 20일. REC. URL: https://www.w3.org/TR/css-fonts-3/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2023년 3월 29일. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-TRANSFORMS-1]
Simon Fraser; et al. CSS Transforms Module Level 1. 2019년 2월 14일. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS3-CONDITIONAL]
David Baron; Elika Etemad; Chris Lilley. CSS Conditional Rules Module Level 3. 2022년 1월 13일. CR. URL: https://www.w3.org/TR/css-conditional-3/
[IFT]
Chris Lilley; Garret Rieger; Myles Maxfield. 증분 폰트 전송(Incremental Font Transfer). 2023년 5월 30일. WD. URL: https://www.w3.org/TR/IFT/
[OPEN-FONT-FORMAT]
정보 기술 — 시청각 객체의 코딩 — Part 22: 오픈 폰트 포맷(Information technology — Coding of audio-visual objects — Part 22: Open Font Format). URL: http://standards.iso.org/ittf/PubliclyAvailableStandards/c052136_ISO_IEC_14496-22_2009%28E%29.zip
[PFE-report]
Chris Lilley. 점진적 폰트 강화: 평가 보고서(Progressive Font Enrichment: Evaluation Report). 2020년 10월 15일. Note. URL: https://www.w3.org/TR/PFE-evaluation/
[TRUETYPE]
TrueType™ 참조 매뉴얼(TrueType™ Reference Manual). URL: https://developer.apple.com/fonts/TrueType-Reference-Manual/
[UAX29]
Josh Hadley. 유니코드 텍스트 분할(Unicode Text Segmentation). 2023년 8월 16일. Unicode Standard Annex #29. URL: https://www.unicode.org/reports/tr29/tr29-43.html
[WINDOWS-GLYPH-PROC]
John Hudson. Windows 글리프 처리(Windows Glyph Processing). URL: http://www.microsoft.com/typography/developers/opentype/default.htm

속성 색인

이름 초기값 적용 대상 상속됨 % 비율 애니메이션 타입 정규 순서 계산값 미디어
font [ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-width-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | <system-family-name> 개별 속성 참조 모든 요소 및 텍스트 개별 속성 참조 개별 속성 참조 문법별 개별 속성 참조
font-family [ <family-name> | <generic-family> ]# 사용자 에이전트에 따라 다름 모든 요소 및 텍스트 해당 없음 불연속 문법별 리스트, 각 항목은 문자열 또는 <generic-family> 키워드
font-feature-settings normal | <feature-tag-value># normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-kerning auto | normal | none auto 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-language-override normal | <string> normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 문자열 또는 키워드 none
font-optical-sizing auto | none auto 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 키워드
font-palette normal | light | dark | <palette-identifier> | <palette-mix()> normal 모든 요소 및 텍스트 해당 없음 계산값 기준 문법별 지정된 키워드, 식별자 또는 <palette-mix()> 함수. <palette-mix()>가 결과적으로 동일한 팔레트라면 하나의 키워드 또는 식별자로 단순화되어야 함.
font-size <absolute-size> | <relative-size> | <length-percentage [0,∞]> | math medium 모든 요소 및 텍스트 상위 요소의 font-size 참조 계산값 타입 기준 문법별 절대 길이 값
font-size-adjust none | <number [0,∞]> none 모든 요소 및 텍스트 해당 없음 계산값 타입 기준 문법별 숫자 또는 키워드 none
font-style normal | italic | oblique <angle [-90deg,90deg]>? normal 모든 요소 및 텍스트 해당 없음 계산값 타입 기준; normal은 oblique 0deg로 애니메이션됨 문법별 지정된 키워드, 각도(지정 시)
font-synthesis none | [ weight || style || small-caps || position] weight style small-caps position 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 키워드(들)
font-synthesis-position auto | none auto 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 키워드
font-synthesis-small-caps auto | none auto 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 키워드
font-synthesis-style auto | none auto 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 키워드 시각적
font-synthesis-weight auto | none auto 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 키워드 시각적
font-variant normal | none | [ [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ] || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] || [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ] || [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ] || [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] || [ sub | super ] || [ text | emoji | unicode ] ] normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-variant-alternates normal | [ stylistic(<feature-value-name>) || historical-forms || styleset(<feature-value-name>#) || character-variant(<feature-value-name>#) || swash(<feature-value-name>) || ornaments(<feature-value-name>) || annotation(<feature-value-name>) ] normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-variant-caps normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-variant-east-asian normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-variant-emoji normal | text | emoji | unicode normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 키워드
font-variant-ligatures normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ] normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-variant-numeric normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero ] normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-variant-position normal | sub | super normal 모든 요소 및 텍스트 해당 없음 불연속 문법별 지정된 값
font-variation-settings normal | [ <opentype-tag> <number>]# normal 모든 요소 및 텍스트 해당 없음 (본문 참고) 문법별 키워드 normal 또는 리스트, 각 항목은 문자열과 숫자 쌍
font-weight <font-weight-absolute> | bolder | lighter normal 모든 요소 및 텍스트 해당 없음 계산값 타입 기준 문법별 숫자, 아래 참조
font-width normal | <percentage [0,∞]> | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded normal 모든 요소 및 텍스트 해결 안됨 계산값 타입 기준 문법별 백분율, 아래 참조

@font-face 디스크립터

이름 초기값
ascent-override normal | <percentage [0,∞]> normal
descent-override normal | <percentage [0,∞]> normal
font-display auto | block | swap | fallback | optional auto
font-family <family-name> 해당 없음
font-feature-settings normal | <feature-tag-value># normal
font-language-override normal | <string> normal
font-named-instance auto | <string> auto
font-style auto | normal | italic | oblique [ <angle [-90deg,90deg]>{1,2} ]? auto
font-variation-settings normal | [ <string> <number>]# normal
font-weight auto | <font-weight-absolute>{1,2} auto
font-width auto | <'font-width'>{1,2} auto
line-gap-override normal | <percentage [0,∞]> normal
src <font-src-list> 해당 없음
unicode-range <urange># U+0-10FFFF

@font-feature-values 디스크립터

이름 초기값
font-display auto | block | swap | fallback | optional auto

@font-palette-values 디스크립터

이름 초기값
base-palette light | dark | <integer [0,∞]> 해당 없음
font-family <family-name># 해당 없음
override-colors [ <integer [0,∞]> <color> ]# 해당 없음

IDL 색인

[Exposed=Window]
interface CSSFontFaceRule : CSSRule {
  readonly attribute CSSStyleDeclaration style;
};

partial interface CSSRule {  const unsigned short FONT_FEATURE_VALUES_RULE = 14;
};
[Exposed=Window]
interface CSSFontFeatureValuesRule : CSSRule {
  attribute CSSOMString fontFamily;
  readonly attribute CSSFontFeatureValuesMap annotation;
  readonly attribute CSSFontFeatureValuesMap ornaments;
  readonly attribute CSSFontFeatureValuesMap stylistic;
  readonly attribute CSSFontFeatureValuesMap swash;
  readonly attribute CSSFontFeatureValuesMap characterVariant;
  readonly attribute CSSFontFeatureValuesMap styleset;
};

[Exposed=Window]
interface CSSFontFeatureValuesMap {
  maplike<CSSOMString, sequence<unsigned long>>;
  undefined set(CSSOMString featureValueName,
         (unsigned long or sequence<unsigned long>) values);
};

[Exposed=Window]interface CSSFontPaletteValuesRule : CSSRule {
  readonly attribute CSSOMString name;
  readonly attribute CSSOMString fontFamily;
  readonly attribute CSSOMString basePalette;
  readonly attribute CSSOMString overrideColors;
};

이슈 색인

수직 쓰기 모드에서 양수와 음수 오블리크는 어떤 방향으로 기울어져야 하나요? 어떻게 반대 방향으로 기울기를 구현할 수 있을까요 (수직 쓰기에서 필요)?
fallbackoptional은 한 패밀리 내 일부 페이스만 사용되고 나머지는 폴백되어 "랜섬 노트"처럼 보이게 됩니다. 아마도 한 폰트 패밀리의 모든 폰트가 동일한 동작(모두 swap 또는 모두 fallback)을 하도록 요구해야 할까요? 폰트 패밀리 단위로 동작을 제어하기 위한 @font-feature-values도 참고하세요.
stream의 타입에 따라 폰트를 로드합니다.
오블리크를 일반(normal)보다 우선 적용하는 임계값은 평균 각도보다 더 낮아야 합니다.
더 많은 예시와 그림을 추가하세요.