The (slightly misanthropic) Rules of HTML Compliance – Part 1

The following post(s) are edited from a document that I wrote a few years ago to try and provide a consistent standard for HTML and CSS submitted by contractors for projects that my company was working on. At the time we found that we were spending a significant chunk of time on rework, in order to make things function properly across different browser types, and the goal was to reduce this, and simultaneously improve quality and customer satisfaction. I’ve edited things a bit, as the original was written with a sarcastic (and occasionally profane) tone that is slightly embarrassing in retrospect (although entirely necessary at the time).

The objective of the following rules is to dramatically reduce the number of issues that occur when a web mockup that was designed and tested in [pick your designer’s favorite web browser of the moment] is suddenly subjected to [some other browser]. Some of them may seem arbitrary, but they’re based on experience. Ignore at your peril.

Rule 1: Validate Your Code

  • All html / css should be run through a validator (i.e. http://validator.w3.org/) and as many issues as possible should be fixed. This alone will prevent 60%+ of the issues you will encounter.
  • Make sure you do at least some cursory testing of your mockups in the following browsers before submitting them for further coding: At least one version of Firefox (reasonably recent), the three most recent versions of IE (compliance mode is a fairly decent – but not perfect – simulator of IE7. Remember that IE8 and 9 aren’t always perfectly identical across different operating systems). If you have time and the right equipment, check Safari on a Mac, and FF’s Mac version (different from a PC). It is OK if the site isn’t perfect in IE6 or lower, although if you follow the rules below it will (often) actually be surprisingly decent.
  • This section also contained an extended (and somewhat profane) rant, which has been removed!

Rule 2: Follow the Box Model

This is an extremely important rule. If you can follow it (some unfortunate exceptions listed below), it will resolve the vast majority of remaining cross-browser issues.

  • The only type of tag that should (ever) have large scale css positioning attached to it is a “<div>”. It is acceptable to have very small adjustments to positioning associated with other tags, but only after you have everything in pretty much the right place using divs. If you’re moving a tag around by more than a few pixels, consider wrapping it with a div, and using that to do the positioning. The reason is that even if you set the other tag to “display: block;”, you cannot trust all browsers to render them the same way.
  • I’m not going to quantify this, because I’m pretty sure people will take it out of context: if you need to position an element by more than a few pixels, wrap it in a div!
  • Repeat: Do not try to do large scale positioning using any other element than a div. Position the [censored] div first, and then place the content inside of it.
  • All content should be wrapped inside of a div. Divs should generally also be inside a div (unless its the main wrapper). If you have one div per row, a separate div inside of that div per column, and then another div wrapping each piece of content inside of the column, you will reduce the number of alignment issues that you need to fix later on. Exception: divs are for alignment. “<p>” tags are for paragraphs. Don’t confuse ’em!
  • Taking into account the previous item, relative positioning is strongly preferred. Absolute positioning is for special cases, and should have a reasonable justification.
  • Margins and padding – if done correctly – do not need to break IE. Make sure you use them correctly. Remember that padding is added onto the width of an element (i.e. the browser considers an element’s width to be the sum of the width set in css, plus any padding – and similarly for height). For this reason, use padding primarily in order to determine the appearance of an individual element, and use margins primarily for fiddly positioning.
  • A short aside: Do not assume that text will magically appear inside of a “<p>” tag. Text is frequently generated by code, or submitted by users. If you set fonts / sizing in a way that assumes that all text is inside of a paragraph tag, there’s a good change that parts of the website will appear broken.
  • One notable exception with regards to divs: some content management systems and development frameworks (ahem, the culprits know who they are) generate markup such as forms automatically, and either wrap form elements inconsistently, or with tags other than divs. In some cases it can take a significant amount of coding work to fix the problem. It is also often compounded by not putting appropriate ID or CLASS parameters on tags, making it difficult to properly lay out forms in such a way as to make them cross-browser compliant. The people responsible for these systems thus lose much karma.

Rule 3: Open and Close Tags Properly

It still astonishes me how many issues are due to improperly closed tags. Most problems of this nature will be caught be a W3C validator, but it is still worth expanding on:

  • If you open a tag, close it after. Surprisingly, this doesn’t appear to be obvious.
  • Divs for big sections MUST have an appropriate comment after (i.e. an html comment with the name of the div is fine). For example, if your div has an ID “mytag”, put the following after your closing tag: <!– //mytag –>. This way, you can easily spot where broken tags are located (code folding in an editor window will not always help with this).
  • Do NOT close a div like this: “<div />”. It will break most browsers (yes, it looks fine in FF). Don’t do it anyway. If you’re using a program that does this, you may want to check your html by hand after. There are only two tags where this sort of short form is acceptable: “<img />” and “<br />”. Image tags will be discussed in more detail below.
  • In a list (“<ul>” or “<ol>”), the ONLY tag that should be a direct descendant is an “<li>” tag. I have frequently encountered situations where designers do things like this: <ul><form><li></li><li></li></form></ul>. This works well in some browsers, and breaks horribly in others. It is better to place the form tag completely outside of the list. Alternatively, consider using something else to position the individual elements of a form (i.e. divs, a table, or if you want to “get semantic”, a dl/dt/dd structure).
  • Do NOT place a link around a div (i.e. “<a><div>…</div></a>”). If you need a div to be click-able, there are lots of W3C compliant ways to accomplish this.

Part 2 of this post may be found here.