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:
-
img, div {
-
behavior: url(iepngfix.htc);
-
}
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:
-
.iepngfix {
-
behavior: url(iepngfix.htc);
-
}
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):
-
<script type="text/javascript">
-
//<![CDATA[
-
-
if (document.all && /MSIE (5\.5|6)/.test(navigator.userAgent) &&
-
document.styleSheets && document.styleSheets[0] && document.styleSheets[0].addRule)
-
{
-
// możesz dodać plik .htc do wszystkich obiektów
-
document.styleSheets[0].addRule('*', 'behavior: url(iepngfix.htc)');
-
-
// lub tylko do wybranych np. warstw DIV
-
document.styleSheets[0].addRule('div', 'behavior: url(iepngfix.htc)');
-
}
-
-
//]]>
-
</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:
-
<script type="text/javascript">
-
//<![CDATA[
-
-
if (window.attachEvent && /MSIE (5\.5|6)/.test(navigator.userAgent))
-
{
-
function printPNGFix(disable)
-
{
-
for (var i = 0; i <document.all.length; i++)
-
{
-
var e = document.all[i];
-
if (e.filters['DXImageTransform.Microsoft.AlphaImageLoader'] || e._png_print)
-
{
-
if (disable)
-
{
-
e._png_print = e.style.filter;
-
e.style.filter = '';
-
}
-
else
-
{
-
e.style.filter = e._png_print;
-
e._png_print = '';
-
}
-
}
-
}
-
};
-
window.attachEvent('onbeforeprint', function() { printPNGFix(1) });
-
window.attachEvent('onafterprint', function() { printPNGFix(0) });
-
}
-
-
//]]>
-
</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):
-
if (t && (/relative|absolute/i).test(currentStyle.position))
-
alert('IEPNGFix: Children of positioned element are unclickable:\n\n<' +
-
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.
Blog przede wszystkim o Internecie i mojej pasji jaką jest tworzenie stron www. Ale nie ograniczam się do jednej tematyki, piszę o wszystkim o czym mam ochotę :-)
izka napisał: 24.01.09 o godzinie 19:51
hmmm…Eureka!!!….
zgadłam?
wowotec napisał: 17.12.09 o godzinie 16:24
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/#
MariuszT napisał: 17.12.09 o godzinie 22:21
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.
Maciej napisał: 22.06.10 o godzinie 10:07
Zapraszam do zapoznania się z pisem na moim blogu dotyczącym tego tematu.
http://www.chalapuk.pl/2010/06.....png-w-ie6/
Pozdrawiam
MariuszT napisał: 22.06.10 o godzinie 14:50
Maciek, trochę się spóźniłeś, temat jest już średnio aktualny, wszyscy się wycofują z suportu IE6.
Maciej napisał: 23.06.10 o godzinie 10:04
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.
MariuszT napisał: 23.06.10 o godzinie 14:58
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.