CSS 타이포그래피

Google Fonts: 개발자를 위한 완전 가이드

업데이트됨 8월 20, 2026
개발자가 Google Fonts에 대해 알아야 할 모든 것 — API, CSS 통합, 셀프 호스팅, 성능 최적화, v2 API 변경 사항까지 다룹니다.

Google Fonts: The Developer's Complete Guide

Google Fonts is the most widely used font delivery service on the web, serving billions of font file requests per day. For developers, it offers an extraordinary catalog of high-quality typefaces — including many variable fonts — available with a single line of HTML. But using it well requires understanding the API, the performance trade-offs, and when to move beyond the CDN to self-hosting.

This guide covers everything a developer needs to know: the CSS API v2 syntax, controlling weights and styles, the display parameter, self-hosting for speed and privacy, subset loading for internationalization, and performance best practices.


Google Fonts CSS API v2

The Google Fonts CSS API v2 (launched in 2019) is a significant upgrade over the original API. It uses a cleaner URL structure, supports variable fonts, enables multiple styles in a single request, and provides finer control over weight ranges.

The API endpoint is https://fonts.googleapis.com/css2.

Basic Usage

<!-- Preconnect for performance (always include these) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- Load Inter Regular (400) -->
<link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet">
/* Apply in your CSS */
body {
  font-family: 'Inter', sans-serif;
}

API URL Structure

The URL structure for the v2 API:

https://fonts.googleapis.com/css2
  ?family=FontName:axis@value
  &family=AnotherFont:axis@value
  &display=swap

Fonts are specified as family parameters. Each can include an axis specification and requested values after @.


Loading Specific Weights and Styles

Static Fonts

For non-variable fonts, you specify weights using wght@:

<!-- Single weight -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400&display=swap" rel="stylesheet">

<!-- Multiple weights -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">

<!-- Multiple weights, sorted (Google requires sorted order) -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">

Italic Styles

Italic styles use the ital axis. Values are 0 (normal) or 1 (italic). When requesting both normal and italic, separate them with a comma inside the weight specification:

<!-- Normal + Italic, one weight each -->
<link href="https://fonts.googleapis.com/css2?family=Lora:ital@0;1&display=swap" rel="stylesheet">

<!-- Multiple weights + italic combinations -->
<!-- Format: ital,wght@0,400;0,700;1,400;1,700 -->
<link href="https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">

Important: when requesting both italic and non-italic, the axis order must be alphabetical. So ital,wght — not wght,ital. The values after @ must be sorted tuples (by the first value, then the second).

Multiple Fonts in One Request

Combine multiple fonts in a single request using multiple family parameters. This is more efficient than multiple <link> tags:

<!-- Multiple fonts in one request -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Lora:ital,wght@0,400;1,400&display=swap" rel="stylesheet">
body {
  font-family: 'Inter', sans-serif;
}

blockquote {
  font-family: 'Lora', Georgia, serif;
}

Variable Fonts

Variable fonts use a range syntax with two dots:

<!-- Inter variable: full weight range -->
<link href="https://fonts.googleapis.com/css2?family=Inter:[email protected]&display=swap" rel="stylesheet">

<!-- Roboto Flex variable: weight + optical size range -->
<link href="https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,[email protected],100..900&display=swap" rel="stylesheet">

<!-- Source Serif 4: italic + weight + optical size -->
<link href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&display=swap" rel="stylesheet">
/* With variable font — any weight in range is valid */
body {
  font-family: 'Inter', sans-serif;
  font-weight: 400;
}

.ui-medium {
  font-weight: 550; /* Not a standard value — works with variable font */
}

h1 {
  font-weight: 750;
}

Display Parameter and Font Loading

The display parameter maps directly to the font-display CSS descriptor. It controls the browser's behavior while the font is downloading.

<!-- swap: Show fallback immediately, swap when loaded (recommended) -->
<link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet">

