Mobile version (Display Regular Site)

Skip to: Navigation | Content | Sidebar | Footer

Weblog Entry

Force-Feeding Medicine, XHTML 1.1

August 01, 2003

On constructive criticism, and XHTML 1.1 vs. MIME types.

It’s great having people pick apart your work with unsolicited advice, isn’t it, Andy? And by great I mean it’s as much fun as having your eyes gouged out with lobster forks. And by fun I mean cringe-inducing.

As a veteran of the odd “doing work for the Common Good and being taken to task after doing something wrong” paradigm, all I can offer is a sense of solidarity, and these words of advice: At the end of the day, if you change one thing to make one person happy, you will inevitably have changed the very thing another was perfectly happy with.

And a word to those who are quick to hit the Contact button. On any site. Honey first, to make the vinegar go down easier. Don’t drown your message in unpleasantness, or it will go unheeded. §

While there are purportedly no real-world benefits to using XHTML 1.1 in 2003, it can’t hurt to start experimenting now.

What I want: a way to serve up <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=iso-8859-1" /> selectively to browsers that can handle it. I’d like both ASP and PHP variants. I tried someone else’s PHP on the Zen Garden a month or so back, but I never got it working properly; does anyone have a link or two on this? §

Reader Comments

riffola says:
August 01, 02h

Try this, put it at the start of each page, amongst the first PHP headers sent:

if ( strpos ( $_SERVER[ “HTTP_ACCEPT” ] , “application/xhtml+xml” ) ) {
header ( “Content-type: application/xhtml+xml” );
else {
header (“Content-type: text/html”);

Matt says:
August 01, 03h

Take riffola’s conditional code and modify it to echo out the meta tag, or not. Aren’t you using ASP though?

Dave S. says:
August 01, 03h

ASP on this site, PHP on the Zen Garden. I plan on moving this site to PHP some time in the next 6 months, hopefully sooner than later. A little bit of foresight goes a long way :)

Brian G says:
August 01, 04h

What are the advantages of PHP over ASP (aside from the obvious “Microsoft Sucks” stance that most people have)?

I currently do all my development in ASP just because I’m a windows user, and IIS is easy to develop in. PHP has always intrigued me because hosts with PHP are traditionally a little cheaper than ASP hosts (until I found out about Vortec Inc. that is).

Just curious.

Oh, and I love both Mezzoblue AND CSS Garden!

Dave S. says:
August 01, 04h

You’ll get a lot of different answers to that.

My main reason for moving onto Apache is so that I can do something about stupid things like this. IIS does everything through the console, which I don’t have access to. Apache lets me use wonderful things like .htaccess, therefore allowing me to create custom error pages and the like.

Plus it seems like all the fun toys are written for PHP these days.

August 01, 04h

Letís not forget the inexpensive nature of Linux PHP web-hosts, in comparision to their Microsoft equivalent.

CodeBitch says:
August 01, 05h

Re Arikawa’s comment above:

Looks like it’s a variant of the crash bug already documented :

August 01, 10h

Times New Roman still has to go. I feel criticism is all good even if all negative, but yes if a pattern emerges, it will be noted.

Brian G says:
August 01, 10h

One more question…as a “Windoze user”, is there a way, without buying a MAC, that I can check stuff on MAC IE5? I’ve just been going on faith that if stuff works in PC IE 5.5, 6.0, NS 6, 7, Opera 6, 7, and now Thunderbird, that it will work in MAC IE5. I didn’t even know until recently that there was a difference between the MAC and PC versions of IE 5!

…it’s not that I have anything against MAC’s I’d just hate to buy all my software again in order to switch.

Dave S. says:
August 01, 10h

Times New Roman can stay.

Negative criticism is fine, if it’s phrased properly. Telling someone why you disagree with their choice while respecting their original choice is acceptable. Making blanket statements that something has to change because you say so is the quickest way to a deaf ear.

Sunny says:
August 01, 10h

Criticism should be healthy; otherwise it defeats the purpose. Forcing your individual, pre-conceived beliefs on others is inherently wrong. You may not like Times New Roman, but forcing this “rule” on others is not justified. Andy has challenged himself to make Times Roman look beautiful. Instead of enjoying this beautiful accomplishment, folks are criticizing his choice of a font. Andy, you are right. It can be a tough pill to swallow.

Arikawa says:
August 01, 10h

Dave, thanks for the show of solidarity.

At the end of the day, if you change one thing to make one person happy, you will inevitably have changed the very thing another was perfectly happy with.

Or in my case, at the end of the day, whilst trying to fix one thing you create a new problem that cause IE5.2/Mac users to have their browser crash on loading your site!

Does anyone know why IE5.2/Mac doesn’t like this combination?

h5 { vertical-align:baseline; line-height:30px;}
.leader { vertical-align:middle; line-height:inherit; }
/* using the html below */
<h5><span class=”leader”>The</span>Daily Flight</h5>

Obviously it’s not the most semantic choice, but it seems to work in every browser save IE5.2/Mac. But as long as it crashes IE5.2/Mac, I’ll have to deal with that pixel or two of misalignment. :-)

