Technology

유니코드 범위 (unicode-range)

@font-face의 CSS 디스크립터로, 폰트 파일에서 다운로드할 유니코드 문자 범위를 지정하여 브라우저가 자동으로 서브셋을 적용할 수 있게 한다.

The unicode-range descriptor in @font-face tells browsers which Unicode characters a font file contains, enabling conditional loading: the font file is only downloaded if the page contains at least one character from the specified range. This is a powerful performance tool that makes it practical to declare many font files without paying the download cost for each.

/* Latin Extended subset */
@font-face {
  font-family: 'Source Serif';
  src: url('/fonts/source-serif-latin-ext.woff2') format('woff2');
  font-weight: 400;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020,
                 U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F,
                 U+A720-A7FF;
}

/* Basic Latin — always loads if Latin text is present */
@font-face {
  font-family: 'Source Serif';
  src: url('/fonts/source-serif-latin.woff2') format('woff2');
  font-weight: 400;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
                 U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074,
                 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
                 U+FEFF, U+FFFD;
}

Syntax for unicode-range values:

  • Single codepoint: U+26 (the ampersand &)
  • Codepoint range: U+0025-00FF
  • Wildcard range: U+00?? (equivalent to U+0000-00FF)

How browsers use it:

Before downloading any font file in a font stack, the browser scans the text content of the page and checks which unicode-range declarations include characters that are actually present. Files whose ranges have no matching characters are never requested. This happens before rendering, so it doesn't cause layout shifts — the browser just skips the fetch entirely.

This is exactly how Google Fonts serves multilingual font families. Noto Sans has separate @font-face declarations for Latin, Greek, Cyrillic, Devanagari, Japanese, Chinese, and dozens of other scripts — but a page with only Latin content downloads only the Latin subset file.

Practical use cases:

/* Only load currency symbols font if page has non-Latin currencies */
@font-face {
  font-family: 'CurrencySymbols';
  src: url('/fonts/currencies.woff2') format('woff2');
  unicode-range: U+20A0-20CF; /* Currency Symbols block */
}

/* Load math symbols only when needed */
@font-face {
  font-family: 'MathFont';
  src: url('/fonts/math.woff2') format('woff2');
  unicode-range: U+2200-22FF; /* Mathematical Operators */
}

One important nuance: unicode-range checks characters in the DOM, not what's actually visible. Content in display: none elements still triggers downloads if those elements contain characters in the range. This rarely causes practical issues but is worth knowing when debugging unexpected font requests.

Related Terms

Fonts That Illustrate This Concept

Learn More