<!-- block: Hide text briefly while font loads (FOIT) -->
<link href="https://fonts.googleapis.com/css2?family=Inter&display=block" rel="stylesheet">

<!-- fallback: Very brief FOIT, then fallback. Swap within 3s only -->
<link href="https://fonts.googleapis.com/css2?family=Inter&display=fallback" rel="stylesheet">

<!-- optional: Brief FOIT, then use fallback permanently if not cached -->
<link href="https://fonts.googleapis.com/css2?family=Inter&display=optional" rel="stylesheet">

<!-- auto: Browser decides (not recommended) -->
<link href="https://fonts.googleapis.com/css2?family=Inter&display=auto" rel="stylesheet">

Recommendation for most projects: display=swap. Users always see text (just briefly in the fallback font), and content is never invisible.

Exception: If you have well-matched fallback fonts and most users are repeat visitors (fonts cached), display=optional produces zero layout shift — the font either loads instantly from cache or falls back permanently. An increasingly good choice for performance-critical sites.

How Google Fonts Serves font-display

The CSS returned by the Google Fonts API injects the font-display value into each @font-face block it serves:

/* What Google Fonts returns for display=swap */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/inter/v19/...-subset.woff2) format('woff2');
  unicode-range: U+0000-00FF, ...;
}
/* ... more @font-face blocks for other subsets */

Self-Hosting Google Fonts (Privacy and Speed)

Self-hosting means downloading Google Fonts files and serving them from your own server or CDN.

Why Self-Host?

Privacy / GDPR compliance. When a user loads a page that requests Google Fonts, their IP address is sent to Google's servers. For EU users and GDPR compliance, this is a potential legal concern. Self-hosting eliminates the third-party request entirely.

Performance. Self-hosted fonts benefit from: - Fewer DNS lookups (no fonts.googleapis.com or fonts.gstatic.com) - Same-origin requests (no CORS pre-flight) - Your CDN's edge caching behavior, which you control - rel="preload" in the same document, pointing to files on your domain

Stability. No dependency on Google's CDN availability.

How to Self-Host Google Fonts

The easiest path is the google-webfonts-helper tool, which lets you select fonts, customize subsets, and download ready-to-use WOFF2 files with auto-generated CSS.

  1. Visit the tool and search for your font (e.g., Inter)
  2. Select the weights and styles you need
  3. Choose "modern browsers" to get WOFF2-only files
  4. Download the zip and place fonts in /public/fonts/
  5. Copy the generated CSS into your stylesheet

The generated CSS looks like:

/* self-hosted Inter — generated by google-webfonts-helper */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-v19-latin-regular.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/inter-v19-latin-700.woff2') format('woff2');
}

Downloading the Variable Font

