Подключение шрифтов

Кастомные шрифты подключаются через @font-face, CDN-сервисы (Google Fonts), или как локальные файлы. Правильное подключение критически важно для производительности — шрифты часто составляют самую тяжёлую часть загрузки страницы.

Зачем нужно

Системные шрифты ограничены и отличаются на разных ОС. Подключение кастомных шрифтов позволяет использовать любой дизайнерский шрифт на любом устройстве, сохраняя единый визуальный стиль бренда.

Где используется

  • Корпоративные сайты с фирменными шрифтами
  • Дизайн-системы
  • Типографические проекты
  • Любой современный веб-сайт

Предпосылки


@font-face — базовое подключение

@font-face {
  font-family: "Inter";
  src: url("fonts/Inter-Regular.woff2") format("woff2"),
       url("fonts/Inter-Regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("fonts/Inter-Bold.woff2") format("woff2"),
       url("fonts/Inter-Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Использование */
body {
  font-family: "Inter", sans-serif;
}
h1 {
  font-weight: 700; /* Подгрузится Inter-Bold */
}

Свойства @font-face

Свойство Описание
font-family Имя шрифта (произвольное)
src Источники файлов (через запятую — fallback)
font-weight Какой вес описывает это начертание
font-style normal, italic, oblique
font-display Стратегия загрузки
font-stretch Ширина символов
unicode-range Диапазон символов (для subset)

Форматы шрифтов

Формат Расширение Поддержка Использовать?
WOFF2 .woff2 97%+ Да (основной)
WOFF .woff 99%+ Как fallback
TTF/OTF .ttf / .otf 99%+ Только если нет WOFF2
EOT .eot IE only Нет (устарел)
SVG .svg Устарел Нет

В 2026 году достаточно WOFF2. Можно добавить WOFF как fallback для очень старых браузеров.

/* Минимальный современный вариант */
@font-face {
  font-family: "MyFont";
  src: url("myfont.woff2") format("woff2");
  font-display: swap;
}

Google Fonts

<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=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">

Способ 2: через @import в CSS

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

body {
  font-family: "Inter", sans-serif;
}

<link> быстрее @import@import блокирует парсинг CSS и загружает последовательно.

Выбор весов и стилей

/* Один вес */
family=Inter:wght@400

/* Несколько весов */
family=Inter:wght@400;700

/* Диапазон (variable font) */
family=Inter:wght@100..900

/* Курсив */
family=Inter:ital,wght@0,400;0,700;1,400;1,700

/* Несколько шрифтов */
family=Inter:wght@400;700&family=Fira+Code:wght@400;700

Локальные шрифты

Можно указать, что если шрифт уже установлен на устройстве — не загружать:

@font-face {
  font-family: "Inter";
  src: local("Inter"),
       local("Inter Regular"),
       url("fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

local проверяет наличие шрифта в системе. Если найден — файл не загружается.


font-display: swap и стратегии загрузки

@font-face {
  font-family: "Inter";
  src: url("Inter.woff2") format("woff2");
  font-display: swap;
}

Как работают стратегии

          Block period    Swap period     Fallback
          (невидимый)     (подмена)       (остаётся)

auto:     [█████████████] [∞∞∞∞∞∞∞∞∞∞∞]
block:    [█████████████] [∞∞∞∞∞∞∞∞∞∞∞]
swap:                   [∞∞∞∞∞∞∞∞∞∞∞]
fallback: [██]            [██████]         [fallback font]
optional: [██]                           [fallback font]

Рекомендации

Тип шрифта Стратегия Причина
Основной текст swap Текст должен быть виден сразу
Заголовки swap или fallback Видимость важнее
Иконочный шрифт block Без шрифта — бессмысленные символы
Декоративный optional Не критичен для UX

Оптимизация производительности

1. Preload критического шрифта

<link rel="preload" href="/fonts/Inter-Regular.woff2" as="font" type="font/woff2" crossorigin>

2. Subsetting — загружать только нужные символы

/* Только кириллица */
@font-face {
  font-family: "Inter";
  src: url("Inter-Cyrillic.woff2") format("woff2");
  unicode-range: U+0400-04FF; /* Кириллица */
  font-display: swap;
}

/* Только латиница */
@font-face {
  font-family: "Inter";
  src: url("Inter-Latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153;
  font-display: swap;
}

Google Fonts автоматически разбивает шрифты по unicode-range. Браузер загружает только нужные подмножества.

3. Self-hosting vs CDN

Self-hosting Google Fonts CDN
Контроль Полный Ограниченный
Конфиденциальность Данные не уходят Запрос к Google
HTTP/2 Одно соединение Доп. соединения
Кэширование Ваш домен Общий кэш (отменён в 2020)
Рекомендация Для продакшна Для прототипов

4. Скачать Google Fonts для self-hosting

# Сервис google-webfonts-helper
# https://gwfh.mranftl.com/fonts

# Или npm-пакет
npx @nicedoc/google-fonts-helper Inter

5. Минимизировать количество шрифтов

/* ПЛОХО — 4 шрифта, 12+ файлов */
font-family: "Playfair Display", "Open Sans", "Roboto Mono", serif;

/* ХОРОШО — 1-2 шрифта */
font-family: "Inter", sans-serif; /* Один variable font для всех весов */

6. Fallback font metrics matching

/* Подогнать системный шрифт под размеры кастомного — уменьшить CLS */
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  ascent-override: 90.49%;
  descent-override: 22.48%;
  line-gap-override: 0%;
  size-adjust: 107.64%;
}

body {
  font-family: "Inter", "Inter Fallback", sans-serif;
}

Variable font — один файл для всех начертаний

@font-face {
  font-family: "Inter";
  src: url("Inter-Variable.woff2") format("woff2") tech("variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Теперь любой вес работает */
.thin    { font-weight: 100; }
.regular { font-weight: 400; }
.custom  { font-weight: 550; } /* Нестандартный — только с variable */
.bold    { font-weight: 700; }
.black   { font-weight: 900; }

Полный пример

<!-- HTML: preload + подключение -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload" href="/fonts/Inter-Variable.woff2" as="font" type="font/woff2" crossorigin>

<style>
  /* Self-hosted variable font */
  @font-face {
    font-family: "Inter";
    src: url("/fonts/Inter-Variable.woff2") format("woff2");
    font-weight: 100 900;
    font-display: swap;
  }

  /* Fallback metrics matching */
  @font-face {
    font-family: "Inter Fallback";
    src: local("Arial");
    size-adjust: 107.64%;
    ascent-override: 90.49%;
    descent-override: 22.48%;
  }

  body {
    font-family: "Inter", "Inter Fallback", system-ui, sans-serif;
    font-weight: 400;
    font-size: 1rem;
    line-height: 1.6;
  }

  h1 { font-weight: 700; }
  h2 { font-weight: 600; }
  strong { font-weight: 600; }
</style>

Частые ошибки

  1. Подключение через @import вместо <link> — блокирует рендеринг:

    /* МЕДЛЕННО */
    @import url('https://fonts.googleapis.com/...');
    
    /* БЫСТРО — в HTML */
    /* <link rel="preconnect" ...> + <link href="..." rel="stylesheet"> */
    
  2. Загрузка всех 18 весов вместо нужных 2-3 — лишние сотни килобайт

  3. Нет font-display — текст невидим 3 секунды при медленной сети (FOIT):

    /* ПЛОХО — текст мигает */
    @font-face { font-family: "X"; src: url(...); }
    
    /* ХОРОШО */
    @font-face { font-family: "X"; src: url(...); font-display: swap; }
    
  4. Один @font-face для разных весов — браузер применит faux bold:

    /* НЕПРАВИЛЬНО */
    @font-face {
      font-family: "Inter";
      src: url("Inter-Regular.woff2");
      /* без font-weight — по умолчанию 400 */
    }
    h1 { font-weight: 700; } /* Браузер сделает faux bold! */
    
  5. Нет crossorigin при preload шрифтов — шрифт загрузится дважды

Практика

  • Подключить шрифт через Google Fonts <link> с preconnect
  • Скачать шрифт WOFF2 и подключить через @font-face
  • Настроить font-display: swap и проверить загрузку в DevTools
  • Подключить variable font с диапазоном весов
  • Применить unicode-range для разделения кириллицы и латиницы
  • Реализовать fallback font matching через size-adjust

Связанные темы

Ресурсы