Данный вопрос появляется регулярно. Решений данной проблемы предостаточно, все они отличаются друг от друга, но все они выполняют свою функцию - исправляют отображение картинок формата png в браузере Internet Explorer 6.
Причиной появления серого фона вместо прозрачного является отсутствие обработчика альфа-канала в самом браузере, что приводит к невозможности кроссбраузерного использования фомата png. Лично я крайне редко прибегаю к использованию png картинок по двум причинам:
1) "вес" картинок данного формата как правило достаточно сильно превосходит jpeg (если используются картинки с разрешением выше 20х20 пикселей без прозрачности), что в итоге будет влиять на скорость загрузки сайта. Лучше попытаться "склеить" две jpeg картинки, чем сразу прибегать к использованию прозрачности.
2) необходимость использования дополнительных скриптов. Если на сайте используется 1-3 png картинки, то скорость обработки и конвертации их в обработчик альфа-канала не займет много времени визуального отображения, но если же картинок более 10, то это сильно "подвесит" браузер. Заметить это можно в поочередном исчезании серого фона у картинок, а не моментальном.
С увеличением потребности использования данного формата microsoft ввел CSS св-во filter. Выглядит данный CSS следующим образом
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../image.png', sizingMethod='scale');
, где sizingMethod определяет поведение браузера по отношению к картинке, таким образом значения
- scale будет масштабировать картинку по ширине и высоте элемента, в котором она располагается.
- crop - обрезает картинку по области элемента
- image - сохраняет первоначальную пропорцию
Так же допустимо путое значение sizingMethod
Многие другие решения базируются именно на данном свойстве
filter, сводя работу верстальщика не к созданию отдельного файла стилей и расписыванию чего-то вроде
div#header { background:none; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../image.png', sizingMethod='image'); }
,а к автоматическому нахождению png картинок через DOM дерево браузера и их подмену на данное свойство. Плюсом подобной замены можно выделить то, что будут обрабатываться и те картинки, которые не предусмотрены изначально в макете, допустим пользовательские аватары. Но подобные действия по отношению к DOM, как я писал выше, приводят к "торможению" браузера. В отдельных случаях результатом может оказаться и "зависание".
Пожалуй, самое распростаненое решение - pngbehavior.htc<public:component>
<public:attach event="onpropertychange" onevent="propertyChanged()" />
<script>
var supported = /MSIE (5\.5)|[6789]/.test(navigator.userAgent) && navigator.platform == "Win32";
var realSrc;
var blankSrc = "blank.gif";
if (supported) fixImage();
function propertyChanged() {
if (!supported) return;
var pName = event.propertyName;
if (pName != "src") return;
// if not set to blank
if ( ! new RegExp(blankSrc).test(src))
fixImage();
};
function fixImage() {
// get src
var src = element.src;
// check for real change
if (src == realSrc) {
element.src = blankSrc;
return;
}
if ( ! new RegExp(blankSrc).test(src)) {
// backup old src
realSrc = src;
}
// test for png
if ( /\.png$/.test( realSrc.toLowerCase() ) ) {
// set blank image
element.src = blankSrc;
// set filter
element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
src + "',sizingMethod='scale')";
}
else {
// remove filter
element.runtimeStyle.filter = "";
}
}
</script>
</public:component>
в CSS шаблона необходимо добавить (
следите за путями к файлу)
img, div { behavior: url("../js/pngbehavior.htc"); }
Следующее решение тоже является одним из основных - iepngfix.htc<public:component>
<public:attach event="onpropertychange" onevent="iePNGFix(0)" />
<script type="text/javascript">
// IE5.5+ PNG Alpha Fix v1.0
// (c) 2004-2008 Angus Turnbull http://www.twinhelix.com
// This is licensed under the GNU LGPL, version 2.1 or later.
// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
// This must be a path to a blank image, relative to the HTML document(s).
// In production use I suggest '/images/blank.gif' or similar. That's all!
if (typeof blankImg == 'undefined') var blankImg = 'blank.gif';
function filt(s, b)
{
var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
var sM = (currentStyle.backgroundRepeat == 'no-repeat')? 'crop' : 'scale';
s = (s || '').replace(/\(/g, '%28').replace(/\)/g, '%29');
if (s && !(/IMG|INPUT/.test(nodeName) && !b) &&
currentStyle.width == 'auto' && currentStyle.height == 'auto')
{
style.width = offsetWidth + 'px';
style.height = clientHeight + 'px';
if (currentStyle.display == 'inline') style.display = 'inline-block';
}
if (filters[f])
{
filters[f].enabled = s ? true : false;
if (s) with (filters[f]) { src = s }
}
else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="' + sM + '")';
}
function iePNGFix(init)
{
if (!/MSIE (5\.5|6)/.test(navigator.userAgent) || typeof filters == 'unknown') return;
var evt = init ? { propertyName: 'src,background' } : event;
var isSrc = /src/.test(evt.propertyName);
var isBg = /background/.test(evt.propertyName);
var isClass = !init &&
((this.className != this._png_class) && (this.className || this._png_class));
if (!(isSrc || isBg || isClass)) return;
this._png_class = this.className;
var blank = blankImg.match(/([^\/]+)$/)[1];
// Required for Whatever:hover support - erase any set BG if className changes.
if (isClass && ((style.backgroundImage.indexOf('url(') == -1) ||
(style.backgroundImage.indexOf(blank) > -1)))
{
setTimeout(function() { this.style.backgroundImage = '' }, 0);
return;
}
if (isSrc && this.src && /IMG|INPUT/.test(nodeName))
{
if ((/\.png/i).test(src))
{
filt(src, 1);
src = blankImg;
}
else if (src.indexOf(blank) == -1) filt();
}
var bgSrc = currentStyle.backgroundImage || style.backgroundImage;
if ((bgSrc + this.src).indexOf(blank) == -1)
{
var bgPNG = bgSrc.match(/^url[("']+(.*\.png[^\)"']*)[\)"']+[^\)]*$/i);
if (bgPNG)
{
style.backgroundImage = 'url("' + blankImg + '")';
filt(bgPNG[1], 0);
// Unclickable elements inside PNG backgrounds.
var tags = ['a', 'input', 'select', 'textarea', 'iframe', 'object'],
t = tags.length, tFix = [];
while (t--)
{
var elms = all.tags(tags[t]), e = elms.length;
while (e--) tFix.push(elms[e]);
}
var t = tFix.length;
if (t && (/relative|absolute/i).test(currentStyle.position))
alert('IEPNGFix: Children of positioned element are unclickable:\n\n<' +
nodeName + (id && ' id=' + id) + '>');
while (t--)
if (!(/relative|absolute/i).test(tFix[t].currentStyle.position))
tFix[t].style.position = 'relative';
}
else filt();
}
}
iePNGFix(1);
</script>
</public:component>
В целом это тот же
pngbehavior.htc, только с улучшеными инициализацией и методом обработки изображения и применением к нему дополнительных стилей для улучшения кроссбраузерности
в CSS шаблона его необходимо подключить так (
следите за путями к файлу)
img, div { behavior: url("../js/iepngfix.htc"); }
Данный скрипт так же работает и для input. Если же требуется задать обработку всех элементов, то досточно сделать так
* { behavior: url("iepngfix.htc"); }
Менее известный способ, использующий css expression* HTML img, * HTML .png {
azimuth: expression( this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "', sizingMethod='image')", this.src = "transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "', sizingMethod='crop')", this.runtimeStyle.backgroundImage = "none")),this.pngSet=true); }
Честно говоря не рекомендую его использовать, а просто привел для "справки"
Альтернатива iepngfix.htc - supersleight.jsvar supersleight = function() {
var root = false;
var applyPositioning = true;
// Path to a transparent GIF image
var shim = 'blank.gif';
// RegExp to match above GIF image name
var shim_pattern = /blank\.gif$/i;
var fnLoadPngs = function() {
if (root) {
root = document.getElementById(root);
}else{
root = document;
}
for (var i = root.all.length - 1, obj = null; (obj = root.all[i]); i--) {
// background pngs
if (obj.currentStyle.backgroundImage.match(/\.png/i)!== null) {
bg_fnFixPng(obj);
}
// image elements
if (obj.tagName=='IMG' && obj.src.match(/\.png$/i)!== null){
el_fnFixPng(obj);
}
// apply position to 'active' elements
if (applyPositioning && (obj.tagName=='A' || obj.tagName=='INPUT') && obj.style.position === ''){
obj.style.position = 'relative';
}
}
};
var bg_fnFixPng = function(obj) {
var mode = 'scale';
var bg = obj.currentStyle.backgroundImage;
var src = bg.substring(5,bg.length-2);
if (obj.currentStyle.backgroundRepeat == 'no-repeat') {
mode = 'crop';
}
obj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='" + mode + "')";
obj.style.backgroundImage = 'url('+shim+')';
};
var el_fnFixPng = function(img) {
var src = img.src;
img.style.width = img.width + "px";
img.style.height = img.height + "px";
img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='scale')";
img.src = shim;
};
var addLoadEvent = function(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
};
}
};
return {
init: function() {
addLoadEvent(fnLoadPngs);
},
limitTo: function(el) {
root = el;
},
run: function() {
fnLoadPngs();
}
};
}();
// limit to part of the page ... pass an ID to limitTo:
// supersleight.limitTo('header');
supersleight.init();
Подключается к шаблону так
<!--[if IE 6]>
<script src="src="<?php echo $mosConfig_live_site; ?>/templates/YOUREMPLATENAME/js/supersleight.js">
<![endif]-->
Обратите внимание, что данные решения
требуют наличия прозрачного однопиксельного gif (blank.gif)!
Далее рассмотрим более "продвинутые" способы-
JqueryPngFix, который
описан в этом топике-
ie7-js, который вообщем правит не только отображение картинок .png, а еще такие вещи как :hover, :fixed и т.д
Правит только картинки с именами вида -trans.png, хотя найдя в конце кода IE7_PNG_SUFFIX:"-trans.png" и стерев -trans.png скрипт будет обрабатывать все картинки
Недавно появившийся
DD_belatedPNG (скачать), отличием которого является отличная поддержка background-position и background-repeat, не требует прозрачного однопиксельного gif, появилась возможность без использования :hover-хака использовать смену картинок при :hover на элемент и самое главное то, что данный способ не использует AlphaImageLoader
Подключается к шаблону следующим образом (
следите за путями к файлу)
<!--[if IE 6]>
<script src="<?php echo $mosConfig_live_site; ?>/templates/YOUREMPLATENAME/js/DD_belatedPNG.js"></script>
<script>
DD_belatedPNG.fix('.png_bg');
/* DD_belatedPNG.fix('*'); * - приведет к фиксу всех тегов */
/* .png_bg должен быть заменен на любой другой селектор, который Вам нужно обработать. Указание в качесте селектора * приведет к фиксу всех тегов, но использовать не рекомендуется, так как значительно увеличивается время рендеринга страницы. Тег body не может быть использован в качестве обрабатываемого селектора */
</script>
<![endif]-->
Данная статья собрана из всего, что обсуждалось или проскакивало на форуме, она является результирующим итогом на 2008 год и все вопросы в разделе "шаблоны и дизайн", связанные с проблемой отображения png картинок будут удаляться.
[вложение удалено Администратором]