For variable fonts, download from the Google Fonts page directly: 1. Search for the font on fonts.google.com 2. Select "Download family" → download the TTF/OTF 3. Convert to WOFF2 using woff2_compress (Google's tool) or Transfonter

# Install woff2 tools (macOS)
brew install woff2

# Convert to WOFF2
woff2_compress Inter-VariableFont_wght.ttf
# → Produces Inter-VariableFont_wght.woff2
/* Self-hosted variable font */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-VariableFont_wght.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

Preload Self-Hosted Fonts

One major advantage of self-hosting: you can preload the critical font file in the <head>:

<head>
  <!-- Preload the most critical font file -->
  <link
    rel="preload"
    href="/fonts/inter-regular.woff2"
    as="font"
    type="font/woff2"
    crossorigin
  >
  <link rel="stylesheet" href="/css/styles.css">
</head>

crossorigin is required even for same-origin font requests when using rel="preload" — this is because fonts are always fetched with CORS mode enabled.


Subset Loading for International Characters

Google Fonts automatically serves subset files based on the unicode-range descriptor and the actual characters present on the page. Each @font-face block in the returned CSS covers a specific character range.

For most projects, you can rely on this subsetting automatically. But for projects targeting specific international audiences, understanding how to optimize matters.

How Google's Automatic Subsetting Works

When the browser encounters a @font-face with unicode-range, it only downloads that file if the page contains characters in that range. For a Latin-only English page loading Roboto, only the Latin subset file downloads, not the Cyrillic or Greek subsets.

<!-- Google handles subsetting automatically for Latin + extended -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">

The API returns CSS with multiple @font-face blocks: - Latin (basic) - Latin Extended (Polish, Turkish, Vietnamese, etc.) - Cyrillic - Cyrillic Extended - Greek - Greek Extended - Vietnamese (sometimes a separate subset)

Requesting Specific Subsets (Legacy v1 API)

The v1 API had an explicit &subset= parameter. In v2, subsetting is automatic — the browser handles it through unicode-range matching. You do not need to specify subsets in v2.

For CJK Languages

For Chinese, Japanese, and Korean fonts, standard subsetting is insufficient. These character sets contain thousands of glyphs, making full font files enormous (500KB+).

Google Fonts serves these through "text" subsetting — a different approach where you specify exactly which characters you need:

<!-- Text-based subsetting: only download glyphs for these characters -->
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&text=サイトタイトル&display=swap" rel="stylesheet">

This is impractical for dynamic content. For CJK content-heavy sites, consider: - Chinese fonts: Source Han Sans, Noto Sans SC/TC, ZCOOL fonts - Japanese: Noto Sans JP, M PLUS fonts - Korean: Noto Sans KR, Nanum fonts

And use Google Fonts' font-display settings combined with generous fallbacks:

/* Japanese with system fallback */
body {
  font-family: 'Noto Sans JP', 'Hiragino Kaku Gothic ProN',
               'Hiragino Sans', Meiryo, sans-serif;
}

Performance Best Practices

1. Preconnect to Google Fonts Domains

<!-- Critical: add before your Google Fonts link tag -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

The crossorigin attribute on the second preconnect is essential — font files are always fetched with CORS, so the browser needs a CORS-enabled connection to fonts.gstatic.com.

2. Load Only What You Need

Every additional weight and style is another file download. Be deliberate:

<!-- Load only what your design uses -->

<!-- Bad: loading all weights -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">

<!-- Good: load only what the design actually uses -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">

<!-- Best: use the variable font for flexibility -->
<link href="https://fonts.googleapis.com/css2?family=Inter:[email protected]&display=swap" rel="stylesheet">

3. Use display=swap

Always include &display=swap to prevent invisible text. Never omit this parameter.

4. Combine Multiple Fonts into One Request

<!-- Avoid: two separate requests -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Lora:ital@0;1&display=swap" rel="stylesheet">

<!-- Better: one combined request -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&family=Lora:ital@0;1&display=swap" rel="stylesheet">

5. Use the @import Approach Sparingly

Importing Google Fonts in CSS is less efficient than the HTML <link> approach:

/* Avoid in production — adds latency before fonts start loading */
@import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');

The <link> approach allows the browser to discover and fetch the CSS API response while parsing the <head>, which is earlier in the document lifecycle.

6. Use resource hints wisely

<head>
  <!-- Step 1: Preconnect to Google APIs -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

  <!-- Step 2: Request the font CSS -->
  <link href="https://fonts.googleapis.com/css2?family=Inter:[email protected]&display=swap" rel="stylesheet">

  <!-- Optional: dns-prefetch as fallback for browsers not supporting preconnect -->
  <link rel="dns-prefetch" href="https://fonts.googleapis.com">
  <link rel="dns-prefetch" href="https://fonts.gstatic.com">
</head>

7. Consider Self-Hosting for Critical Fonts

For the primary body font that renders above-the-fold content, self-hosting with rel="preload" is the most performant approach. Combine with Google Fonts CDN for secondary fonts:

<head>
  <!-- Self-host + preload the critical body font -->
  <link rel="preload" href="/fonts/inter-regular.woff2" as="font" type="font/woff2" crossorigin>

  <!-- Use Google Fonts CDN for the display/heading font -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700&display=optional" rel="stylesheet">
</head>

The heading font uses display=optional because: (a) headings are less content-critical, (b) the font caches on first visit and loads instantly on subsequent ones, (c) Georgia is an excellent fallback for Playfair Display.

A Complete, Optimized Setup

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Preconnect for Google Fonts CDN -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

  <!-- Load Inter (variable, primary) + Lora (secondary) -->
  <link
    href="https://fonts.googleapis.com/css2?family=Inter:[email protected]&family=Lora:ital,wght@0,400;0,700;1,400&display=swap"
    rel="stylesheet"
  >

  <link rel="stylesheet" href="/css/styles.css">
</head>
/* styles.css */
body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  font-weight: 400;
  line-height: 1.6;
}

