CSS @font-face

Правило CSS, обеспечивающее работу шрифтовых иконок в вебе — объявление, загрузка и использование пользовательских шрифтовых файлов в таблицах стилей.

Основы

@font-face — это CSS at-правило, которое сообщает браузеру, где найти шрифтовой файл и как его назвать. Впервые оно было поддержано в IE 4 ещё в 1997 году, но стало практичным для всех браузеров лишь около 2010 года, когда появился WOFF и другие браузеры последовательно реализовали это правило.

Для шрифтовых иконок @font-face является связующим звеном между шрифтовыми файлами и CSS-классами, отображающими иконки. Без него браузер не имеет возможности узнать, что font-family: 'MyIcons' должен загрузить конкретный файл с вашего сервера.

Базовый синтаксис
@font-face {
  font-family: 'MyIcons';
  src: url('fonts/myicons.woff2') format('woff2');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

Дескриптор font-family даёт шрифту имя, на которое вы будете ссылаться в дальнейшем. Дескриптор src сообщает браузеру, откуда загрузить файл и в каком формате он представлен. Дескрипторы font-weight и font-style гарантируют, что браузер не будет пытаться синтезировать жирные или курсивные варианты. А font-display управляет поведением во время загрузки шрифта.

Современный стек шрифтов

Подсказка format() после каждого URL сообщает браузеру, в каком формате файл, чтобы он мог пропускать неподдерживаемые форматы без их предварительной загрузки. За прошедшие годы рекомендуемый набор форматов значительно сократился по мере улучшения поддержки браузерами.

Современный вариант (рекомендуется)
@font-face {
  font-family: 'MyIcons';
  src: url('myicons.woff2') format('woff2');
  font-display: swap;
}

При охвате 97%+ браузеров одного WOFF2 достаточно для подавляющего большинства современных проектов. Это наиболее простой и производительный подход.

С запасным WOFF (поддержка IE 11)
@font-face {
  font-family: 'MyIcons';
  src: url('myicons.woff2') format('woff2'),
       url('myicons.woff') format('woff');
  font-display: swap;
}

Добавление WOFF в качестве запасного варианта охватывает IE 11, который не поддерживает WOFF2. Современные браузеры возьмут файл WOFF2; IE 11 откатится к WOFF.

Полный устаревший стек (поддержка IE 6-8)
@font-face {
  font-family: 'MyIcons';
  src: url('myicons.eot');                    /* IE9 compat */
  src: url('myicons.eot?#iefix') format('embedded-opentype'),
       url('myicons.woff2') format('woff2'),
       url('myicons.woff') format('woff'),
       url('myicons.ttf') format('truetype');
  font-display: swap;
}

Полный «пуленепробиваемый» стек включает EOT для IE 6-8, WOFF2 для современных браузеров, WOFF для IE 9-11 и TTF как финальный запасной вариант. Браузер последовательно перебирает каждый элемент src и использует первый понятный ему формат. Этот подход необходим только для проектов с жёсткими требованиями к поддержке устаревших браузеров.

Использование классов иконок

Стандартный паттерн для шрифтовых иконок использует базовый класс, который задаёт font-family и общие стили рендеринга, а затем индивидуальные классы иконок, использующие псевдоэлементы ::before с content, установленным на кодовую точку Unicode каждой иконки.

CSS-классы иконок
.icon {
  font-family: 'MyIcons';
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-home::before { content: '\E001'; }
.icon-search::before { content: '\E002'; }
.icon-user::before { content: '\E003'; }

Базовый класс сбрасывает стилизацию шрифта, чтобы браузер не применял жирное начертание, курсив или другие трансформации, которые исказят иконки. Свойства -webkit-font-smoothing и -moz-osx-font-smoothing включают сглаживание для более чёткого отображения в macOS и iOS.

Каждый класс иконки устанавливает псевдоэлемент ::before с кодовой точкой Unicode, назначенной этому глифу. Нотация с обратной косой чертой (\E001) — это способ CSS ссылаться на символ Unicode по его шестнадцатеричной кодовой точке.

Использование в HTML
<i class="icon icon-home"></i>
<span class="icon icon-search"></span>

Оба элемента — <i> и <span> — работают одинаково хорошо. Сам элемент пустой — иконка целиком отображается псевдоэлементом ::before.

font-display

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

ЗначениеПоведениеЛучше всего для
swapНемедленно показывает запасной текст, переключается на шрифт иконок при загрузкеШрифтовые иконки (рекомендуется)
blockКратко скрывает текст (до 3с), затем показывает запаснойТекстовые шрифты, когда мерцание нежелательно
fallbackКороткая блокировка (~100мс) + короткая замена (~3с)Хороший баланс для текстовых шрифтов
optionalБраузер может полностью пропустить шрифт на медленных соединенияхНеобязательные декоративные шрифты

Для шрифтовых иконок swap является рекомендуемым выбором. Кратковременное мерцание нестилизованного содержимого (когда кодовые точки иконок могут выглядеть как квадраты или пустые пробелы) значительно лучше, чем невидимые иконки. С block пользователи могут видеть пустое место там, где должны быть иконки, в течение до 3 секунд на медленных соединениях — что выглядит как сломанная страница. С swap иконки появляются сразу после загрузки шрифта, и переход обычно незаметен на современных соединениях.

Оптимизация загрузки

Шрифтовые файлы по умолчанию блокируют рендеринг — браузер не будет отрисовывать текст с пользовательским шрифтом до завершения загрузки файла. Вот техники для минимизации этого воздействия:

  • Предзагрузка шрифтового файла — используйте <link rel="preload"> для начала загрузки шрифта как можно раньше, до того как браузер даже разберёт CSS, ссылающийся на него.
  • Самостоятельное размещение шрифтов — размещение шрифтовых файлов на том же источнике, что и HTML, позволяет избежать дополнительных DNS-запросов и установки соединений, а также устраняет проблемы CORS.
  • Субсеттинг шрифта — удаляйте неиспользуемые иконки для уменьшения размера файла. Шрифт из 500 иконок, из которых вы используете только 50, расходует 90% загрузки впустую.
  • Использование unicode-range — если у вас несколько наборов иконок, этот дескриптор указывает браузеру загружать шрифтовой файл только тогда, когда символы из указанного диапазона действительно используются на странице.
Предзагрузка шрифтового файла
<link rel="preload" href="fonts/myicons.woff2" as="font"
      type="font/woff2" crossorigin>

Атрибут crossorigin обязателен даже для шрифтов того же происхождения — это особенность спецификации загрузки шрифтов. Без него браузер загрузит шрифт дважды: один раз по подсказке preload (без CORS) и один раз по правилу @font-face (с CORS).

Типичные ошибки

  • Ошибки CORS — шрифтовые файлы, обслуживаемые с другого источника (например, поддомена CDN), требуют заголовков Access-Control-Allow-Origin на сервере. Либо используйте атрибут crossorigin на теге <link>. Без правильной настройки CORS браузер молча заблокирует шрифт.
  • Иконки отображаются как квадраты или прямоугольники — обычно это означает, что путь к шрифтовому файлу неверен, шрифт ещё не загрузился, или имя font-family в классе иконки не совпадает с именем в объявлении @font-face. Проверьте вкладку Network в браузере, чтобы убедиться, что шрифтовой файл загрузился со статусом 200.
  • Иконки отображают неправильные глифы — конфликт кодовых точек Unicode с системными шрифтами. Если шрифт иконок использует кодовые точки в диапазонах, пересекающихся с распространёнными системными шрифтами, браузер может отрисовать системный символ вместо иконки. Шрифты иконок обычно используют зону частного использования (U+E000 до U+F8FF), чтобы этого избежать.
Совет по отладке
Откройте DevTools браузера, перейдите на вкладку Network и отфильтруйте по «Font». Вы должны увидеть ваш файл .woff2 со статусом 200. Если он отсутствует — путь неверный. Если отображается ошибка CORS — проверьте заголовки сервера. Если файл загрузился, но иконки всё равно не отображаются — проверьте элемент и убедитесь, что font-family совпадает точно.
В Bobcorn
Bobcorn генерирует полный CSS-файл за вас — объявление @font-face, базовый класс .icon и индивидуальные классы иконок с правильными кодовыми точками Unicode. CSS использует выбранное вами имя шрифта и ссылается на шрифтовые файлы с относительными путями. Включите опцию CSS в диалоге экспорта, чтобы добавить его к вашим шрифтовым файлам.