Transparent PNG Fix for IE6???

Associate
Joined
31 Jan 2010
Posts
283
Location
UK
Hi im hoping someone can help,

I have been using this method to fix the transparent PNG problem in IE6.

It works perfect but you have to specify the height and width of the image for it to work.

I have a floating div that has a background image with faded edges (which needs to be transparent).

Is there a PNG fix which does not need the height and width values?

Thanks in Advance :)
 
This is a minefield.. most fixes have their own little quirks.

I have had most success with Supersleight. I don't believe it requires height and width attributes but I wouldn't bet my life on it. It tends to be the first fix I use and, more often than not, everything works.
 
Tag all images with an 'img' class. Stick this in your IE6 CSS file:

Code:
img { 
behavior: url(/css/iepngfix.htc);
}

iepngfix.htc:

Code:
<public:component>
<script type="text/javascript">

// IE5.5+ PNG Alpha Fix v2.0 Alpha
// (c) 2004-2009 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/

var IEPNGFix = window.IEPNGFix || {};
IEPNGFix.data = IEPNGFix.data || {};


// CONFIG: blankImg is the path to blank.gif, *relative to the HTML document*.
// Try either:
// * An absolute path like:  '/images/blank.gif'
// * A path relative to this HTC file like:  thisFolder + 'blank.gif'
var thisFolder = document.URL.replace(/(\\|\/)[^\\\/]*$/, '/');
IEPNGFix.blankImg = '../images/blank.gif';


IEPNGFix.fix = function(elm, src, t) {
	// Applies an image 'src' to an element 'elm' using the DirectX filter.
	// If 'src' is null, filter is disabled.
	// Disables the 'hook' to prevent infinite recursion on setting BG/src.
	// 't' = type, where background tile = 0, background = 1, IMG SRC = 2.

	var h = this.hook.enabled;
	this.hook.enabled = 0;

	var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
		src = (src || '').replace(/\(/g, '%28').replace(/\)/g, '%29');

	if (
		src && !(/IMG|INPUT/.test(elm.nodeName) && (t != 2)) &&
		elm.currentStyle.width == 'auto' && elm.currentStyle.height == 'auto'
	) {
		if (elm.offsetWidth) {
			elm.style.width = elm.offsetWidth + 'px';
		}
		if (elm.clientHeight) {
			elm.style.height = elm.clientHeight + 'px';
		}
		if (elm.currentStyle.display == 'inline') {
			elm.style.display = 'inline-block';
		}
	}

	if (t == 1) {
		elm.style.backgroundImage = 'url("' + this.blankImg + '")';
	}
	if (t == 2) {
		elm.src = this.blankImg;
	}

	if (elm.filters[f]) {
		elm.filters[f].enabled = src ? true : false;
		if (src) {
			elm.filters[f].src = src;
		}
	} else if (src) {
		elm.style.filter = 'progid:' + f + '(src="' + src +
			'",sizingMethod="' + (t == 2 ? 'scale' : 'crop') + '")';
	}

	this.hook.enabled = h;
};


IEPNGFix.process = function(elm, init) {
	// Checks the onpropertychange event (on first 'init' run, a fake event)
	// and calls the filter-applying-functions.

	if (
		!/MSIE (5\.5|6)/.test(navigator.userAgent) ||
		typeof elm.filters == 'unknown'
	) {
		return;
	}
	if (!this.data[elm.uniqueID]) {
		this.data[elm.uniqueID] = {
			className: ''
		};
	}
	var data = this.data[elm.uniqueID],
		evt = init ? { propertyName: 'src,backgroundImage' } : event,
		isSrc = /src/.test(evt.propertyName),
		isBg = /backgroundImage/.test(evt.propertyName),
		isPos = /width|height|background(Pos|Rep)/.test(evt.propertyName),
		isClass = !init && ((elm.className != data.className) &&
			(elm.className || data.className));
	if (!(isSrc || isBg || isPos || isClass)) {
		return;
	}
	data.className = elm.className;
	var blank = this.blankImg.match(/([^\/]+)$/)[1],
		eS = elm.style,
		eCS = elm.currentStyle;

	// Required for Whatever:hover - erase set BG if className changes.
	if (
		isClass && (eS.backgroundImage.indexOf('url(') == -1 ||
		eS.backgroundImage.indexOf(blank) > -1)
	) {
		return setTimeout(function() {
			eS.backgroundImage = '';
		}, 0);
	}

	// Foregrounds.
	if (isSrc && elm.src && { IMG: 1, INPUT: 1 }[elm.nodeName]) {
		if ((/\.png/i).test(elm.src)) {
			if (!elm.oSrc) {
				// MM rollover compat
				elm.oSrc = elm.src;
			}
			this.fix(elm, elm.src, 2);
		} else if (elm.src.indexOf(blank) == -1) {
			this.fix(elm, '');
		}
	}

	// Backgrounds.
	var bgSrc = eCS.backgroundImage || eS.backgroundImage;
	if ((bgSrc + elm.src).indexOf(blank) == -1) {
		var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);
		if (bgPNG) {
			if (this.tileBG && !{ IMG: 1, INPUT: 1 }[elm.nodeName]) {
				this.tileBG(elm, bgPNG[1]);
				this.fix(elm, '', 1);
			} else {
				if (data.tiles && data.tiles.src) {
					this.tileBG(elm, '');
				}
				this.fix(elm, bgPNG[1], 1);
				this.childFix(elm);
			}
		} else {
			if (data.tiles && data.tiles.src) {
				this.tileBG(elm, '');
			}
			this.fix(elm, '');
		}
	} else if ((isPos || isClass) && data.tiles && data.tiles.src) {
		this.tileBG(elm, data.tiles.src);
	}

	if (init) {
		this.hook.enabled = 1;
		elm.attachEvent('onpropertychange', this.hook);
	}
};


