Pull to refresh

Новый пуленепробиваемый синтаксис @font-face

Typography *
Translation
Tutorial
Original author: Ethan Dunham
С самого начала «вебошрифтовой революции» мы полагались на неизящные хаки деклараций @font-face, чтобы шрифты из Паутины загружались во всех браузерах. Может ли существовать лучший путь? Вполне изящный и совместимый с будущими браузерами?

Вкратце об истории вопроса


В сентябре 2009 года Пол Айриш (Paul Irish) огласил пуленепробиваемый синтаксис для записи деклараций @font-face. Синтаксис был компактным и в то время действовал во всех браузерах. Недавно стали поступать, со временем усиливаясь, жалобы на отказ шрифтов загружаться в Android — поэтому мы стали вместо того рекомендовать синтаксис «Mo' Bulletproofer», сочинённый Ричардом Финком (Richard Fink). К сожалению, синтаксису «Mo' Bulletproofer» требуется двойная запись деклараций, так что поддержка его сложнее.

Синтаксис Fontspring @Font-Face


А вот таким этому коду следовало бы быть с самого начала. Чистым, ясным и простым:
@font-face {
	font-family: 'MyFontFamily';
	src: url('myfont-webfont.eot?') format('eot'), 
	     url('myfont-webfont.woff') format('woff'), 
	     url('myfont-webfont.ttf')  format('truetype'),
	     url('myfont-webfont.svg#svgFontName') format('svg');
	}

Что? Я не понял.


Хак Трюк, заставляющий этот код заработать — символ «?» вслед за именем файла EOT. Без шуток.

Как это срабатывает


Internet Explorer (в версиях более ранних, чем девятая) содержал баг в обработчике значения «src». Если в «src» поместить больше одного формата шрифта, то IE не сможет загрузить его и сообщит об ошибке 404. Причина в том, что IE пытается использовать как адрес файла всё, что записано после первой открывающей скобки и до самой последней закрывающей скобки. Чтобы преодолеть это некорректное поведение, просто определите EOT первым и добавьте единственный символ «?». Он обманет IE, который станет думать, что остаток строки является строкою запроса (query string), и загрузит только файл EOT. Остальные браузеры последуют спецификации CSS — выберут необходимый им формат, исходя из последовательности значений «src» и указаний формата шрифта.

Совместимость с браузерами


Safari 5.03, IE 6­-9, Firefox 3.6­-4, Chrome 8, iOS 3.2­-4.2, Android 2.2­-2.3, Opera 11.

А как насчёт шрифтов в «data:…»-адресах?


Вы можете воспользоваться этим синтаксисом и для встраивания шрифтов в CSS-стиль. Однако, чтобы это сработало, понадобятся две декларации. Хотя, если уж вы пошли этой дорогою, разве лишняя декларация значит хоть что-то? Также обратите внимание, что указание формата должно быть «embedded-opentype».
@font-face {
	font-family: 'MyFontFamily';
	src: url('myfont-webfont.eot?') format('embedded-opentype');
	}
	
@font-face {
	font-family: 'MyFontFamily';
	src: url(data:font/truetype;charset=utf-8;base64,ЗДЕСЬ_ДАННЫЕ_КОДОМ_BASE64) format('truetype'),
	     url(data:font/woff;charset=utf-8;base64,ЗДЕСЬ_ДАННЫЕ_КОДОМ_BASE64) format('woff'),
	     url('myfont-webfont.svg#svgFontName') format('svg');
	}

Обновление 1 — от 3 февраля 2011 г.


The CSSNinja великолепно подметил, как можно принудить IE9 подхватить WOFF-шрифт вместо EOT. Он предложил добавить символ «#» к указанию формата EOT. (Это срабатывает, потому что IE9 не узнаёт указание формата «#embedded-opentype».) Чтобы учесть его находку, я переменил вышеизложенный синтаксис. Указание формата «embedded-opentype» я заменил на «eot», которое IE9 также не понимает и поэтому двигается далее, туда где WOFF.

Примечание переводчика:  CSSNinja тоже не стоит на месте и предложил запись «format('')». Она на два символа короче и к тому же является реверансом в сторону Пола Айриша, впервые предложившего запись «local('')» для обмана IE.

Обновление 2 — от 4 февраля 2011 г.


IE отказывался загружать вебошрифты, когда страница открыта локально (с диска у читателя). Получается, что IE предпочитает вопросительный знак (символ «?»). Код изменён, чтобы учесть это. Первоначально в этой блогозаписи восхвалялася волшебная решётка (символ «#»).
Tags:
Hubs:
Total votes 141: ↑132 and ↓9 +123
Views 70K
Comments Comments 42