August 01, 10h

Your site sucks and CSS Zen Garden is the worst thing since Limburger cheese. It’s got to go because I say so!

(I’m kidding, of course.)

Dave S. says:
August 01, 11h

BrowserCam is one way, but I find it a bit slow. There’s nothing like the instant feedback of hitting Refresh.

As far as I know, no VirtualMac or similar product exists. I’d love it if someone were to correct me on this point… but I doubt it. Your best bet is to buy an older Mac on eBay for testing. Something just barely capable of running OS X, since you can’t run Safari on < 10.

August 01, 11h

The PHP code for passing a line based on the UA is not difficult. A simple regular expression match on the $_SERVER[“HTTP_USER_AGENT”] super global variable will determine the agent. You can do any number of loops there after on what line of code to pass.

If you need further help send me an email and I’ll see what I can do.

Dave S. says:
August 01, 11h

Okay, let me confess: I know nothing about PHP, and next to nothing about ASP. So the phrase ‘regular expression match’ goes flying over my head.

Sample code that I can reverse-engineer is what I’m going for here…

Peter J. says:
August 01, 11h

Actually, don’t trigger on HTTP_USER_AGENT; use HTTP_ACCEPT instead. See the “Accommodating Legacy Browsers” section of The Road to XHTML 2.0: MIME Types for PHP code.

Sean says:
August 01, 11h

Use both, for goodness’ sake.

This is how I do it in ASP:

Dim Browser, AcceptHeader, SupportsXHTML, ContentType

Browser = Request.ServerVariables(“HTTP_USER_AGENT”)
AcceptHeader = Request.ServerVariables(“HTTP_ACCEPT”)
SupportsXHTML = False
ContentType = “text/html”

If InStr(AcceptHeader, “application/xhtml+xml”) Or InStr(Browser, “W3C_Validator”) Or InStr(Browser, “WDG_Validator”) Or InStr(Browser, “Opera 6”) Or InStr(Browser, “Opera 7”) Then SupportsXHTML = True

If SupportsXHTML Then ContentType = “application/xhtml+xml”

Response.ContentType = ContentType
Response.Charset = “iso-8859-1”

…start writing to page…

<meta http-equiv=”content-type” content=”<%= ContentType >>; charset=iso-8859-1” />

I also set the doctype to XHTML 1.1 only if the browser supports application/xhtml+xml, otherwise it’s 1.0 Strict.

Ethan says:
August 01, 11h

Dave–hope this helps:

$mime_type = (stristr($_SERVER[‘HTTP_ACCEPT’], ‘application/xhtml+xml’)) ? ‘application/xhtml+xml’ : ‘text/html’;

header(‘Content-type: ’ . $mime_type);

Then, in the <head /> of my pages, I toss in:

<meta http-equiv=”Content-Type” content=”<?= $mime_type; ?>; charset=iso-8859-1” />

Sorry about the wack-ass formatting, but your CSS-fu is no match for my shoddy PHP. ;)

Dave S. says:
August 01, 11h

Excellent, thanks Sean! Easy enough to follow, now that I have it in front of me. I’ll give that a try this weekend. Now for PHP… (but I’m just being greedy, ASP is the more relevant of the two for now)

Dave S. says:
August 01, 11h

And there it is. Right on. Thanks, Ethan.

Ethan says:
August 01, 11h

Anytime, Dave. Good luck with the coding.

Bob says:
August 01, 11h

Pardon my ignorance, but what is the purpose of passing along a different MIME type to a browser w/r/t XHTML when passing the proper DOCTYPE seems to work fine across all browsers (that I’ve tested, anyway)? Not asking to be flip - I really don’t know. :-)

Dave S. says:
August 01, 12h

Serving XHTML 1.1 as text/xhtml is technically invalid, according to the W3.

But the problem is that serving it as application/xhtml+xml causes NN4.x and perhaps other older browsers to download the (theoretically unstyled) content, rather than display it. So selective MIME types it is.

August 01, 12h

XHTML’s Dirty Little Secret
XHTML Media Types | Summary
XHTML media type test

Just some useful links. I think Bob can find his answer in the first given link.

Sean says:
August 01, 12h

From that link:

Note that a meta http-equiv statement will not be recognized by XML processors, and authors SHOULD NOT include such a statement in an XHTML document served as ‘application/xml’ (and ‘application/xhtml+xml’ as well for that matter).

I did not know that. What happens to supporting UAs if you eliminate the http-equiv meta tag and just set the HTTP headers?

August 01, 12h

Nothing, check my site ;)

August 02, 01h

There isn’t any resource on this that I’m aware off (I found out myself, but there must be resources on this), but “DON’T TURN application/xhtml+xml ON AT CSS ZEN GARDEN. Why? Because that will turn Mozilla in XML-mode. In that mode the element body will be nothing more than a div. So if you want to apply a background-image you should do that on the html element for mozilla and the body element for text/html.

I don’t think any of the CSS Zen Garden entries have styled the html element like that for future proof.

So it ain’t possible unless you change everything and tell people who submit what they have to do.

DJ Dizzy Trizzy says:
August 02, 03h

Take a look at this article for instructions on doing this in PHP. It’s a good article, and brings up a lot of good points, like how “browser sniffing is stupid.” The method talked about in the article sends the MIME type and character encoding in the header, but you can probably easily alter this to send this information as a meta tag (just as long as you send it in the headers as well, because this is the proper way). You also may want to edit this script to make sure that the W3C validator is always send text/xhtml+xml.

Dave S. says:
August 02, 09h

Anne - good points. I originally had it validating to XHTML 1.1, but found out that, since I was still serving it as text/html, I was doing it wrong. It’s XHTML 1.0 Strict, and I have no intention of changing that.

I’m pretty sure I’ve read elsewhere about Mozilla in XML-mode not giving special status to the long-standard HTML tags. It sounds familiar, at the very least, which must mean I’ve read it somewhere along the way.

Bob says:
August 02, 11h

Thanks, Anne and Dave, for the info. Learn something new every day… :-)

Shayne says:
August 03, 03h

Here is a sample PHP template that I gave to my class over the summer

Mark says:
August 06, 03h

Most examples I’ve seen here won’t actually work properly because they don’t respect the q= settings that a browser can send in the Accept: header. I made the same mistake in my Dive Into XML article on the subject; some examples happened to partially respect it, but I don’t think any supported it fully.

Oh, and yeah, browser sniffing is stupid. I used to sniff for “Gecko” and serve application/xhtml+xml, until Safari came out and included the phrase “(like Gecko)” but didn’t support xhtml. 2 million Mac fanatics, a Certified Apple Trainer, and a beta browser that downloads my home page instead of rendering it. Browser sniffing is stupid. Don’t go there.

August 06, 03h

“Browser sniffing is stupid. Don’t go there.”I disagree. The only good reason for going to the trouble of sending out application/xhtml+xml is if you are actually going to embed other XML namespaces in your document (the “+xml” part). If you do that, you have to worry about how a given User Agent will deal with a namespace that it doesn’t undestand.

The Spec says that the User Agent should just ignore elements from namespaces it does not understand and render the text. Unfortunately, there’s not a browser in existence that behaves according to Spec. Just because a browser’s Accept headers say it will handle application/xhtml+xml doesn’t mean it won’t puke when it sees your page. You need to browser-sniff.

This is not just theoretical. Camino coughs up blood when I serve my blog to it as application/xhtml+xml. It needs to be fed text/html. It doesn’t matter what the Accept headers say.


August 06, 12h

Anne van Kesteren wrote:
Why? Because that will turn Mozilla in XML-mode. In that mode the element body will be nothing more than a div. So if you want to apply a background-image you should do that on the html element for mozilla and the body element for text/html.
Look at my weblog. I’ve applied a background-image to the body element, and I am most certainly serving it as (valid!) XHTML 1.1 with a MIME type of application/xhtml+xml (to gecko-based browsers).

riffola says:
August 07, 05h

Most examples I’ve seen here won’t actually work properly because they don’t respect the q= settings that a browser can send in the Accept: header.

I am not sure how to figure out the q setting for application/xhtml+xml and compare it with the q setting for text/html, what the modified code below does is check if application/xhtml+xml appears before text/html, if so the header sent is application/xhtml+xml. It’s not perfect, but it’s a bit better.

if ( strpos ( $_SERVER[ “HTTP_ACCEPT” ] , “application/xhtml+xml” ) && (strpos ( $_SERVER[ “HTTP_ACCEPT” ] , “application/xhtml+xml” ) < strpos ( $_SERVER[ “HTTP_ACCEPT” ] , “text/html” )) ) {
header ( “Content-type: application/xhtml+xml” );
else {
header (“Content-type: text/html”);

P.S: Sorry about the previous comment mess up.

redux says:
August 07, 07h

jacques, regarding xhtml1.1 / xml and background images: i think the problem arises when your page’s content does not fill the browser window. the background simply stops at the end of the content, leaving the rest of the background without bg image…if that made any sense at all…

August 07, 11h

Doesn’t seem to be a problem for me. Try this search.

If your browser window is fairly large, the “content” will fill only the upper part of the window, whereas the background-image (applied to the <body> element) fills the whole window. N.B., unlike most people, my search page is served as application/xhtml+xml.

Ethan says:
August 08, 04h

Learn something new from Mark every day. Just saw his comment on the q= parameter, of which I’d never previously been aware.

I’m now serving up application/xhtml+xml according to the following condition (thanks to Mark’s article for the regular expression):

$mime_type = (stristr($_SERVER[‘HTTP_ACCEPT’], “application/xhtml+xml”) AND !eregi(“application/xhtml\+xml\s*;\s*q=0”, $_SERVER[‘HTTP_ACCEPT’])) ? ‘application/xhtml+xml’ : ‘text/html’;

Ethan says:
August 08, 04h

Hang a tic; that probably won’t work, as it looks like the q= parameter can have a value of 0.x. I’m gonna leave, and post again when I know what I’m talking about. Bah.

August 09, 02h

Jacques Distler,

I’m sorry, I wasn’t saying what I intended to say. The body element doesn’t work on absolutely positioned layouts.

And I think those layouts exist in the Garden, don’t they? I went into trouble with this styling my blog site, which is absolutely positioned.

August 10, 10h

Anne wrote”I’m sorry, I wasn’t saying what I intended to say. The body element doesn’t work on absolutely positioned layouts.”Ah! OK. That’s better, then. But is this really something essential about XHTML as XML, or is this a CSS rendering bug in Gecko? Does Opera 7 (or whatever) have the same problem?

I get suspicious that this is just some stupid little CSS bug in Gecko once you put in all the caveats.

August 10, 11h

I think it has to do with the body element becoming a div. Since you can position this like any other element (only in Gecko supported though).

Sean says:
August 27, 05h

‘If InStr(AcceptHeader, "application/xhtml+xml") Or InStr(Browser, "W3C_Validator") Or InStr(Browser, "WDG_Validator") Or InStr(Browser, "Opera 6") Or InStr(Browser, "Opera 7") Then SupportsXHTML = True’

This is broken in two ways.

1. As Mark says, it doesn’t respect the q= settings. Is this a problem now? Are there any UAs that give text/html a higher q= setting than application/xhtml+xml? Searching for position (as riffola does) doesn’t work, because it’s possible to list q= settings in ascending or descending order; or, indeed, any other order.

I’m going to leave this for now, because there’s no incentive not to.

2. It should be searching for ‘Opera/6’ and ‘Opera/7’. Sorry.