IEPNGFix.childFix = function(elm) {
	// "hasLayout" fix for unclickable children inside PNG backgrounds.
	var tags = [
			'a',
			'input',
			'select',
			'textarea',
			'button',
			'iframe',
			'object'
		],
		t = tags.length,
		tFix = [];
	while (t--) {
		var pFix = elm.all.tags(tags[t]),
			e = pFix.length;
		while (e--) {
			tFix.push(pFix[e]);
		}
	}
	t = tFix.length;
	if (t && (/relative|absolute/i).test(elm.currentStyle.position)) {
		alert('IEPNGFix: Unclickable children of element:' +
			'\n\n<' + elm.nodeName + (elm.id && ' id=' + elm.id) + '>');
	}
	while (t--) {
		if (!(/relative|absolute/i).test(tFix[t].currentStyle.position)) {
			tFix[t].style.position = 'relative';
		}
	}
};


IEPNGFix.hook = function() {
	if (IEPNGFix.hook.enabled) {
		IEPNGFix.process(element, 0);
	}
};


IEPNGFix.process(element, 1);

</script>
</public:component>

And stick a 1x1 pixel blank GIF in your images folder and link to it in the above script.

---

Alternatively if you only have a few PNGs, you can use this:

<img src="transparent.png" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(transparent.png);">

Quote this to get the code and remove the ':D'...
 
Last edited:
This is a minefield.. most fixes have their own little quirks.

I have had most success with Supersleight. I don't believe it requires height and width attributes but I wouldn't bet my life on it. It tends to be the first fix I use and, more often than not, everything works.

Tag all images with an 'img' class. Stick this in your IE6 CSS file:

Code:
img { 
behavior: url(/css/iepngfix.htc);
}

iepngfix.htc:

Code:
<public:component>
<script type="text/javascript">

// IE5.5+ PNG Alpha Fix v2.0 Alpha
// (c) 2004-2009 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/

var IEPNGFix = window.IEPNGFix || {};
IEPNGFix.data = IEPNGFix.data || {};


// CONFIG: blankImg is the path to blank.gif, *relative to the HTML document*.
// Try either:
// * An absolute path like:  '/images/blank.gif'
// * A path relative to this HTC file like:  thisFolder + 'blank.gif'
var thisFolder = document.URL.replace(/(\\|\/)[^\\\/]*$/, '/');
IEPNGFix.blankImg = '../images/blank.gif';


IEPNGFix.fix = function(elm, src, t) {
	// Applies an image 'src' to an element 'elm' using the DirectX filter.
	// If 'src' is null, filter is disabled.
	// Disables the 'hook' to prevent infinite recursion on setting BG/src.
	// 't' = type, where background tile = 0, background = 1, IMG SRC = 2.

	var h = this.hook.enabled;
	this.hook.enabled = 0;

	var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
		src = (src || '').replace(/\(/g, '%28').replace(/\)/g, '%29');

	if (
		src && !(/IMG|INPUT/.test(elm.nodeName) && (t != 2)) &&
		elm.currentStyle.width == 'auto' && elm.currentStyle.height == 'auto'
	) {
		if (elm.offsetWidth) {
			elm.style.width = elm.offsetWidth + 'px';
		}
		if (elm.clientHeight) {
			elm.style.height = elm.clientHeight + 'px';
		}
		if (elm.currentStyle.display == 'inline') {
			elm.style.display = 'inline-block';
		}
	}

	if (t == 1) {
		elm.style.backgroundImage = 'url("' + this.blankImg + '")';
	}
	if (t == 2) {
		elm.src = this.blankImg;
	}

	if (elm.filters[f]) {
		elm.filters[f].enabled = src ? true : false;
		if (src) {
			elm.filters[f].src = src;
		}
	} else if (src) {
		elm.style.filter = 'progid:' + f + '(src="' + src +
			'",sizingMethod="' + (t == 2 ? 'scale' : 'crop') + '")';
	}

	this.hook.enabled = h;
};


