понедельник, 11 августа 2008 г.

Easy Way to Embed Transparent PNG24 into IE6 without JavaScript (vml xhtml)

Итак, есть задача - отобразить полупрозрачный png24:

  1. Способ должен работать везде, в том числе и в IE6 (и IE5 тоже было бы неплохо);
  2. Код должен быть семантичным;
  3. Картинка не является фоновой, но подумать о фоновом PNG не помешает;
  4. Желательно обойтись без яваскрипта;
  5. Посторонние визуальные эффекты недопустимы;
  6. Тормоза недопустимы;
  7. Лишние запросы на сервер и лишний трафик крайне нежелательны;
  8. Код должен быть валидным;
  9. При невозможности соблюдения всех вышеперечисленных условий должен соблюдаться принцип graceful degradation.
Решение
И, как всем известно, есть одна маленькая проблема - версии IE младше седьмой полупрозрачный PNG отобразить не в силах. Решений множество, но все они мне не нравятся по причине плохого качества - в них не соблюдается принцип graceful degradation [9] или [2, 4, 6, 7].
По сути нужно решить две задачи:
  1. Выделить IE6-, оставив остальным просто тег img.
    Это достаточно просто реализуется через условные комментарии для IE. Это просто волшебная вещь.
    [if (lt IE 7)&vml]
  2. Вылечить IE6-.
    Обычно все используют фильтры и JS, что и приводит к [5, 6]. Но есть способ лучше! Это VML! Поддерживается начиная с IE5.
    <v:image src="flower.png" style="width:85px;height:88px;" />
В очередной раз убеждаюсь, что тестировать нужно только в реальном окружении! Что эмуляторы IE врут безбожно. Забудьте по MultipleIEs и IETester. Поставьте официально бесплатную виртуальную машину от майкрософт с официально бесплатным образом нужной винды и увидите разницу.
Кстати, валидатор от W3C таки научился понимать пространства имен. Это позволяет не использовать условные комментарии для включения VML.

Особенности метода
  1. Картинка должна иметь указанный размер, иначе не будет показана;
  2. Картинка должна иметь точно указанный размер, иначе будет отмасштабирована;
  3. Бывают непонятные смещения в 1px. Лечится через margin;
  4. До работы с фоновым изображением у меня руки не дошли, теоретически это тоже можно эмулировать через v:image. Когда понадобится - решу и эту проблему.
Глюки
  1. Неполноценное кеширование [7]. IE6 всегда будет посылать лишние запросы If-Modified-Since. В IE7 это залечили, кстати, но нам это сейчас бесполезно. Решить эту проблему в IE6 мне не удалось;
  2. Значок и контур на месте загружаемой картинки [5]. Очень неприятно. Очень. Т.е. не работает нормальная интеграция в DOM и браузер не в состоянии определить загружена картинка или нет. Решить эту проблему мне не удалось.
Заключение
Я считаю, что эти глюки не противоречат [9]. Доля IE6 падает и проблема уходит. А пока она не ушла совсем, то можно и потерпеть, если пользуешься устаревшим браузером. Безусловно, всем этот метод не всем подходит, но на моих проектах доля IE6 уже менее 15%. Прогресс идет.

Демонстрация. Обратите внимание на лечение однопиксельного сдвига. А также на включение VML и на условные комментарии, если ранее не сталкивались.

Похоже, я первый, кто опубликовал такой метод. На мой взгляд это достаточно красивое решение. Я был бы очень благодарен за любые отзывы, критику и сообщения об ошибках.

3 коммент.:

egor комментирует...

А с фоновыми изображениями? Чтобы ссылки были поверх

Павел комментирует...

Пока не знаю - небыло необходимости. А вообще - это явно через JS. Если буду решать - обязательно опубликую.

Gleb Arestov комментирует...

http://www.minc.ne.jp/~konda/web_resoce/js/behavior/png2vml.html

мухахаха