вебмастер, фидошник
0,0
рейтинг
4 февраля 2011 в 11:05

Дизайн → Новый пуленепробиваемый синтаксис @font-face перевод 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 предпочитает вопросительный знак (символ «?»). Код изменён, чтобы учесть это. Первоначально в этой блогозаписи восхвалялася волшебная решётка (символ «#»).
Перевод: Ethan Dunham
Mithgol the Webmaster @Mithgol
карма
60,5
рейтинг 0,0
вебмастер, фидошник
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Дизайн

Комментарии (41)

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

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

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

        Благодарю за внимательность.
  • +2
    Оперативно постите :)
    Chrome 9 — всё гуд!
  • +2
    Гениально.
  • +2
    уже появилось в опциях генератора fontsquirrel.com)
    • 0
    • –1
      На белке-шрифтелке действуют так оперативно, что коллега наш flight даже сперва подумал было, что этот рецепт и раньше там был :-)
      • +3
        Я уже согласился с вами =) Но даже до изобретения данного способа, белка работала как часы. Это только немного улучшило код.
  • +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 никак не добавить?

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