IEPNGFix.process = function(elm, init) {
	// Checks the onpropertychange event (on first 'init' run, a fake event)
	// and calls the filter-applying-functions.

	if (
		!/MSIE (5\.5|6)/.test(navigator.userAgent) ||
		typeof elm.filters == 'unknown'
	) {
		return;
	}
	if (!this.data[elm.uniqueID]) {
		this.data[elm.uniqueID] = {
			className: ''
		};
	}
	var data = this.data[elm.uniqueID],
		evt = init ? { propertyName: 'src,backgroundImage' } : event,
		isSrc = /src/.test(evt.propertyName),
		isBg = /backgroundImage/.test(evt.propertyName),
		isPos = /width|height|background(Pos|Rep)/.test(evt.propertyName),
		isClass = !init && ((elm.className != data.className) &&
			(elm.className || data.className));
	if (!(isSrc || isBg || isPos || isClass)) {
		return;
	}
	data.className = elm.className;
	var blank = this.blankImg.match(/([^\/]+)$/)[1],
		eS = elm.style,
		eCS = elm.currentStyle;

	// Required for Whatever:hover - erase set BG if className changes.
	if (
		isClass && (eS.backgroundImage.indexOf('url(') == -1 ||
		eS.backgroundImage.indexOf(blank) > -1)
	) {
		return setTimeout(function() {
			eS.backgroundImage = '';
		}, 0);
	}

	// Foregrounds.
	if (isSrc && elm.src && { IMG: 1, INPUT: 1 }[elm.nodeName]) {
		if ((/\.png/i).test(elm.src)) {
			if (!elm.oSrc) {
				// MM rollover compat
				elm.oSrc = elm.src;
			}
			this.fix(elm, elm.src, 2);
		} else if (elm.src.indexOf(blank) == -1) {
			this.fix(elm, '');
		}
	}

	// Backgrounds.
	var bgSrc = eCS.backgroundImage || eS.backgroundImage;
	if ((bgSrc + elm.src).indexOf(blank) == -1) {
		var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);
		if (bgPNG) {
			if (this.tileBG && !{ IMG: 1, INPUT: 1 }[elm.nodeName]) {
				this.tileBG(elm, bgPNG[1]);
				this.fix(elm, '', 1);
			} else {
				if (data.tiles && data.tiles.src) {
					this.tileBG(elm, '');
				}
				this.fix(elm, bgPNG[1], 1);
				this.childFix(elm);
			}
		} else {
			if (data.tiles && data.tiles.src) {
				this.tileBG(elm, '');
			}
			this.fix(elm, '');
		}
	} else if ((isPos || isClass) && data.tiles && data.tiles.src) {
		this.tileBG(elm, data.tiles.src);
	}

	if (init) {
		this.hook.enabled = 1;
		elm.attachEvent('onpropertychange', this.hook);
	}
};


IEPNGFix.childFix = function(elm) {
	// "hasLayout" fix for unclickable children inside PNG backgrounds.
	var tags = [
			'a',
			'input',
			'select',
			'textarea',
			'button',
			'iframe',
			'object'
		],
		t = tags.length,
		tFix = [];
	while (t--) {
		var pFix = elm.all.tags(tags[t]),
			e = pFix.length;
		while (e--) {
			tFix.push(pFix[e]);
		}
	}
	t = tFix.length;
	if (t && (/relative|absolute/i).test(elm.currentStyle.position)) {
		alert('IEPNGFix: Unclickable children of element:' +
			'\n\n<' + elm.nodeName + (elm.id && ' id=' + elm.id) + '>');
	}
	while (t--) {
		if (!(/relative|absolute/i).test(tFix[t].currentStyle.position)) {
			tFix[t].style.position = 'relative';
		}
	}
};


IEPNGFix.hook = function() {
	if (IEPNGFix.hook.enabled) {
		IEPNGFix.process(element, 0);
	}
};


IEPNGFix.process(element, 1);

</script>
</public:component>

And stick a 1x1 pixel blank GIF in your images folder and link to it in the above script.

---

Alternatively if you only have a few PNGs, you can use this:

<img src="transparent.png" style="filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(transparent.png);">

Quote this to get the code and remove the ':D'...

This seems to be the problem with them:

Background images cannot be positioned or repeated
 
Personally for something like that I would just plain replace the footer background with a non-transparent one for IE6. Can't test the layout as don't have IE6 on my laptop.
 
Back
Top Bottom