Выбрать главу

}

Здесь в адресе картинки идет протокол mhtml (который поддерживается исключительно в IE, но это не так важно), далее полный URL до CSS-файла (который содержит эту картинку), в данном случае этот URL еще и содержит GET-параметр для соответствующего кэширования. И небольшая тонкость применения данного формата: необходимо в URL использовать ту же строку, что и в HTML-файле, в котором подключается данный CSS, иначе IE запросит CSS-файл дважды: первый раз как таблицу стилей, второй раз — как хранилище картинки. Далее после восклицательного знака (!) идет тот идентификатор, который мы назначили картинке в Content-Location. И все.

Объединяем несовместимое

С одной стороны, у нас схема data:URI, которая поддержана W3C и распознается всеми браузерами, кроме IE. С другой стороны, у нас IE, который понимает mhtml и с которым работают 70% наших пользователей. Мы объединим эти два решения, благо они оба используют base64-представление картинок.

Задача первая: объединить оба назначения стилевых правил, чтобы они не конфликтовали друг с другом. Решается это очень просто с помощью либо отдельного CSS-файла для IE (через условные комментарии), либо CSS-хаков (последнее предпочтительнее, ибо позволяет загружать всего один CSS-файл). В итоге в CSS-файле мы имеем примерно следующее:

/*

Content-Type: multipart/related; boundary="_"

--_

Content-Location: 1

Content-Transfer-Encoding: base64

iVBOR..

*/

ul li {

background: #fff url(data:image/png;base64,iVBOR...) 0 0 no-repeat;

}

* html ul li {

background-image: url(mhtmclass="underline" http://site.ru/main.css?20081010!1);

}

*+html ul li {

background-image: url(mhtmclass="underline" http://site.ru/main.css?20081010!1);

}

Данная конструкция позволяет вывести фоновое изображение в base64-кодировке для всех (ну или 99,9%) браузеров. Почему в конце содержатся 2 разных CSS-селектора с одним объявлением? Первое предназначено для IE6 и предыдущих версий, второе — для IE7. Объединить через запятую их нельзя.

Панацея или ящик Пандоры?

Первый же скептический вопрос, который каждый читатель должен в этом месте задать: как можно эти картинки выводить только один раз в CSS-файле (можно заметить, что base64-строка фигурирует там дважды)? Ответ: никак. Однако выход есть.

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

Стоит также заметить, что при таком подходе результирующий сжатый файл занимает даже меньше, чем при назначении с помощью CSS-хаков для IE внешних изображений для загрузки (ведь используется меньше различных конструкций).

Валидность

Получившийся таким образом CSS-файл абсолютно валиден (так как все mhtml-вставки происходят в комментариях). Каждое CSS-объявление валидно с точки зрения CSS 2.1, и те небольшие приемы, которые позволяют эффективно сжать данные для всех браузеров, не отражаются на восприятии ими файла. Такой подход будет уместным только для CSS. Для HTML ситуация совсем другая (о ней немного подробнее ниже). HTML-документ при таком подходе оказывается невалидным, что выливается во множественные проблемы верстки, и это не та же цена, которую можно заплатить за некоторый не очень явный рост производительности.

Некоторые итоги

Картинки в CSS можно вставлять с помощью data:URI.

Для IE можно использовать mhtml, полностью дублирующий эту функциональность.

Для корректного применения стилей нужны CSS-хаки либо разделение CSS-файлов.

Используем gzip для CSS-файлов для устранения последствий множественного использования base64-строки.

Использовать base64-кодирование на ваших страницах можно уже прямо сегодня. Очень важно при этом понимать возможные последствия и по возможности обойтись малой кровью. Однако с выходом IE8 и массовым его распространением ситуация кардинально изменится (ведь он поддерживает data:URI и для него описанные обходные приемы уже теряют свою актуальность).

Включение музыки (base64)

Летом 2008 года весь мир облетела страница, содержащая реализацию первого уровня Super Mario Brothers. В нее, в общем, можно играть, хотя упущены многие ключевые аспекты (нет грибов, нет флага, нет повышающих очков и т. д.). Однако это, на самом деле, не самый интересный аспект этой разработки.

Наверное, больше всего интереса в этом веб-приложении представляет не сама игровая механика, а тот факт, что все собрано в одном-единственном файле — игровом скрипте, который включает все игровые спрайты и всю музыку. Это весьма любопытный образец использования технологий. Удивительно, но способ подключения музыки в этом приложении, пожалуй, наиболее простой для понимания. Приложение использует схему data:URI, которая кодирует музыкальные MIDI-файлы Mario в base64-виде.