views:

230

answers:

9

I need to display different HTML if the browser is IE6/IE7. I know conditional comments work fine if we're just talking about styling information but in this particular case it's the actual markup.

I will have an unordered list of images which will be png-24. They will have rounded corners (hence the need for the transparency provided by png-24) and will have rounded border styling in the CSS(3). With IE6 not recognising png-24's I want to have an alternate list of images which are jpg's which already have the borders included in the image. This will keep IE6/IE7 happy whilst the standards compliant browsers will get the proper version.

(I'm doing it this way because the site will potentially grow to many images and it needs to be easily themed. If I produce the borders in code one simple change to border-color and it changes site wide. I realise IE will still have to be manual but I can create a separate charge for this if they really want it supported by IE6.)

So my question is what is the best way to do this using PHP and are there any downsides?

+1  A: 

You can get the Browser UA by looking at $_SERVER['HTTP_USER_AGENT']

Here is a list of UA strings for IE.

beggs
+5  A: 

You can detect it in PHP and send different HTML:

$using_ie6 = ((strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6.') !== FALSE) || (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6,0') !== FALSE));
if ($using_ie6) {
    ...
}
else {
    ...
}

The downsides to this method are that apparently Opera sometimes sends MSIE 6 in it's user agent headers, and this may also match IE mobile.

Sending different content to different browsers is generally something it's good to avoid, as far as possible - you end up with lots of duplicate code, with all the inherent evils that brings.

Dominic Rodger
I would remove the '.' after the 6 as the first version is IE6 used a ','
beggs
I've edited in a particular check for `6,0` - maybe I'm obsessive, but hey, one day there might be IE 60... ;-)
Dominic Rodger
+2  A: 
$is_ie6 = (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false));
MiffTheFox
A: 

You can make it client-side if you want, like this: Make two divs, one for IE and the other for the rest of the browser. The DIV for IE will have display=none; Then you will add a conditional CSS, only for IE, and you will hide the div for the other browsers and set the IE display=block

Palantir
A: 

Just a different suggestion, which should be possible too in PHP. In ASP.NET, you can write special handlers which would be able to send back all kinds of binary data back to the client. Instead of rewriting your pages, you could link the image tags to a special image handler. This handler would receive the request, check the user agent string from the client to detect the browser version and in case of IE6, it would convert the PNG to a JPG file and stream that back. In other cases, it would just return the PNG file.

Your URL would then look a bit like http://example.org/yourpage.php?yourimage

Basically, you would be fixing the problem much closer to the source of the problem. And detecting IE6 has been explained already.

Workshop Alex
+3  A: 

Use conditional comments - they work perfectly well with markup, not just with styling information:

<!--[if lte IE 6]>
<p>Old school</p>
<![endif]-->

See MSDN: About Conditional Comments

RichieHindle
+1. This is *the* best way to serve custom content to IE 6 (unless you absolutely do not want the IE6-specific content visible to users of other browsers for some reason). Sniffing user agents on the server is going to result in you sending the IE6-specific content to bots and crawlers that pretend to be IE 6 and most importantly, will *not* send the IE6-specific content to users that have changed their user agent or blocked it entirely (which some companies and security software do).
Grant Wagner
+1  A: 

are there any downsides?

Oh yes, very much. You have to output a ‘Vary’ header to tell proxies/caches that the page will be different for each UA string, which kills the effectiveness of cacheing. (If you don't, browsers will see pages with the wrong markup.) And of course many browsers just lie about what they are. I would avoid UA sniffing wherever possible — and it almost always is possible.

Conditional comments are much better for the specific case of presenting IE with simpler markup. You can use them anywhere in HTML, but note that the MS-proposed syntax for downlevel-revealed markup is invalid. For targetting something at IE6 only, instead try:

<!--[if lt IE 7]>
    (markup for IE6)
<![endif]-->

<!--[if gte IE 7]><!-->
    (markup for everyone else)
<!--<![endif]-->

With IE6 not recognising png-24's I want to have an alternate list of images which are jpg's which already have the borders included in the image.

Have you tried one of the many PNG fixes to make the transparency work in IE6? This would be much easier (and look better) than having separate images and markup.

bobince
A: 

I know this isn't what you asked, but I'll hit it anyway.

Use 8-bit PNG-images for IE 6. It won't look the same as 24-bit ones, but that'll save you from creating extra markup, just a extra stylesheet with one line replacing the background-image.

You win quite a bit of time by not creating custom markup for a faulty browser, and the end result is quite close to what you want - especially if you can use opaque JPEGs in transparent PNGs stead currently.

One really shouldn't be too nice to IE6, although I do (unfortunately) know that it's not always possible to make your own choice about it.

nikc
A: 

Is there any possibility of using something like javascript, a library, to effect the following:

<!--[if ie]>
 // remove the #for_non_id_browsers and replace, using an ajax call or whatever, with an IE-suitable version
<![endif]-->

<div id="for_non_ie_browsers">
Page content
</div>
David Thomas