Home » CSS @font-face — как использовать пользовательские шрифты на сайте
CSS @font-face — как использовать пользовательские шрифты на сайте

CSS @font-face — как использовать пользовательские шрифты на сайте

Знаете, в нашей работе серверного админа часто приходится решать, казалось бы, простые задачи, которые на деле оказываются не такими уж тривиальными. Вот взять хотя бы кастомные шрифты на сайте — казалось бы, что тут сложного? А на практике оказывается, что неправильно настроенный @font-face может превратить ваш сайт в тормозящее чудище, которое грузится 10 секунд и съедает половину трафика пользователей. Особенно это критично, когда вы управляете несколькими серверами и хостите десятки проектов.

Сегодня разберём, как правильно использовать CSS @font-face, чтобы ваши кастомные шрифты не только красиво выглядели, но и не убивали производительность сервера. Покажу на реальных примерах, как оптимизировать загрузку, настроить кеширование и избежать типичных граблей, на которые наступают 90% разработчиков.

Как работает @font-face под капотом

Начнём с основ. @font-face — это CSS-правило, которое позволяет браузеру загружать шрифты с сервера вместо использования системных. Звучит просто, но дьявол кроется в деталях.

Когда браузер встречает @font-face, он:

  • Парсит CSS и находит объявление шрифта
  • Определяет, нужен ли этот шрифт для рендеринга страницы
  • Делает HTTP-запрос к серверу за файлом шрифта
  • Загружает и применяет шрифт к тексту

Проблема в том, что этот процесс может занимать несколько секунд, особенно если шрифт тяжёлый или сервер медленный. А пользователи в это время видят либо системный шрифт, либо вообще пустое место (привет, FOIT!).

Базовая настройка @font-face

Классическое объявление выглядит так:

@font-face {
  font-family: 'MyCustomFont';
  src: url('/fonts/mycustomfont.woff2') format('woff2'),
       url('/fonts/mycustomfont.woff') format('woff'),
       url('/fonts/mycustomfont.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

Но это только верхушка айсберга. Давайте разберём каждый параметр:

  • font-family — имя шрифта, которое будете использовать в CSS
  • src — пути к файлам шрифтов в порядке приоритета
  • font-weight/font-style — стиль и насыщенность шрифта
  • font-display — как браузер должен вести себя во время загрузки

Пошаговая настройка с оптимизацией

Вот как я настраиваю шрифты на продакшн-серверах:

Шаг 1: Подготовка файлов

Сначала конвертируем шрифты в современные форматы. Используем утилиту fonttools:

# Устанавливаем fonttools
pip install fonttools brotli

# Конвертируем TTF в WOFF2
fonttools ttLib.woff2 compress input.ttf

# Или используем онлайн-конвертер для быстрого результата
# Но лучше автоматизировать этот процесс

Шаг 2: Структура каталогов

/var/www/site/
├── fonts/
│   ├── roboto-regular.woff2
│   ├── roboto-regular.woff
│   ├── roboto-bold.woff2
│   └── roboto-bold.woff
└── css/
    └── fonts.css

Шаг 3: Правильное объявление CSS

/* Preload критически важные шрифты в HTML */
/*  */

@font-face {
  font-family: 'Roboto';
  src: url('/fonts/roboto-regular.woff2') format('woff2'),
       url('/fonts/roboto-regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Roboto';
  src: url('/fonts/roboto-bold.woff2') format('woff2'),
       url('/fonts/roboto-bold.woff') format('woff');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

Шаг 4: Настройка сервера

Для Apache (.htaccess):

# Включаем сжатие для шрифтов

  AddType application/font-woff2 .woff2
  AddOutputFilterByType DEFLATE application/font-woff2


# Настраиваем кеширование

  ExpiresActive on
  ExpiresByType application/font-woff2 "access plus 1 year"
  ExpiresByType font/woff2 "access plus 1 year"


# CORS для шрифтов

  
    Header set Access-Control-Allow-Origin "*"
  

Для Nginx:

location ~* \.(woff2?|ttf|otf)$ {
  expires 1y;
  add_header Cache-Control "public, immutable";
  add_header Access-Control-Allow-Origin "*";
  
  # Предварительное сжатие
  gzip_static on;
  gzip_types
    application/font-woff2
    font/woff2;
}

Сравнение форматов шрифтов

Формат Размер Поддержка Когда использовать
WOFF2 ~30% меньше TTF IE11+, все современные Основной формат для продакшена
WOFF ~20% меньше TTF IE9+ Fallback для старых браузеров
TTF Базовый размер Все браузеры Только для крайних случаев
EOT Больше TTF IE6-8 Устаревший, не используем

Продвинутые техники оптимизации

Subset fonts — загружаем только нужные символы:

# Создаём subset только с латинскими символами
pyftsubset font.ttf --output-file=font-latin.woff2 --flavor=woff2 --layout-features='*' --unicodes=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

# Или только кириллица
pyftsubset font.ttf --output-file=font-cyrillic.woff2 --flavor=woff2 --layout-features='*' --unicodes=U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116

Variable fonts — один файл вместо множества начертаний:

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

/* Использование */
.text {
  font-family: 'InterVariable', sans-serif;
  font-weight: 350; /* Любое значение в диапазоне */
}

Автоматизация и мониторинг

Создаём скрипт для автоматической оптимизации шрифтов:

#!/bin/bash
# optimize-fonts.sh

FONTS_DIR="/var/www/fonts"
TEMP_DIR="/tmp/font-processing"

mkdir -p $TEMP_DIR

for font in $FONTS_DIR/*.ttf; do
  filename=$(basename "$font" .ttf)
  
  # Конвертируем в WOFF2
  fonttools ttLib.woff2 compress "$font" -o "$FONTS_DIR/${filename}.woff2"
  
  # Создаём subset для латиницы
  pyftsubset "$font" --output-file="$FONTS_DIR/${filename}-latin.woff2" \
    --flavor=woff2 --layout-features='*' \
    --unicodes=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
  
  echo "Processed: $filename"
done

# Проверяем размеры
du -h $FONTS_DIR/*.woff2

Мониторинг производительности через скрипт:

#!/bin/bash
# check-font-performance.sh

SITE_URL="https://your-site.com"
FONT_PATH="/fonts"

# Проверяем время загрузки шрифтов
curl -w "@curl-format.txt" -o /dev/null -s "$SITE_URL$FONT_PATH/roboto-regular.woff2"

# Проверяем размеры шрифтов
find /var/www/fonts -name "*.woff2" -exec ls -lh {} \; | awk '{print $5 " " $9}'

Типичные проблемы и их решения

FOIT (Flash of Invisible Text) — пользователи видят пустое место во время загрузки шрифта:

/* Решение: используем font-display: swap */
@font-face {
  font-family: 'MyFont';
  src: url('/fonts/font.woff2') format('woff2');
  font-display: swap; /* Показываем fallback до загрузки */
}

Медленная загрузка — шрифты грузятся слишком долго:

/* Preload критически важные шрифты в HTML */


/* Используем local() для проверки системных шрифтов */
@font-face {
  font-family: 'MyFont';
  src: local('Arial'),
       url('/fonts/font.woff2') format('woff2');
}

CORS ошибки — шрифты не загружаются с CDN:

# Настраиваем CORS в Nginx
location ~* \.(woff2?|ttf|otf)$ {
  add_header Access-Control-Allow-Origin "*";
  add_header Access-Control-Allow-Methods "GET, OPTIONS";
  add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
}

Интересные факты и нестандартные применения

Вот несколько фишек, которые мало кто знает:

  • Unicode-range — можно загружать разные шрифты для разных языков автоматически
  • Font-feature-settings — активируем лигатуры и другие OpenType-фичи
  • Font-variation-settings — тонкая настройка variable fonts
@font-face {
  font-family: 'MultiLang';
  src: url('/fonts/latin.woff2') format('woff2');
  unicode-range: U+0000-00FF; /* Только латиница */
}

@font-face {
  font-family: 'MultiLang';
  src: url('/fonts/cyrillic.woff2') format('woff2');
  unicode-range: U+0400-04FF; /* Только кириллица */
}

/* Использование OpenType-фич */
.code {
  font-family: 'FiraCode', monospace;
  font-feature-settings: "liga" 1, "calt" 1; /* Лигатуры */
}

Интеграция с системами сборки

Для больших проектов удобно автоматизировать процесс через webpack:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(woff2?|ttf|otf)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: '[name].[hash].[ext]',
            outputPath: 'fonts/',
            publicPath: '/fonts/',
          }
        }
      }
    ]
  }
};

