Internet Explorer i przezroczyste PNG

23 stycznia 2009

Tak tak, wiem, że problem z przezroczystością plików graficznych PNG w Internet Explorer (wersje 5.5 i 6) nie jest wcale nowy i już dawno go rozwiązano. Nadal sprawy nie można ignorować, 24% polskich użytkowników internetu wciąż używa IE 6. Ja do tej pory nie musiałem się z tym problemem borykać dlatego niewiele mnie on interesował. Zmieniło się to kilka dni temu :)

Rozwiązań jest kilka ale większość ma swoje wady. Albo nie przechodzą walidacji albo nie działają we wszystkich przypadkach (np. gdy nasz PNG jest ustawiony jako tło) albo strasznie mulą przeglądarkę.

Tak się składa, że w moim najnowszym projekcie używam przezroczystego PNG w dwóch miejscach, jako tło warstwy. Szybko okazało się, że większość rozwiązań odpada...

Ale znalazłem dość uniwersalne rozwiązanie, najlepsze z tych o których czytałem, stąd ten wpis (bo wcale nie tak łatwo było to znaleźć... :) ).

Mowa tu o IE PNG Alpha Fix. Ten mały skrypcik HTC rozwiązuje większość problemów z przezroczystością PNG w IE. Nie będę się nad tym rozwodził, to po prostu działa, jest najlepsze z tego co udało mi się znaleźć i najmniej kłopotliwe :) Nie podoba mi się w nim tylko to, że trzeba dodatkowo dołączać przezroczysty GIF (jest tutaj) ale jakoś to przeboleję :)

No dobra, nie podoba mi się jeszcze to, że autor nie przygotował żadnej paczki do ściągnięcia z potrzebnymi plikami i najlepiej z kilkoma przykładami. Plik HTC jest do ściągnięcia tutaj.

Jak tego używać? Jest kilka sposobów. Najprostszy to dodanie odpowiedniej reguły do CSS. Autor proponuje coś takiego:

CSS:
  1. img, div {
  2. behavior: url(iepngfix.htc);
  3. }

Jeżeli na stronie używasz przezroczystych PNG w wielu miejscach to możesz tak to właśnie ustawić. U mnie problem dotyczy tylko dwóch pliczków dlatego zdecydowanie lepiej jest stworzyć odpowiednią klasę i przypisać ją do odpowiednich warstw a następnie ustawić taki CSS:

CSS:
  1. .iepngfix {
  2. behavior: url(iepngfix.htc);
  3. }

Takie rozwiązanie będzie mniej obciążające dla przeglądarki (a więc szybsze).

Inny sposób (nie ma problemów z walidacją ale wymaga włączonego JavaScript i wcześniej musi być dołączony przynajmniej jeden zewnętrzny plik z regułami CSS):

JavaScript:
  1. <script type="text/javascript">
  2.  //<![CDATA[
  3.  
  4.  if (document.all && /MSIE (5\.5|6)/.test(navigator.userAgent) &&
  5.   document.styleSheets && document.styleSheets[0] && document.styleSheets[0].addRule)
  6.  {
  7.   // możesz dodać plik .htc do wszystkich obiektów
  8.   document.styleSheets[0].addRule('*', 'behavior: url(iepngfix.htc)');
  9.  
  10.   // lub tylko do wybranych np. warstw DIV
  11.   document.styleSheets[0].addRule('div', 'behavior: url(iepngfix.htc)');
  12.  }
  13.  
  14.  //]]>
  15.  </script>

W powyższym przykładzie są dwa sposoby dołączenia pliku HTC. Do wszystkich obiektów lub tylko do wybranych tagów. Przed umieszczeniem kodu na swojej stronie pamiętaj żeby wybrać tylko jedno z tych rozwiązań, nigdy oba. Dlatego którąś linijkę będziesz musiał usunąć.

Sposób na wyłączenie przezroczystych PNG podczas drukowania:

