Native alpha transparency, as supported by Safari, Firefox, Opera et al, was one of the most popular requests to be fixed in Internet Explorer 7 . As documented elsewhere, alpha transparent PNGs can still be displayed in IE6, but to do so requires browser-specific styles to be applied.
The BritPack logo on these pages is an alpha-transparent PNG and I use a little PHP script to deliver browser-specific code to IE6 and IE5.5 and a normal image to other browsers. The normal image uses this mark-up:
<img src="proud.png" alt="BritPack" style="width:140px; height:109px" />
As explained on WebFX, IE6 and IE5.5 requires a non-standard IE-specific filter to be applied as a background image, thus the same alpha-transparent PNG can be shown in IE using this code to apply the PNG as a background to a transparent gif.
<img src="shim.gif" style="width:140px; height:109px;
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(
src='proud.png', sizingMethod='scale')"
alt="BritPack" />
When a transparent PNG is required, I use a simple PHP function to work out which code to send the browser:
function alphapng($src, $alt) {
$ua = $_SERVER['HTTP_USER_AGENT'];
if (strpos($ua, "MSIE 6") OR strpos($ua, "MSIE 5.5")) {
$imgEl .= "<img src=\"shim.gif\"
style=\"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(
src='".$src."', sizingMethod='scale');\" alt=\"".$alt."\"";
$imgEl .= " />";
} else {
$imgEl .= "<img src=\"".$src."\" alt=\"".$alt."\" />";
}
return $imgEl;
}
Call the function like this:
echo alphapng("proud.png", "BritPack")
The function uses old fashioned browser detection to check for IE6 or IE5.5 to decide whether to spit out the IE-specific code or a normal img element. Simple, but handy especially if (like me) you need to display a PNG upon different coloured backgrounds.
PHP/MySQL · CSS techniques · Mark-up techniques
David G wrote:
Very nice.. Thanks for sharing!
Su wrote:
is there a particular reason you didn’t just put the htc reference in a separate stylesheet or header include, called though a conditional comment?
Seems like more work than necessary to do a browser check and then have PHP modify the document each time it’s loaded, not that it’ll exactly put a strain on the server or anything.
I’m mainly curious because the conditional comment method seems to be the currently preferred or more common way to do it, but you never know when something else might force you to work differently.
Rich wrote:
This way non-IE browsers will simply get a straightforward image, thus keeping mark-up simple for most browsers.
David Dorward wrote:
The trouble with “old fashioned” browser detection is that it is horribly unreliable.
I installed Opera last week (nice browser BTW) and its default user agent string (which I just extracted from my server logs) is:
Mozilla/4.0 (compatible; MSIE 6.0; X11; Linux i686; en) Opera 8.02
... which would get your IE code.
If I were to do something like then, then I’d use conditional comments.
Faruk Ateş wrote:
Just a quick question, but why go through extra “effort” to not support IE 5.0? Why add the “.5” when it can just as easily be omitted?
Rich wrote:
Because IE 5.0 doesn’t support the AlphaImageLoader filter.
Rich wrote:
David – aah yes the old Opera problem. I didn’t realise it was still so shy and ashamed of itself. Surely the web has moved on enough for Opera to come out.
As you say, I could use conditional comments, but I’ll stick by my method because I want to address two very specific browsers. I guess I should add an extra clause of logic to check for Opera in the user agent string. How about this:
if (strpos($ua, "MSIE 6") OR strpos($ua, "MSIE 5.5") AND !strpos($ua, "Opera")) {David Dorward wrote:
That would solve the problem with the default user agent string in Opera – but there is so much browser spoofing going on out there (especially with MSIE, since that has always been the favourite of the “Use our browser or get locked out” school of design [ http://linuxtoday.com/infrastructure/2005090801426NWMSPB ]) that I still wouldn’t trust the user agent string.
Danny Hope wrote:
Easier Alpha Transparent PNGs
Have you considered using JavaScript to achieve this?
Obviously this will only work when visitors have JavaScript turned on, but it doesn’t rely on server-side technology and it’s very easy for people to implement.
We used to develop sites in PHP and we used a similar script. Now though, all our sites are based around the Plone content management system and we decided to abandon the server-side approach in favor of JavaScript which fails gracefully.
Rich wrote:
Danny – I had considered JavaScript but I’d rather use server side methods where possible, especially as it proved fairly easy to do.
william doyle wrote:
what would be really cool is if you used javascript for object detection (as opposed to browser sniffing) and then based on the results, served the correct php variables to a slightly simplified server-side script.
Dave S. wrote:
Maybe I’m missing something, but how is including inline style for your image dimensions any better than width and height values? It seems a little like re-inventing the wheel.
If you had offloaded them to an external CSS file, it’d be more logical to me. However, inlining them like that strikes me as a worse solution than using the image attributes which were designed for that purpose.
Rich wrote:
Dave, there was no particular reason to use a
styleattribute to specify the width and height, and yes it’s probably not preferable to normalwidthandheightattributes. Probably just the way my mind was thinking at the time.Dave S. wrote:
Ah, fair enough. Just checking. :)
André Lima wrote:
I made some changes…
if (file_exists($src)){ list($width, $height, $type, $attr) = getimagesize($src); $ua = $_SERVER[‘HTTP_USER_AGENT’]; if (strpos($ua, “MSIE 6”) OR strpos($ua, “MSIE 5.5”)) { $imgEl .= “<span style=”width:” . $width . “px; height:” . $height . “px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’”.$src.”’, sizingMethod=’scale’);” alt=”“.$alt.”“>”; $imgEl .= “</span>”; } else { $imgEl .= “<img src=”“.$src.”” alt=”“.$alt.”” />”; } return $imgEl; }I dont need the gif and size of image now…
<?
function alphapng($src, $alt) {
}
?>
Charles wrote:
Rich, the Opera clause you suggested doesn’t work, or at least it didn’t for me. Here’s a modified version, note the parentheses grouping the OR clauses:
if ((strpos($ua, "MSIE 6") OR strpos($ua, "MSIE 5.5")) AND !strpos($ua, "Opera")) {Or it can be shuffled around to make what I think is a slightly more readable version:
if (!strpos($ua, "Opera") && strpos($ua, "MSIE 6") || strpos($ua, "MSIE 5.5")) {Note I’ve used to more conventional && and || operators in that last example for the sake of demonstration.
I also came to a solution similar to Andre’s for adding width and height, although I use attributes rather than inline style. Here’s the full function:
<pre>
if (!file_exists($src)) { echo “image not found!”; return; } $ua = $_SERVER[‘HTTP_USER_AGENT’]; list($width, $height, $type, $attr) = getimagesize($src); if (!strpos($ua, “Opera”) && strpos($ua, “MSIE 6”) || strpos($ua, “MSIE 5.5”)) { $imgEl .= “<img src=”blank.gif” “; $imgEl .= “style=”filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(“; $imgEl .= “src=’$src’, sizingMethod=’scale’);” alt=”$alt” $attr />”; } else { $imgEl .= “<img src=”$src” alt=”$alt” $attr />”; } return $imgEl;<code>
function alphapng($src, $alt) {
}
</code>
</pre>
Sorry for the messyness; the textile standard use of <pre><code> for code blocks doesn’t work here – is there another way of doing code blocks here Rich?
Olly O wrote:
Hi Rich,
Was fixing this up the other day and thought I’d add my t’pence. I know I’m slightly late in the argument but I thought I’d offer a nice solution that doesn’t use any server-side and weeniest amount of javascript…
<html>
<head>
<title>My Filter Test Page</title>
<script type=”text/javascript”>
function Is() {
sniffer code here…..
</script>
<style type=”text/css”>
.filter {
position:absolute; top:175px; left:560px;
background-image: url(‘filter.png’);
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader( src=’filter.png’, sizingMethod=’scale’);
}
</style>
</head>
<body>
<img src=”Picture6.png” width=”1138” height=”779” alt=”“>
<img class=”filter” style=”background-image: url(‘javascript:if(is.ie55||is.ie6){‘shim.gif’};’);” src=”shim.gif” width=”203” height=”215” alt=”“>
</body>
</html>
Only IE and Opera support the dynamic expression in css so the inline style be enforced. Nice