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

http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax
  • Перевод
  • Tutorial
С самого начала «вебошрифтовой революции» мы полагались на неизящные хаки деклараций @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 предпочитает вопросительный знак (символ «?»). Код изменён, чтобы учесть это. Первоначально в этой блогозаписи восхвалялася волшебная решётка (символ «#»).
Поделиться публикацией
Похожие публикации
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 42
  • +20
    Первым на Хабрахабре об этой находке сообщил ZaiSL, разместивший топик-ссылку во блоге «Каскадные Таблицы Стилей».

    А здесь мною приводится перевод на русский язык той блогозаписи, на которую указывала эта ссылка.
    • +5
      во блоге
      вы взорвали мой мозг :(
      • +12
        Хотел написать «Mithgol детектед», а потом присмотрелся, оказался и правда Мицгол.
        • 0
          Ему не впервой, привыкайте. Хотя, признаться честно, «вебошрифты» и меня удивили =)
          • 0
            Вообще, так как «блог» — слово заимствованное, логично предположить, что к нему стоит применять общие правила, которые гласят об использовании предлога «во» вместо «в» перед словами, начинающимися с двух и более согласных. Так что, для взрыва мозга простым «во блоге» — причины отсутствуют.
            • 0
              Тем не менее, для русскоязычного Интернета более привычно словосочетание «в блоге»…
          • +2
            А почему при переводе символ "?" превратился в "#"?
            • +1
              Автор первоисточника сегодня (4 февраля) внёс в него дополнения и изменения.

              Я учёл их сейчас в своём переводе.

              Благодарю за внимательность.
          • +2
            Оперативно постите :)
            Chrome 9 — всё гуд!
            • +2
              Гениально.
              • +2
                уже появилось в опциях генератора fontsquirrel.com)
              • +2
                Воткните под кат пожалуйста статью.
                • +4
                  Хорошо!

                  Воткнул.
                  • 0
                    И все-таки воткнули кат. Дождались публичного обращения. Приватной рекомендации вам было недостаточно.: )
                    • +1
                      Единственной рекомендации было недостаточно. Когда их набралось три, я решил последовать гласу народа.
                      • +6
                        Следовать, в таких случаях, надо бы еще и простой логике, тогда не возникнет ни приватных обращений ни публичных, относящихся к оформлению материала.

                        Процитирую себя же в приватном обращении.

                        «И все же я считаю что пост, высота которого превышает его ширину больше чем в два раза (особенно при ширине монитора в 1024px), должен делиться на «до ката» и «после ката».»
                • +4
                  От себя добавлю, что упомянутые автором первоисточника «жалобы на отказ шрифтов загружаться в Android», которые появляются в случае следования рецепту Пола Айриша, вызваны известным багом в браузерах Android 2.2 и Android 2.3: эти браузеры, оказывается, вообще не воспринимают указание «local('имя шрифта')» и игнорируют декларацию @font-face, его содержащую.

                  Пол Айриш приводит специальный код, которым можно обойти эту проблему, используя уточнитель «@media screen and (max-device-width: 480px)» и метаэлемент <meta name="viewport">. При этом, как и в рецепте «Mo' Bulletproofer», появляется необходимость двойной декларации; кроме того, сейчас есть устройства с Android, использующие более широкие экраны, чем 480px. Так что костыль этот кривой и негодный; а вот рецепт Fontspring лишён этих недостатков, так как «local(…)» в нём вовсе не требуется.
                  • +2
                    Заставить баги IE работать во благо это круть :)
                    • 0
                      У меня вопрос вообще насчёт использования @font-face:
                      лично я его пока не использую только потому что при загрузке мне не нравится что шрифт дергается
                      (то есть сначала показывается шрифт без применения стилей,
                      подгружается шрифт и только потом меняется внешний вид текста)

                      Теперь вопросы:
                      1) Как-то можно избежать этого дерганья?

                      2) Помогает ли от такого поведения использование кэшированных шрифтов от Гугла?
                      (а-ля fonts.googleapis.com/css?family=IM+Fell+English|Molengo|Reenie+Beanie)

                      3) Насколько распространено решение из пункта 2?
                      Я просто нигде не припомню чтобы такое видел.
                      • 0
                        По поводу вопроса #2 Айриш предлагает решение:
                        paulirish.com/2009/fighting-the-font-face-fout/
                        • 0
                          Прошу прощения, вопрос #1 (про «дёргание»)
                        • 0
                          Про №1. В кеш лет на 10 все файлы из @font-face с отдачей верного type на сервере. Дернется всего один раз.
                          • 0
                            лично у меня проблема дергания была решена, тем что шрифт был в base64
                          • +1
                            Пост вдохнул веру в то, что всему своё время и место :) Здорово, что нашлось такое простое решение.
                            • 0
                              Кстати очень неплохая ссылка для тех кто пользуется «внешними» шрифтами:
                              http://www.fontsquirrel.com/fontface/generator
                              • 0
                                У этого способа есть недостатки: не работает в Опера (у меня). В ФФ и Хроме заметен процесс переключения шрифта.

                                Но я нашел решение:

                                /* для IE */
                                @font-face {
                                font-family: 'MyriadProLight';
                                src: url('fonts/myriadpro-light-webfont.eot?') format('embedded-opentype');
                                }
                                /* для не IE */
                                @font-face {
                                font-family: 'MyriadProLight';
                                src: url('fonts/myriadpro-light-webfont.svg#webfontOkKwgGFT') format('svg'), /* первым в списке для Opera */
                                url(data:font/woff;charset=utf-8;base64,...) format('woff'), /* подключаем через base64 для FireFox. В этом случае не заметен процесс подключения шрифта. */
                                url('fonts/myriadpro-light-webfont.ttf') format('truetype');
                                font-weight: normal;
                                font-style: normal;
                                }

                                Остается заметен процесс подключения шрифта в Хроме, но он не раздражает. И для меня остается загадкой почему Хром и ФФ загружают woff шрифт, а не svg, а Опера наоборот.
                                • 0
                                  Chrome 9, как и Opera 11 загружает svg, FF 3.6 — woff. Перерисовка шрифта в Chrome почти не заметна.
                                  • 0
                                    В конце концов понял, что svg надо подключать перед truetype для Оперы.
                                    • +3
                                      Пишу по просьбе Владимира Буторина:

                                      в рунете была замечена проблема, а именно – в Opera. Причем товарищ, заметивший данный баг, пришел к выводу, что дело решается простым подключением svg перед truetype.

                                      Так вот, это работает, но с некоторыми глюками (пропадает часть символов). А истинная же причина кроется в том, что в пути к данному документу есть русские символы! Как только я записывал тестовую папочку в корень или в папку без русских символов – все подключалось на ура.


                                      www.free-lance.ru/commune/?id=129&site=Topic&post=1438148&om=0
                                      • 0
                                        Спасибо за прояснение обстоятельств дела.

                                        Надеюсь, заинтересованные лица ужé передали разработчикам «Оперы» описание этой проблемы, надеясь на её исправление ими?
                                • 0
                                  А у вас нормально отображаются шрифты на iPhone в Safari?
                                  Делала свой пример, не заработало, думала, шрифт неправильно сгенерился (сама делала), но на сайте fontsquirrel.com тоже не отображаются.
                                  iOS 4.0
                                  • 0
                                    Заработало. Почему-то неправильный font id был прописан в @font-face, шрифт и css генерился белкой. Может кому поможет, ответ нашелся в статье, там было разъяснение про хеш.
                                  • 0
                                    Есть шрифт, кириллицу поддерживает. Но, когда я пытаюсь заюзать его с помощью @font-face, срабатывает только в том случае, если текст на латинице. Кириллицу тоись напрочь отказывается отображать :(
                                    Вы не подскажете, в чём может быть дело?
                                    Может быть, в конкретном шрифте?
                                    • 0
                                      Люди, может быть я задам глупый вопрос, но я для себя не могу найти на него ответа.

                                      С этими все понятно:

                                      EOT — only supported by Internet Explorer
                                      WOFF— Cross-browser, web-only font format that uses gzip compression. IE9+, FF3.6+, Chrome 5+
                                      SVG — This is an XML format required by iOS devices before version 4.2.

                                      НО!
                                      за чем тогда подключать TTF, если и без него все хорошо работает, WOFF недостаточно??
                                      Заранее спасибо за ответ.
                                      • 0
                                        Для старых версий браузеров, которые TTF ужé поддерживали, а WOFF ещё не поддерживали.

                                        Mozilla Firefox 3.5 (поддержка WOFF появилась в версии 3.6).

                                        Google Chrome 4 (поддержка WOFF появилась в версии 5).

                                        Opera 10 и 11.0 (поддержка WOFF появилась в версии 11.1).

                                        Safari 3.1 и 4 (поддержка WOFF появилась в версии 5.1).
                                    • 0
                                      Отлично! Как раз в данный момент волновала эта тема. Вы сэкономили мне несколько часов.
                                      • 0
                                        В Ваше втором примере eot шрифт не прописан в data. Tо есть получается в IE8 шрифт через data никак не добавить?
                                        • 0
                                          Как гласит официальная документация от Корпорации Microsoft, IE8 не поддерживает data длиннее 32 768 символов. Если учесть ещё и избыточность base64-кодировки, то получится, что это вопиюще неподходящий способ подключения шрифтов в IE8 (разве что шрифт попадётся двадцатикилобайтовый или ещё того меньше).

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