@font-face в деталях

Автор: Евгений Рыжков Дата публикации: 26.08.2011

Типичный вид CSS правил, который генерирует сервис Typekit для внедрения шрифта выглядит так:

@font-face {
    font-family: "JournalRegular";
    src: url("journal-webfont.eot");
    src: url("journal-webfont.eot?#iefix") format("embedded-opentype"),
         url("journal-webfont.woff") format("woff"),
         url("journal-webfont.ttf") format("truetype"),
         url("journal-webfont.svg#JournalRegular") format("svg");
    font-weight: normal;
    font-style: normal;
}

Разберем детально что тут к чему и нужно ли оно.

font-family

Задаем имя внедряемого шрифта, которое потом можно будет указать нужным элементам. Например, заголовкам h1 зададим внедренный шрифт:

h1 { font-family: JournalRegular; }

Указать имя шрифту можно любое — на свое усмотрение. Кавычки обязательны только для имен, состоящих из более чем одного слова.

Вывод: правило обязательное.

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

С помощью параметра src указываем путь к внедряемому шрифту. Думаю каждому понятно, что данный параметр тоже обязателен.

Зачем так много форматов

В качестве ответа приведу таблицу поддержки форматов различными браузерами:

Формат Поддерживают браузеры
EOT
  • IE6+
WOFF
  • IE9+
  • FF 3.6+
  • 11+
  • Chrome 6+
  • 5.1+
  • Opera mobile 11+
TTF и OTF
  • FF 3.5+
  • 10+
  • Chrome 4+
  • 3.2+
  • Opera mobile 10+
  • iOS 4.2+
  • Android 2.2+
SVG
  • 9+
  • Chrome 4+
  • 3.2+
  • Opera mobile 10+
  • iOS
  • Android 3

Т.е. такое обилие подключаемых форматов обусловлено максимальным покрытием браузеров. При этом браузер загружает только первый из списка, который сможет отобразить (при условии указанных format).

О порядке шрифтов

Т.к. грузится только первый шрифт, который браузер поддерживает, логичным будет указывать шрифты в порядке увеличения веса. Замечу сразу, что визуально все форматы выглядят одинаково. Хотя WOFF самый легкий, на первом месте стоит EOT для избежания бага в IE6-8.

Сокращаем запись

Если задача стоит в разработке под наиболее популярные браузеры, тогда в основном CSS можно оставить только WOFF:

@font-face {
    font-family: JournalRegular;
    src: url(journal-webfont.woff) format("woff");
    font-weight: normal;
    font-style: normal;
}

Для IE6-8 внедрить EOT в отдельном CSS подключенным через условные комментарии

@font-face {
font-family: JournalRegular;
    src: url(journal-webfont.eot);
    src: url(journal-webfont.eot?#iefix) format("embedded-opentype");
}

А для мобильных браузеров подключить отдельный CSS с TTF и SVG (для этого потребуется на стороне сервера определить, что это мобильное устройство и отдать нужный CSS).

Нужно ли указывать format?

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

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

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

@font-face {
    font-family: JournalRegular;
    src: url(journal-webfont.woff);
    font-weight: normal;
    font-style: normal;
}

О декларации для IE

Во-первых их две. Первая строка (src: url(journal-webfont.eot);) — это для IE9. Вторая — IE6-8. (journal-webfont.eot?#iefix) такая хитрая запись нужна для фикса потенциально возможного бага в IE, который может коряво обработать src. IE9 хорошо понимает WOFF, поэтому если подключать отдельные стили для IE6-8, можно оставить только одну строку и при этом можно убрать фикс бага и format.

@font-face {
font-family: JournalRegular;
src: url(journal-webfont.eot);
}

Недостаток такой оптимизации

В IE6-8 появится дополнительный запрос к серверу: браузер будут пытаться загрузить шрифт из основного файла стилей с багом, о котором уже упоминал выше. Шрифт не подключится, после чего IE загрузит eot. Тут решать каждому, что в приоритете: то ли современные браузеры, то ли отсталые «ослы».

Заметка о WOFF

WOFF имеет преимущества перед остальными:

  1. это сжатый формат, легче любого другого почти в два раза;
  2. имеет относительную защиту — шрифт можно будет использовать только в Веб;
  3. содержит информацию о происхождении шрифта.

Зачем указывать font-style и font-weight

Чтобы явно определить стиль и жирность подключаемого шрифта. Если подключается шрифт всего с одним стилем и жирностью, можно эти правила упустить. Конечно если начертание шрифта совпадает со значениями по умолчанию: font-syle: normal, font-weight: normal.

@font-face {
    font-family: Journal;
    src: url(journal-webfont.woff);
}

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

@font-face {
    font-family: JournalRegular;
    src: url(journal-webfont-regular.woff);
}
@font-face {
    font-family: JournalBold;
    src: url(journal-webfont-bold.woff);
}
@font-face {
    font-family: JournalItalic;
    src: url(journal-webfont-italic.woff);
}
h1 {
	font-family: JornalBold;
}
p {
	font-family: JournalRegular;
}
em {
	font-family: JournalItalic;
}

Это, конечно, будет работать. Но ошибка тут в том, что для разных начертаний используется разные имена шрифтов, а не соответствующие CSS правила. Это усложняет чтение кода, поддержку его, а та же может привести к неверному отображению элемента, если шрифт не загрузится (например, заголовок может остаться regular вместо требуемого bold).

Правильнее будет использовать шрифты следующим образом:

@font-face {
    font-family: Journal;
    src: url(journal-webfont-regular.woff);
	font-style: normal;
	font-weight: normal;
}
@font-face {
    font-family: JournalBold;
    src: url(journal-webfont-bold.woff);
	font-style: normal;
	font-weight: bold;
}
@font-face {
    font-family: JournalItalic;
    src: url(journal-webfont-italic.woff);
	font-style: italic;
	font-weight: normal;
}
h1 {
	font-family: Jornal;
	font-weight: bold;
}
p {
	font-family: Journal;
	font-style: normal;
}
em {
	font-family: Journal;
	font-style: italic;
}

Данный код можно сократить, используя значения по умолчанию. Тут я написал полностью для лучшей наглядности.

Что можно еще добавить в @font-face

В рассмотренные выше правила вошли не все возможные, а только самые востребованные на данный момент. Для полноты картины познакомимся с остальными.

font-stretch

font-stretch задает ширину символов. Используется в @font-face по аналогии с font-syle и font-weight. По умолчанию имеет значение normal. Пока нет особого смысла использовать из-за слабой поддержки браузерами.

@font-face {
    font-family: Journal;
    src: url(journal-webfont-regular.woff);
	font-style: normal;
	font-weight: normal;
	font-stretch: normal;
}

local

Данная декларация говорит браузеру чтобы тот вначале поискал нужный шрифт на машине пользователя и только если нужный не нашелся, тогда грузить его из сети. Можно использовать несколько local, чтобы указать все возможные варианты записи шрифта в системе.

@font-face {
    font-family: Journal;
    src: local(JournalRegular), local("Journal Regular"),
		 url(journal-webfont-regular.woff);
	font-style: normal;
	font-weight: normal;
}

Использовать данную декларацию нужно очень осторожно, из-за проблем в некоторых браузерах.

unicode-range

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

@font-face {
    font-family: Journal;
    src: url(journal-webfont-regular.woff);
    unicode-range: U+00-FF, U+980-9FF;
}

Поддержка браузерами на данный момент сильно хромает.

Материалы

По теме