h1, h2, h3 {
  font-family: 'Lora', Georgia, serif;
  font-weight: 700;
  line-height: 1.2;
}

This setup loads two high-quality Google Fonts in a single optimized request, uses variable font capabilities for Inter, and provides sensible system fallbacks for both.

타이포그래피 용어

도구 사용해 보기

언급된 폰트

Roboto Sans Serif #1

Christian Robertson이 Google의 Material Design 생태계를 위해 디자인한 이 네오그로테스크 산세리프는 웹과 Android에서 가장 널리 사용되는 서체입니다. 이중적 성격의 디자인은 기계적 정밀함과 자연스러운 읽기 리듬 사이에서 균형을 이루어 UI 레이블과 긴 본문 텍스트 모두에 잘 어울립니다. 가변 폰트는 너비와 웨이트 축을 지원하며 키릴, 그리스, 확장 라틴 문자도 함께 지원합니다.

The quick brown fox jumps over the lazy dog
Open Sans Sans Serif #2

Steve Matteson이 만든 이 휴머니스트 산세리프는 수직적인 응력과 열린 조리개로 다양한 화면 크기와 해상도에서의 가독성을 우선시합니다. 역대 가장 많이 배포된 웹 폰트 중 하나로, 본문 텍스트와 이메일 템플릿, 웹 애플리케이션에 잘 어울리는 중립적이고 전문적인 톤을 지니고 있습니다. 가변 너비와 웨이트 축, 히브리어와 그리스어 문자 지원 덕분에 다재다능한 다국어 작업용 폰트입니다.

The quick brown fox jumps over the lazy dog
Inter Sans Serif #4

Rasmus Andersson은 컴퓨터 화면을 위해 특별히 이 네오그로테스크를 여러 해에 걸쳐 다듬었으며, 디지털 디스플레이의 작은 크기에서도 높은 가독성을 확보하기 위해 자간과 x-height, 획 대비를 최적화했습니다. 광학 크기 축(opsz)은 캡션과 헤드라인에 맞춰 디자인을 자동으로 조정하며, 웨이트 축은 얇은 것부터 가장 굵은 것까지 전체 범위를 아우릅니다. 전 세계 대시보드, 문서 사이트, 개발자 도구에서 사실상의 표준 선택지가 되었습니다.

The quick brown fox jumps over the lazy dog
Montserrat Sans Serif #5

부에노스아이레스 몬세라트 지역의 기하학적 표지판과 상점 전면에서 영감을 받아, Julieta Ulanovsky는 20세기 초 도시 레터링의 정신을 담아내기 위해 이 서체를 만들었습니다. 깔끔한 원형 형태와 강한 기하학적 비례는 헤드라인, 브랜딩, 랜딩 페이지에 이상적인 단호한 존재감을 부여합니다. 가변 웨이트 축은 넓은 범위를 아우르며, 키릴 문자와 베트남어 문자도 포함됩니다.

The quick brown fox jumps over the lazy dog

관련 글