Производительность и метрики

Для мониторинга производительности шрифтов использую такие метрики:

  • FCP (First Contentful Paint) — когда появляется первый текст
  • LCP (Largest Contentful Paint) — когда загружается основной контент
  • CLS (Cumulative Layout Shift) — как сильно “прыгает” макет

Мониторим через Google PageSpeed Insights API:

#!/bin/bash
# pagespeed-check.sh

API_KEY="your-api-key"
URL="https://your-site.com"

curl -s "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$URL&key=$API_KEY" | \
jq '.lighthouseResult.audits["font-display"].score'

Альтернативные решения

Кроме @font-face есть несколько альтернативных подходов:

  • Google Fonts API — быстро, но зависимость от внешнего сервиса
  • System font stack — максимальная производительность, но ограниченный выбор
  • Font loading API — JavaScript-контроль загрузки шрифтов

Для высоконагруженных проектов рекомендую комбинированный подход:

/* Сначала system fonts для быстрого рендеринга */
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Затем асинхронно загружаем кастомные */
.fonts-loaded body {
  font-family: 'CustomFont', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

Заключение и рекомендации

Правильная настройка @font-face — это не только про красивый дизайн, но и про производительность всего сайта. Особенно это критично, когда вы управляете множеством проектов на VPS или выделенных серверах.

Мои главные рекомендации:

  • Используйте WOFF2 как основной формат
  • Всегда добавляйте font-display: swap
  • Настройте правильное кеширование на сервере
  • Мониторьте производительность через метрики
  • Автоматизируйте процесс оптимизации

И помните: лучший шрифт — это тот, который пользователь не замечает. Если ваши кастомные шрифты тормозят сайт, лучше откажитесь от них в пользу системных. Производительность всегда важнее красоты.

P.S. Не забывайте регулярно проверять актуальность форматов и поддержку браузеров. Веб-технологии развиваются быстро, и то, что работало год назад, может быть уже неоптимально сегодня.


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked