XHTML, PHP, Validation and Browsers

Recently for a school project I was working on, I had to develop an XTHML 1.1 Strict validated page and a validated CSS to style the page. This was not a problem in and of itself, however there were several problems that I encountered while trying to serve the pages to different browsers and to the W3C’s validator.

What this post will attempt to do is cover several items that I found necessary to accomplish a page that displayed properly in Internet Explorer 7, Firefox 2, Netscape 9, SeaMonkey, Opera and Safari for Windows. I have not fully tested the resulting pages on the Linux or Mac platforms yet, so I will attempt to do that when time permits. I did however use BrowserCamp to get a screen shot of what it looks like in Safari 2.0.4 and there were some CSS issues (I assume anyway).


The first thing that happened when I attempted to view the page in Firefox was that the body background color did not fill the entire page as it does on IE. The problem, it appears, is caused from the implementation of the Body tag in an XHTML 1.1 doctype. The body tag has been revamped so that it truly is only the content area of the size specified. Thus, I had specified a body of 770 pixels wide, therefore in Firefox, which implements the XHTML standard, showed a body background of 770 pixels wide rather than filling the screen. In IE, the entire body backgorund filled the whitespace. Why? To answer that I have to take you on a journey into mime-types, doctypes and standards compliance browsers…….Let’s go.

The XHTML 1.1 specification denotes that all documents of this type SHOULD be sent with the application/xhtml+xml mime-type. Huh? What that means is the server, whether through the configuration of it (in my case apache), through .htaccess or programatically should send the document as the mime-type of application/xhtml+xml. The problem is, my server was configured to send all documents as text/html if the extension and/or mime-type were not known. No big deal, I added the supporting mime-type in my conf files and specified it for documents with an .xhtml extension only since I host several sites on here that all use .htm, .html or .php extensions. I didn’t want to specify a mime-type for a standard file extension and start sending regular HTML documents as application/xhtml+xml.

So that takes me to the next phase of this project. I found that after I did this, the validator stopped complaining on files with .xhtml extension, but that files with .php were still being sent as text/html. I could not send all my PHP files on my various sites as application/xhtml+xml, so I couldn’t register .php as that mime-type. What I could do though was register PHP files in this current directory that I was serving them out of as application/xhtml+xml via .htaccess. Sounds great right? Sovles the problem right? Wrong. Unfortunately when I enabled this, I found out that it then bypassed the PHP interpreter and the pages would not render any PHP code in them due to that. So, I have XHTML 1.1 validated pages, but they are not parsed as PHP. I also did not want to parse every html or xhtml page through the PHP parser, that would be a waste of resources really.

After searching on Goolge, I found out that I was not the only person struggling with this issue. I will list the resources I used in my final solution at the end of this post to give credit where credit is due. BTW, around this time I also find that the browsers are displaying the page different, as mentioned in the first paragraph here. Mime-types again and compiant browser support…..

PHP has the ability to modify headers programatically, thus providing an anwer to this part of the delima. The end result is that through various resources I found that I could setup a PHP document to be sent as application/xhtml+xml to the browsers and validator that required and supported that mime-type, send it as text/html mime-type to IE and other browsers that required that and still have the PHP interpreter parse the pages PHP code properly. Want a code snippet? Here you go:

[quickcode: PHP Header- Content-Type: modifications]
header("Vary: Accept");
if(stristr($_SERVER["HTTP_ACCEPT"], "application/xhtml+xml"))
header("Content-Type: application/xhtml+xml; charset=utf-8");
elseif(stristr($_SERVER["HTTP_USER_AGENT"], "W3C_Validator") || stristr($_SERVER["HTTP_USER_AGENT"], "WDG_Validator"))
header("Content-Type: application/xhtml+xml; charset=utf-8");
else
header("Content-Type: text/html; charset=utf-8");

?>
[/quickcode]

What the code does: It first sees if the user agent is capable of the mime-type of application/xhtml+xml, and if it is sets the mime-type accordingly. If that is not the case, it checks to see if it is the validator engine accessing it, and if so, sets the mime-type to be proper for the application/xhtml+xml type. If both of those checks come back as false, it will fall back to text/html, for IE in other words.

This is important to note: It is not fooling the Validator in to validating the page. It is adjusting the mime-type according to user agent and user agent capabilities. In this case it is sending the appropriate mime-type to compliant browsers and the validator engine, while sending the expected type to non-conforming browsers and agents.

So now, I have PHP files that will be parsed by the PHP engine, have the extnesion of .php, and are being send with the appropriate mime-type based upon what agent is requesting it and what that agent’s capabilities are. Validation problem solved, but I still am having the white space and other problems occuring accross different browsers. Why?

The DOM in XHMTL is access and handled differently than in prior HTMl versions, and when a compliant user agent is accessing the page, this difference becomes manifested in the display of the page. In that aspect, how the body tag is handled differs between the two mime-types (application/xhtml+xml and text/html) in how a compliant browser displays them. The body tag is as the body is defined. If you define the body via CSS to be 770×500 pixels in size, with a background-color of #669900 you will have a box in an XHTML compliant browser that is 770×500 pixels in size that has the color of #669900. However, in a non-compliant browser or when using text/html as the mime-type for this document, you will find that the entire page background is the color #669900. The solution? Apply the color or background image to the html tag as well as the body tag and it should work in both complaint and non-compliant browsers, as well as with both mime-types.

So now I have a validated XHTML 1.1 and CSS layout based page, that is with the .php extension, is passed through the PHP parser as it should be, is rendered as application/xhtml+xml by supporting browser and the W3′s Validator, and is rendered as text/html by user agents and browsers (such as Internet Explorer) that do not support the XHTML specification.

All is good in the world again. The reference links I used in finding this out and compiling it in to this post are:

http://www.autisticcuckoo.net/archive.php?id=2004/11/03/content-negotiation
http://juicystudio.com/article/content-negotiation.php#php
http://www.xml.com/pub/a/2003/03/19/dive-into-xml.html
http://www.schillmania.com/content/entries/2004/10/24/application-xhtml+xml/
http://blogs.msdn.com/ie/archive/2005/09/15/467901.aspx
http://www.hixie.ch/advocacy/xhtml
http://www.workingwith.me.uk/articles/scripting/mimetypes