JavaScript:
  1. <script type="text/javascript">
  2.  //<![CDATA[
  3.  
  4.  if (window.attachEvent  && /MSIE (5\.5|6)/.test(navigator.userAgent))
  5.  {
  6.   function printPNGFix(disable)
  7.   {
  8.    for (var  i = 0; i <document.all.length; i++)
  9.    {
  10.     var e = document.all[i];
  11.     if (e.filters['DXImageTransform.Microsoft.AlphaImageLoader'] || e._png_print)
  12.     {
  13.      if (disable)
  14.      {
  15.       e._png_print = e.style.filter;
  16.       e.style.filter = '';
  17.      }
  18.      else
  19.      {
  20.       e.style.filter = e._png_print;
  21.       e._png_print = '';
  22.      }
  23.     }
  24.    }
  25.   };
  26.   window.attachEvent('onbeforeprint',  function() { printPNGFix(1) });
  27.   window.attachEvent('onafterprint',  function() { printPNGFix(0) });
  28.  }
  29.  
  30.  //]]>
  31.  </script>

Na koniec chciałbym wspomnieć o jednym problemie na który się natknąłem. Jeżeli masz warstwę w której jest odnośnik a warstwa jako tło ma przezroczysty PNG i w CSS ustawiono position: relative; lub position: absolute; dla tej warstwy to odnośnik nie będzie klikalny ;) Ot, taki kolejny bug w IE... Niestety nasz pliczek HTC za każdym razem informuje nas o takiej sytuacji zgrabnym alertem... Żeby go usunąć wystarczy zakomentować/usunąć te trzy linijki (oczywiście w pliku HTC):

JavaScript:
  1. if (t && (/relative|absolute/i).test(currentStyle.position))
  2.     alert('IEPNGFix: Children of positioned element are unclickable:\n\n<' +
  3.      nodeName + (id && ' id=' + id) + '>');

Rozwiązanie powyższego problemu (nieklikalne odnośniki) niby jest tutaj ale ja się nie wczytywałem :)

Plik działa tylko w IE 5.5 i IE 6, w innych przeglądarkach jest ignorowany. Nie stwarza więc dodatkowych problemów.

Dodaj komentarz

7 odpowiedzi dla tego wpisu

  1. izka napisał:

    hmmm…Eureka!!!…. ;) zgadłam? :)

  2. wowotec napisał:

    A nie lepiej zapisać png w formacie 8 bitowym? Też działa i nie tracisz czasu na odzczyt pliku HTC, a dotego rozmiar jest dużo mniejszy.
    poczytaj: http://www.sitepoint.com/blogs.....r-winner/#

  3. MariuszT napisał:

    Nie wiedziałem o tym, ciekawe ale nie doskonałe. Rozwiązania w JS czy HTC mają tą przewagę, że są wygodne. Po prostu działają i nie trzeba się jakoś specjalnie przygotowywać, zmieniać plików PNG etc.

    Szkoda, że ta alternatywa ma tak małą paletę kolorów, często to wystarczy ale nie zawsze. No i te IE6…

    Mimo wszystko dobrze, że jest jakiś wybór, przy każdej stronie www trzeba rozważyć wszystkie za i przeciw. Bardzo możliwe, że w następnym projekcie użyję PNG 8-bit. Dzięki za tego linka.

  4. Maciej napisał:

    Zapraszam do zapoznania się z pisem na moim blogu dotyczącym tego tematu.
    http://www.chalapuk.pl/2010/06.....png-w-ie6/
    Pozdrawiam

  5. MariuszT napisał:

    Maciek, trochę się spóźniłeś, temat jest już średnio aktualny, wszyscy się wycofują z suportu IE6.

  6. Maciej napisał:

    Nie wiem od czego to zależy, ale u mnie w pracy na Windows XP64 IE7 nie potrafi renderować PNG bez DirectX, więc temat chyba nadal aktualny.

  7. MariuszT napisał:

    Coś tam kiedyś słyszałem, że IE7 też ma czasami problemy z kanałem alpha PNG. Sam osobiście nigdy nie spotkałem. Z drugiej strony jak mam spotkać skoro nie używam IE :) Tylko w nim testuję.

    Podsumowując: ja problem olewam ale być może istnieje, w IE nic już mnie nie zdziwi.

Odpowiedz



Podobne wpisy: