This gives miscellaneous information related to the testing of websites:
Note : this page has recently been added to the Browser News. It will be expanded as time permits.
Testing is easier if you design in ways that reduce browser differences, or that make differences less important. Here are a few guidelines:
Keep it simple: browser differences are more likely if the code or the page is needlessly complex.
Design to the standards, using a DOCTYPE that makes modern browsers honour standards more strictly: browser difference are more likely if the code violates standards.
Many believe Internet Explorer is the standard. It is not: it is just the most used. To paraphrase Mark Twain: “Satan (impatiently) to Newcomer: The trouble with you Internet Explorer people is that you think you are the best people down here; whereas you are merely the most numerous.” [quote...]
Note : you should also “test to the standards”, i.e. do initial testing with a browser that complies very well with the standards. Only when the design works with such a browser should it be tested with lesser browsers — the chief troublemakers being the various versions of Internet Explorer — and only then should any code be tweaked to get around problems these browsers have: and even then it is usually possible to tweak the code and still honour the standards.
Note : if you are unsure about the benefits of designing to the standards, read Using Web Standards in your Web Pages.
Use only valid HTML 4.01 and CSS 2.1: invalid code puts you at the mercy of how different browsers — past, present, and future — handle coding errors. Several HTML validators and CSS validators are available. You can use xHTML 1.0 instead of HTML 4.01, but some argue you should not, and you should ponder their advice. [more...]
Once it was hard to make pages valid, because poor standards support entailed the use of non-standard features. E.g. a non-standard BACKGROUND attribute was used for TABLE tags to specify background images when browsers did not support CSS background-image.
Making invalid pages today is rarely justified. Alas, many software tools such as Microsoft’s FrontPage create badly broken code targeting extinct browsers; modern tools are much better, e.g.:
One special challenge is to work with legacy sites — like this site, the Browser News — which were created long ago when standards support was very poor. Such sites often have code that has accreted over the years, including code that deals with differences or limitations in extinct browsers. Even code that is well designed, with a simple, regular structure, can devolve into chaos. Sites can therefore become more costly to maintain as time goes on, especially when not maintained by the original designer(s). At a certain point it may be cost effective to redo the code in line with modern coding practices. It may be hard, however, to get management approval for such a redesign, since management may not understand this issue; it may, therefore, be better to delay the redesign until the need arises for a major site update which has clear, tangible benefits that even a manager can understand ;-)
A contentious issue is when to use elements of emerging, unreleased standards, especially elements which enjoy a fair amount of browser support.
Examples are the HTML 5 <canvas> tag and the CSS 3 opacity property. New standards likely will not be supported by most browsers for
a long time. But this has also been true of existing standards: e.g., nearly 10 years after its release, CSS 2 is not universally fully supported,
and never will be. This author’s view is that well-established elements of proposed standards may be treated much like elements of official standards:
if using such an element makes the site more effective, but the site can still be effective without support of that element, then it is okay to use
it. Nonetheless, using anything which is not universally supported complicates testing, and using anything which is not in a released standard
complicates validation, so there must be a compelling reason for using elements of emerging standards.
Note : it is a common error to assume that what Internet Explorer supports is valid. IE has many non-standard features which are not supported by other browsers, or which are supported by other browsers only to help make them more compatible with legacy sites. The true standards — i.e. industry standards, not de facto standards — are those published by standards organizations such as ECMA, ISO, and the W3C.
Note : do not assume that there are no coding errors in a page that looks right. First, some errors may not be obvious when you test your work. Second, a browser that does not conform to the standards may wrongly produce results you expect. And third, some browsers — most notably IE — try hard to recover from errors gracefully by guessing what the designer intended, which hides errors. Often the first sign that there is a problem with your code is that your page looks bad with a different browser or an updated browser.
Use only well-formed HTML, where tags nest properly, and no end tags are omitted: some legacy browsers can misbehave badly if the HTML is not well-formed. [more...] Code checkers may warn about deviant code. [more...] Note that xHTML must be well-formed, so a validator alone will suffice to find deviant xHTML.
Use only CSS for layout; for consistency, put the CSS in files which all pages share.
Note : browsers have many properties whose default values are not defined in the specifications, and these properties
can vary from browser to browser. You should therefore specify CSS properties fully to avert differences in browser defaults.
E.g. if you want to make a page fill the browser window, do html, body { margin:0; padding:0; }: default margins and padding
are not defined in the specifications and may differ for different browsers; to ensure consistent results, CSS should set both.
Note : don’t use the cursive and fantasy generic CSS fonts: they vary too much from user to user, so it is hard to test for problems resulting from their use.
Caution : the CSS 2.1 specification does not say how marker positions or indent sizes for the <li> tag should be controlled.
Different browsers and different versions of a browser may control them in different ways, so setting a certain margin and padding for a list may
produce good results for one browser and awful results for another: you may need different CSS for different browsers — and perhaps for different versions of a browser —
and you must test very carefully with your full test suite.
Avoid over-precise control of layout: otherwise you may create fragile pages that break when browsers don’t do layout the way you expect, and you will waste time fighting how different browsers do layout, and how user preferences affect layout.
It is a common mistake to believe that layout can be precisely controlled. Browsers may do layout incorrectly because they are not standards-compliant. Browsers may do layout correctly but unexpectedly because (1) some elements of standards are optional, ambiguous, or unspecified, (2) layout is affected by user settings, PC configuration, and display technologies, or (3) you wrongly understand how layout should be done.
It is also a common mistake to believe that layout should be precisely controlled. Many designers — especially fledgling designers — try to treat a web page like a sheet of paper, with content to be placed in precise, pixel-perfect positions, with fonts of precise, pixel-perfect sizes. Such a view is wrong: the web is an elastic medium that can and must adapt to users with a wide range of devices and abilities.
Sadly, GUI authoring tools encourage precise layout. When told about problems, designers using these tools are often bewildered, denying that problems could possibly occur, or having no idea how to prevent them.
Here are some common problems resulting from attempts to control layout too precisely:
Blocks may overlap if the user‘s font size is larger than the designer expected. E.g. here is overlapping text in a page made by a professional designer using Dreamweaver:

In another example, from a well-known company’s site, the menu overlaps and distorts a search box:
![]()
Note : this problem is more common when designing for IE with font sizes in absolute units, e.g. in pixels. Designers may wrongly assume that users cannot change the sizes of such fonts, because IE makes it somewhat difficult to do so. Designers may therefore wrongly assume that such text will always fit into blocks of predictable sizes. In fact, however, users can resize fonts specified in absolute units — albeit more easily with some browsers — so sizes of blocks containing text are not truly knowable, and overlaps can occur if blocks are placed at absolute locations.
Another problem is unwanted gaps. E.g. here is the header of a page made by another professional designer using DreamWeaver; the larger than expected font results in a gap in the header, and a 1 pixel vertical offset in two pieces of the header:

Another example of this problem, this time in a site made by a designer using NetObjects Fusion, is this one, where vertical gaps appear between rows of a sliced image because text to the right of the slices was larger than the designer expected:

A third problem arises when the designer not only places page elements at pixel-perfect locations, but also crams the content into fixed-size blocks: if the user’s font size is larger than expected, the content may be too large to fit within the blocks, and the content may be cropped. Here is an example where this occurred on the CNN home page:

A fourth problem appears when the designer tries to control layout precisely in order to cram as much as possible into a small space. The page can be so crowded that people have a very hard time finding what they are looking for and reading what they have found. Also, the page can be so crowded that it cannot be made accessible to the disabled.
In many cases it is better to break up the page into multiple pages joined by links. For example, one page might list what information is available — as a list of headlines with teasers — with links to pages containing the actual information. Such pages can be smaller and more open, with more whitespace, which makes them faster to load and easier to use. Such pages are easier to test, because an open layout is less likely to break than a layout which is very compact.
Other problems include such things as: pages requiring horizontal scrolling (because the designers assumed a specific window size wider than some users have); pages with large whitespaces on the right side of the browser window, or on the left and right sides (because the designers assumed a specific window size much less than some users have); navigational buttons too small to be read by some users (because the designers made the buttons from images).
Avoid overcrowding pages: use whitespace wisely. Making crowded pages increases the likelihood that the layout will fall apart if the browser behaves a little differently than expected, or if the user needs a larger font than expected, or if the user has a device with a small screen, such as a web-enabled cellphone. Making crowded pages also makes it more likely that the tester will fail to notice small or subtle problems.
Avoid using poorly supported aspects of standards when failure would impair functionality: e.g. avoid CSS fixed positioning, which is not supported by IE6 and its progenitors.
Experience will teach you much about browsers differences, but good up-to-date reference books are essential. E.g.:
Because many people continue to use old, less capable browsers, even when much better versions are available, you may have to avoid using some poorly supported elements of standards for many years, until so few people use the old browsers that you can reasonably exclude these people from your websites.
If you must use something that is poorly supported, use a proven workaround that works
with all browsers. E.g. if you need
getElementById(), which old versions of IE do not support, cloak it in this equivalent function, which uses IE’s
document.all[] when getElementById() is missing:
function getElement ( id )
{
var element = null;
if ( document.getElementById )
element = document.getElementById( id );
else if ( document.all )
element = document.all[id];
return( element );
}
Another example of a proven workaround is to hide HTML or CSS that must be seen only by specific browsers by using @import restrictions or IE conditional comments. E.g. this HTML links to ie50.css only if the browser is IE 5.0x, enabling one to create CSS that copes specifically with IE 5.0x incompatibilities:
<!--[if lt IE 5.5000]>
<link rel="stylesheet" type="text/css" href="ie50.css">
<![endif]-->
Use programming languages like JavaScript very cautiously: develop software only when needed; and make maximum use of standard, proven components and techniques.
Creating software disproportionately increases development costs, because it is harder to make good software than good HTML and CSS.
Creating any software for a site adds an additional level of complexity, especially when “pushing the envelope”. In addition, using a client-side language like JavaScript increases the risk of encountering browser differences. JavaScript differences include such things as features missing (especially in older versions), features added (especially proprietary features), and features broken (e.g. when a browser fails to correctly adhere to the specifications). A good JavaScript reference manual is essential, but even a good manual cannot cover all possible problems.
One especially troublesome issue is the use of document.write to generate HTML or CSS “on the fly”, as the browser is
parsing the HTML or CSS: the code generated may not be inserted where you might expect, and may be inserted at different places by different browsers;
or the code generated may be inserted where you expect, but a browser’s parser may get confused and fail at some later point. Sometimes it
is safer to wait till the page is displayed, and then use the innerHTML method to dynamically change the page.
Avoid browser sniffing, since this is not entirely reliable.
For more information about browser sniffing and the alternatives, see Resources > Browser Sniffing.
Testing is made more difficult by a number of contentious things which browser makers have done:
The information below would be much, much longer if horribly broken browsers like Netscape 4 were still being used. Thank goodness that old browsers do die, eventually.
Browsers, like most other software, have bugs, and many bugs affect how pages are rendered, often in obscure situations. Older browsers have more bugs, and more serious bugs, so bugs are a bigger problem for users who do not (or can not) keep their browsers up to date.
This author found that, in Jan 2008, the biggest problems are IE older than IE 7: other browsers, such as Firefox and Opera, create fewer problems because their users tend to keep up to date; IE is a problem, not only because many users refuse to update (e.g. many IE5 users refuse to update to IE6), but also because some users can’t update (e.g. all IE5 users, and many IE6 users, can’t update to IE7, because IE7 is not available for versions of Windows older than XP SP2).
There are workarounds for many bugs — e.g. the notorious IE peekaboo bug — and there is much information on the Internet about these bugs and their workarounds. Experience and experiment are required to solve each bug.
Browser bugs complicate testing, especially when bugs are triggered by conditions which might not appear during routine testing. Internet Explorer should be tested more brutally.
Most browsers use the DOCTYPE to decide how strictly to apply standards. Using the DOCTYPE for this purpose is not part of any official standard, but it has proven useful for making it possible to apply standards properly without breaking legacy pages which were designed when today’s standards either did not exist or were very new. As discussed elsewhere, there are two or three DOCTYPE modes: quirks mode, which tells the browser to misbehave like legacy browsers; standards mode, which tells the browser to comply with the standards; and (except for Internet Explorer) almost-standards mode, which differs from standards mode only in how it calculates the heights of images within blocks.
One facet of using DOCTYPEs for this purpose is that, because there is no standard, some DOCTYPEs trigger different modes in different browsers. To help make browsers behave alike, only DOCTYPEs which trigger standards mode in all browsers should be used, so only a few are recommended DOCTYPEs.
Something which complicates the use of DOCTYPEs is that IE8 will honour the DOCTYPE differently if a meta tag appears telling IE8 to render pages like some other version of IE. For example, the DOCTYPE could indicate standards mode, but the meta tag could tell IE8 to emulate IE7, which would result in pages not being rendered as strictly as they could be. More information about this is available in Microsoft’s Defining Document Compatibility.
Another IE8 issue is that the user can force it into an IE7 mode, making it use an IE7 user agent and making it render pages more as IE7 would: though likely not exactly as IE7 would, so a page could be rendered differently in IE7 than it would in IE8’s IE7 emulation. Also, the switch to IE7 mode applies to all tabs, so if one tab holds a page which works best in IE8 mode, and another tab holds a page which works best in IE7 mode, when the user switches modes, one of the two pages will be degraded. (IE8 is, at the time this was written, an early beta, so Microsoft may change how it works.)
Another aspect of using DOCTYPEs for this purpose is that it has encouraged lazy designers to continue to make broken sites: designers omit the DOCTYPE or pick a DOCTYPE which triggers yesteryear’s quirky browser behaviours, focus on making websites which appear to work with their version of Internet Explorer, then complain in bewilderment when other browsers do not render their broken code the same way that their version of Internet Explorer does. The introduction of a meta tag by Microsoft in IE8 (and, presumably, later versions of IE) to make IE work like an older version makes it even easier for lazy designers to make broken sites.
Using a DOCTYPE which triggers standards mode will make it more likely that browsers will act alike: there may still be differences, but there will be fewer than with quirks mode. Using such a DOCTYPE is therefore an important part of making it easier to test sites.
HTML 5 may change this: the official position of its creators is that the DOCTYPE has no purpose,
so HTML 5 will have the unadorned DOCTYPE <!DOCTYPE html>: but there is no provision in this for an HTML 5 page which
retains some elements of older standards for backwards compatibility. We live in interesting times.
Browsers often perversely make the sizes of <h5> and <h6> headers smaller than the size of normal body text.
If you use such headers, therefore, you should consider setting your header font sizes yourself, e.g. using this CSS:
h1 { font-size:175%; }
h2 { font-size:152%; }
h3 { font-size:132%; }
h4 { font-size:115%; }
h5 { font-size:100%; }
h6 { font-size:100%; font-style:italic; }
Most browsers support some CSS which is not part of today’s official standards. In some cases the CSS is part of a draft standard; in some cases the CSS has been proposed — but not accepted — as an addition to a draft; and in some cases the CSS is inherently peculiar to a single browser.
An example of CSS in an emerging standard is the opacity property, which is defined in the draft CSS 3 standard. Use of such CSS clearly
complicates testing, since browser support is very uneven: but, on the other hand, this is just as true of unevenly supported features of CSS 2; well defined CSS 3, therefore, cannot
be excluded just for this reason. Use of such CSS may be justified if there is
enough browser support to make it worth the effort, and if the absence of support by other browsers is harmless, or can be made harmless.
An example of CSS which was a proposed standard, but which was not accepted, are the properties which Internet Explorer and some other browsers recognize for styling scrollbars. Use of such CSS may, perhaps, be justified — styling scrollbars is particularily contentious — but again only if there is enough browser support to make it worthwhile, and only if the absence of support by other browsers is harmless, or can be made harmless.
Marker positioning can also be a serious problem. A marker is the number, bullet, or other glyph which normally appears to the left of each item in a list. The CSS 2.1 specification does not say how to control the size of the indent for each item, nor does it say where to position the marker within the indent: instead, the CSS specification leaves this up to each individual browser.
Browsers control this through various combinations of <li> margin-left and padding-left properties, and different browsers do this
differently. Indeed, different versions of the same browser may do it differently: IE4 does it one way, IE5 another, and IE6 yet
another; Opera 9 does it one way, Opera 7 another, and older versions of Opera yet another; the Gecko browsers, fortunately, appear to be
consistent.
If, therefore, you wish to control the <li>
indent size and marker position, you must be prepared to use different CSS for each version of each browser, and to test with each browser and
each version. You must also be prepared to update each site when a new version appears which handles marker position differently.
This is possible, but onerous.
Note that CSS 2.0 defined a way to control the marker indent size and positioning, but no browser implemented it, so this was dropped in CSS 2.1. CSS 3 has re-introduced it, but it will be useless until most browsers support it, which will not be for many years, perhaps when all of today’s designers have retired.
An example of CSS which is peculiar to a single browser is Internet Explorer’s alpha transparency filter. Though it is supported only by Internet Explorer, it is the only way to make older versions of Internet Explorer support alpha transparency in PNG images. Since all other browsers support alpha transparency in PNG images properly, without a filter, using this particular proprietary CSS can be justified to ensure that pages work the same for all browsers. Using other proprietary CSS, however, is more contentious, and harder to justify.
In any case, use of such CSS complicates testing, and this must be a factor in deciding whether to use such CSS.
Most browsers support some HTML which is not part of today’s official standards. In some cases the HTML is part of a draft standard; in some cases the HTML is archaic HTML created for browsers which today are extinct; and in some cases the HTML is peculiar to a single browser.
An example of HTML in an emerging standard is the <canvas> tag, which is defined in the draft HTML 5 standard. Use of such HTML clearly
complicates testing, since browser support is very uneven. Use of such HTML may be justified if there is
enough browser support to make it worth the effort, but only if the absence of support by other browsers is harmless, or can be made harmless.
It is very important to use such HTML only if it helps make a site more effective, and only if the site remains effective even when the HTML is not supported.
Two examples of archaic HTML are the <blink> and <marquee> tags. The first was a Netscape invention,
the second a Microsoft invention, and neither is in today’s standards.
Flashing objects with frequencies from 2-55 Hz can trigger epileptic episodes in some people. For this reason, the
archaic HTML tags <blink> and <marquee> should never be used, the CSS 2
text-decoration:blink should never be used, and flashing effects using other techniques should be used only with extreme caution.
Another example of archaic HTML is the background attribute of the <table> tag: this attribute is not
in the standards, but its use was justifiable years ago when old browsers supported this attribute but did not support equivalent CSS. There is no
justification for using such HTML today.
Examples of HTML which are peculiar to a particular browser include the HTML which Microsoft invented to enable documents to be converted
from Word format to HTML format, and back, without loss of formatting information, e.g. <o:SmartTagType>. Such HTML
should never be used in web pages.
The bottom line is that you should not use non-standard HTML, except possibly HTML which is well-defined in an emerging specification: and if you use such HTML, you must make sure that the site remains effective without it, and you must accept that this complicates testing.
Since JavaScript and the DOM are inextricably intertwined, this discusses both together. For brevity, JavaScript will be used to refer to both.
Most browsers support some JavaScript which is not part of today’s official standards. In some cases the JavaScript is part of a draft standard, or has been proposed for such a standard; in some cases the JavaScript is archaic, created for browsers which are extinct, or nearly extinct; and in some cases the JavaScript is peculiar to one browser.
An example of JavaScript in an emerging standard are the generators and iterators supported by the Gecko 1.8.1 browser engine. It is difficult to justify using such features: cross-browser support is poor, acceptance in new standards is far from certain, and some browser makers have objected very strongly to these features, so support by their future browsers is especially uncertain. Use of such JavaScript may be justified, but only if the benefit is very great, and only if there is a viable alternative for other browsers: an example might be a new feature which makes critical code much faster, where more conventional code can be created for browsers which do not support the new feature. Such software is inevitably more complex, and is therefore more prone to software bugs, and more difficult to test.
An example of archaic JavaScript is Internet Explorer’s document.all[] array, used to get the element associated with an
HTML ID. The document.getElementById() method should be used instead, but Internet Explorer 5.0x for Windows, which is still
in common use, does not support it: for this reason it is necessary to use object detection to decide whichever technique to use.
It is best to encapsulate such archaic JavaScript in a function which uses the appropriate technique, for example:
function getElement ( id )
{
var element = null;
if ( document.getElementById )
element = document.getElementById( id );
else if ( document.all )
element = document.all[id];
return( element );
}
Encapsulating such differences in a standard, tested function keeps the software simple, and makes testing no more complex.
An example of JavaScript which is peculiar to one browser, is JavaScript for Internet Explorer to detect plugins. An
array navigator.plugins[] should have details about installed plugins, but Internet Explorer stupidly does not support it.
Code unique to Internet Explorer must therefore be used.
Code to get information about plugins should be encapsulated in a function which uses the appropriate technique, though this is
harder because different code is needed for each Internet Explorer plugin.
The bottom line is that you should not use non-standard JavaScript, except when it is extremely important to do so, and when the JavaScript differences are encapsulated within standard functions which make it unnecessary for other code to care about the differences. Creating a new standard function will complicate testing, but using a proven standard function should not.
Many designers create pages which contain JavaScript errors, especially when designers consider the errors to be harmless. This creates two problems. First, it may worry users who notice the errors, because they will worry that that there is a problem with their PC, or a problem with the site. Second, it makes it harder to detect errors which are not harmless, because the serious errors are hidden within a pile of supposedly harmless errors. There is no reason to allow JavaScript code to have any errors, and every reason to ensure that there are none.
Like many browsers, Firefox can automatically resize (shrink) images which are too big to fit within the browser window. This can be nice for the user, as it enables users to view large images without scrolling, but it can make it harder to test sites, since the resizing can obscure problems. It is therefore vital to disable resizing during testing. This is easy to do with many browsers, including Internet Explorer, Mozilla, SeaMonkey, and Firefox 1.5: but it is harder to do this with Firefox 2 because, in an act of appalling stupidity, the Firefox makers removed the option from the Preferences in Firefox 2: resizing can only be disabled using Firefox’s arcane about:config page.
To disable resizing with Firefox 2, it is necessary to set the following about:config property to false:
browser.enable_automatic_image_resizing
As discussed elsewhere, CSS recognizes five generic fonts: serif, sans-serif, cursive, fantasy, and monospace. To test a page which is styled using these fonts, it is necessary to determine which font is used, and to do this it can be helpful to be able to select generic fonts which can be easily distinguished. Firefox’s progenitor, Mozilla, enables one to select all the generic fonts, but the Firefox makers foolishly chose to remove this feature. (The Firefox makers appear to believe that taking features away from users makes Firefox easier to use.) This can complicate testing. Designers who make pages using all five generic fonts should consider using SeaMonkey instead of Firefox for testing, since SeaMonkey still allows all five generic fonts to be selected. Alternatively, designers can avoid using the cursive and fantasy generic fonts.
With the CSS box model, the width of a box is the width of the contents of the box, excluding padding, borders, and margins. Internet Explorer wrongly makes the width include the padding, borders, and margins, in IE 5, and in quirks mode in IE6 and IE7: in standards mode, IE6 and IE7 handle the width correctly.
If standards mode is used, there are testing problems, but only with IE5. To avoid problems with IE5, simply design the page so that the width is not critical, i.e. so that the page works well enough even with the wrong box model.
As discussed elsewhere, CSS recognizes five generic fonts: serif, sans-serif, cursive, fantasy, and monospace. To test a page which is styled using these fonts, it is necessary to determine which font is used, and to do this it can be helpful to be able to select generic fonts which can be easily distinguished. Unfortunately, IE picks the five fonts, and does not allow the user to select them, so if IE picks fonts which cannot be easily distinguished, people testing pages can do nothing about it.
When Internet Explorer encounters a CSS coding error, it may guess what the designer intended and render pages accordingingly, whereas the CSS standards say that browsers should ignore such errors. The result is that Internet Explorer obscures errors, making testing harder.
An example is height:20: this is an error because no units are specified; units are mandatory unless the value is zero. Internet Explorer commonly assumes that the
designer meant height:20px, and renders pages accordingly: such errors are common, probably because dimensions are not required
in HTML, where pixels are the standard unit, so sloppy designers can easily err when they create similar CSS. An amazing number of pages on the Internet have such errors.
The best way to prevent this problem is to only test sites which have been validated, hence have no CSS errors.
As discussed elsewhere, browser makers have chosen to use the DOCTYPE to decide how strictly to honour the standards. This use of DOCTYPEs is not prescribed in the standards: it is just a common way of enabling browsers to better honour the standards without breaking legacy sites.
A problem with IE is that versions older than IE7 require that the DOCTYPE appear on the very first line of an HTML file: if it is not on the first line, IE will render pages in quirks mode.
To avoid this problem, it is advisable to always put the DOCTYPE on the first line.
When the designer specifies a font size in absolute units, e.g. pixels, Internet Explorer makes it harder for a user to make Internet Explorer use another size. Many designers appear to assume that it is not just hard, but impossible, and therefore design a site assuming that the font size will always be exactly what they specify. However, it is possible to override the designer’s font size in Internet Explorer, and it is very easy to do so with many other browsers. The designer’s false assumption can, therefore, result in pages which look awful when the user overrides the size, e.g. to enlarge the text to make it more readable.
Note : the user can tell Internet Explorer to honour their preferred font size, ignoring the size set by the designer, using the command Tools, Internet Options, General, Accessibility, Check “Ignore Font Sizes Specified on Web Pages”. This is even easier with other browsers: with Firefox and Safari, for example, the user can simply do Ctrl + or Ctrl - to increase or decrease the font size. In this author’s experience, few people know about the Internet Explorer option, so it is easy for both designers and users to believe that it is not possible to override the font size.
The best way to deal with this is not to specify font sizes in absolute units, but instead to specify the sizes in ways which result in text growing or shrinking as the user’s preferred font size grows or shrinks. This is an element of “fluid design”. There are four ways of doing this:
Don’t specify any particular font size, but use tags like <h1>, <small>, and <big>, as appropriate: this makes all font sizes proportional to the user’s default font size, with normal text being the size which the user prefers.
One problem with this method is that it often results in fonts which are too large: historically, sites have made font sizes a bit smaller than the user’s default font size, so users tend to compensate by setting the default size a bit larger than what they really want. Using the default sizes, therefore, perversely results in text which is too large.
A problem with all these methods is that browsers tend to require users to pick their preferred font size from a list, and the list may not have the size which the user would most prefer. For example, this author’s version of Opera 9 offers these choices for font sizes: 10, 12, 13, 14, 16, 18, 21, 24, 26, 29, 32, 34, 37, 48, 64, 96; this author would prefer 17, but Opera does not offer this choice; and, like other browsers, Opera capriciously does not allow the user to simply enter the size they would prefer. This problem is especially serious for Internet Explorer, which offers a list with only five choices.
Another problem with this method is that it uses HTML to control appearance, and appearance is best controlled using CSS.
Specify font sizes using CSS, in percentages, e.g. font-size:83%: this makes all font sizes proportional to the user’s default font size,
with normal text being the specified percentage of the preferred size. Typically the percentage is less than 100%, which makes text harder to read, which is why, as
mentioned above, users tend to set their default size a bit larger than what they really want.
It can be hard, though, to pick percentages which result in a set of font sizes which fit well together: percentages cannot be exact when characters are formed from pixels, so a set of font sizes which are nicely in proportion for one user may be woefully out of proportion for another user.
Another problem is that this can result in font sizes which are far too small. For example, if the designer makes the size of small text (say) 50% of the normal size, it may be that a user who can read text at the 100% size cannot read it at the smaller size. Other browsers offer an option to set a minimum size, with smaller fonts being set to this minimum, hence users can prevent the font sizes from becoming unreadably small: but Internet Explorer does not offer such an option.
Still, this is a very common method.
Specify font sizes using CSS, in em units, e.g. font-size:.83em: this is similar to the second method. This
author prefers this method to the second method.
Specify font sizes using CSS, in the standard CSS sizes, e.g. font-size:medium, font-size:small, or
font-size:x-small: this makes all font sizes proportional to the user’s default font size,
with normal text being the preferred size when font-size:small is used (Internet Explorer), or font-size:medium
(all other browsers).
(What Internet Explorer does is wrong: if this is critical, it is easy, though a bit convoluted, to code around the problem.)
The advantage of this method is that, unlike the above two methods, this method results in a set of font sizes which are are nicely in proportion for all users. This is the approach most preferred by this author.
Note : this author recommends that only two font sizes be used for most body text, one size for normal body text, and a smaller size for footnotes and possibly for sidebars. Using more than two sizes for body text makes it harder to pick sizes which are readable, but clearly distinguishable, and may also confuse users, who could wonder what the significance of the different sizes is.
Something that often goes along with setting font sizes in absolute units, is setting positions of content at absolute positions: a designer who wrongly assumes that browsers will honour fixed font sizes will also often wrongly assume how much space the text will occupy; and such a designer may therefore position other blocks of content at specific, absolute positions, which often results in content overlapping or being cropped when the browser does not honour fixed font sizes. It is therefore important not only not to specify fixed font sizes, but also not to specify absolute positions for content. This is another aspect of fluid design.
When Internet Explorer encounters an HTML coding error, it guesses what the designer wants to happen, and renders the page accordingly. This can be good for users, because it makes pages usable which might otherwise not be usable, but this can make it harder to test sites, because it can obscure errors, and because other browsers likely will not behave the same.
Internet Explorer’s tolerance of HTML and CSS errors is arguably the major reason why so many designers create so many sites which appear to work with Internet Explorer, but which fail to work with other, less tolerant browsers: designers think that their sites are fine because they see no problems, forgetting that Internet Explorer hides problems.
Another important reason for the creation of so many sites that fail with other browsers, perhaps, is that many designers hold the view — perhaps subconsciously — that their version of Internet Explorer does what is right.
The best way to prevent this problem is to only test sites which have been validated, hence have no HTML errors.
When Internet Explorer encounters a JavaScript error, it offers information about the error, but the information is often too sparse to be useful: it reports only one error at a time, and although it reports the number of the line where the error was encountered, the number can be wrong, and the file where the error was encountered is not named.
It is therefore better to test first with browsers which provide more information about JavaScript errors — e.g. Firefox or Opera — and to test with Internet Explorer only when these browsers report no errors: this leaves only any errors arising from differences in Internet Explorer’s implementation of JavaScript.
Internet Explorer has complex security options which give users a lot of control about what IE will allow, on a site by site basis. One aspect to this is that the security mode can depend on whether a site is local, on the tester’s PC, or remote, on the web. This can result in sites behaving differently when tested locally than when tested remotely.
To circumvent this problem, Microsoft supports a MOTW (a Mark of the Web) comment, which can be added to web pages to make IE run a local site as if it were remote. Designers who want to ensure that sites can be properly tested locally should add the MOTW comment to all pages of sites which are affected by IE’s security options.
Unlike most browsers, Internet Explorer for Windows stupidly allows only one version of Internet Explorer to be installed on a PC. This is because Microsoft perversely and unnecessarily chose to integrate Internet Explorer with the operating system. There are ways to install more than one version of Internet Explorer, but testing with multiple versions is not anywhere as easy as testing with multiple versions of other browsers.
With IE, specifying a <table> width of 100% will typically make the table extend beyond the right margin. To prevent this, designers should set table widths using CSS, and should use a technique like conditional comments to make the width 98% for IE.
Internet Explorer 7 and its predecessors do not implement xHTML: they treat xHTML as if it were HTML.
There are two approaches to dealing with this. One is to always use HTML, never xHTML. The other approach is to use xHTML, but to follow the recommendations in the xHTML specifications to ensure that legacy browsers will render xHTML appropriately. Both approaches have their merits. This author prefers the latter approach, but recognizes that others do not agree.
Testing will be easier and quicker if you use automated tools that can find errors in your code. For example:
Validators : HTML validators and CSS validators report syntax errors, i.e. violations of a language’s rules. Validators may also issue warnings, e.g. about dubious elements in the code.
Using a validator is a fast and simple way to identify the most blatant errors. Because different browsers may handle errors differently, fix all syntax errors and critical warnings before manual testing.
Using a validator and studying its error messages will also help you learn more about HTML and CSS, and so enable you to improve the quality of your work.
Note : some authoring programs like FrontPage create invalid code; you should avoid using such programs.
Code Checkers : code checkers report errors and warnings about a page or site, e.g. missing end tags, nesting errors,
broken links, wrongly sized images, or accessibility issues. A code checker might report some of the same errors that a validator would report, but a code checker will
go beyond this to report what appear to be errors in perfectly valid code. E.g. if you have an img tag with a src
attribute naming an image file that does not exist, a validator will not report an error, because it does not violate the HTML syntax to refer to
a missing image file; but a code checker should report an error, or at least a warning, because it is very likely that the code specifies
either the wrong filename, or the correct filename of an image that has not yet been created.
Many HTML code checkers and CSS code checkers are available. For example:
Code checkers may issue warnings which you decide can be safely ignored. Deciding which warnings may be ignored can take time, so it is a good idea to change your code to eliminate even minor warnings so that new critical warnings are not hidden amongst old minor warnings, like needles in a haystack.
Some code checkers let you do less stringent checks to minimize unwanted warnings: this may be useful after making minor changes, but you should do strict checks after major changes or before major testing.
Error Consoles : these are browser windows which can dynamically report error and warnings detected while pages are loaded and used. Output in an error console likely indicates a coding error.
You must load the error console:
Gecko-Based Browsers : many Gecko-based browsers support an Error Console (called the JavaScript Console in Mozilla and older versions of Firefox). To view it you must click Tools, Error Console (or Tools, JavaScript Console in Mozilla and older versions of FF). You may be able to increase the amount of information reported: e.g. with Firefox, setting the about:config item javascript.options.strict to true will make Firefox report more potential JavaScript problems.
Internet Explorer : IE has no error console. It can produce a popup that reports JavaScript errors, but the report is often of little use except to say that somewhere there is some kind of error: the details it gives are often wrong or misleading. For initial testing you should use a more capable browser.
Opera : Opera supports an Error Console, called the JavaScript Console in Opera 8 and earlier versions. To view it, click Tools, Advanced, Error Console (Tools, Advanced, JavaScript Console in Opera 8 and earlier). You can control attributes of the Error Console using a set of opera:config options. [more...]
Safari : Safari supports an error console called the JavaScript Console. To use it you must turn on logging of JavaScript errors and load the window. With Safari 1.3 and up you can output your own messages to the console. [more...]
Error consoles are also useful in debugging, but will be discussed elsewhere.
Sanity Checkers : these are tools which can be used to detect anomalies which might result from errors. Examples of sanity checkers are:
Dust-Me Selectors Extension : this is a free Firefox extension [more...], which can be used to identify CSS selectors which are not used. It could be that unused selectors can simply be deleted; it may be that they are needed, but not yet; or it may be that they should have been used, but weren’t, in which case other, incorrect selectors may have been used instead.
Web Developer Extension : this is a free Firefox extension [more...], which offers many functions useful to website designers, including functions which can be considered to be sanity checkers, such as these:
Disable JavaScript : this can be used to quickly check whether a page works as expected when JavaScript is disabled.
Display Alt Attributes : this displays the values of the alt text associated with images,
making it easy to quickly check the text which would appear if the user disables images.
Outline Images Without Title Attributes : this can be used to identify images without title
attributes.
View Generated Source : this is like View Source, except that it also includes dynamically generated HTML. This makes it possible to see if there are errors in dynamic HTML.
There are many more useful functions, some useful for performing sanity checks, some useful for finding coding errors, and some useful for both.
This discusses selection and installation of browser test suites.
The first thing you must do is decide which browsers you will test with. Deciding can be hard.
You should clearly test with the browsers used by a significant number of your users. But what is significant? And how will you find out which browsers your visitors use?
When you decide what is significant, you are deciding how many people to exclude from your site, but you may also be deciding how effective to make your site. For if you don’t serve older browsers in common use, you exclude people who use these browsers; but if serving older browsers means that you can’t use features supported by modern browsers that could make your site more effective, then you may find yourself paying a high price for serving old browsers.
A
nasty fact of life is that many people don’t keep their browsers up to date.
E.g. a study of one stats source (EWS)
in Nov 2006 revealed not only that many people had old
versions of Netscape 8, but also that most had even older versions of Netscape 7, including mid-2002’s Netscape 7.0. Even though
it is easy to update, and very foolish not to, people still use older versions having more bugs, fewer capabilities, and more security risks.
The pie chart at the right illustrates the reported number of people using various versions of Netscape’s version 7 and 8 browsers.
Testing sites would be far, far easier if most people kept their browsers up to date: but, sadly, people don’t.
Another nasty fact of life is that browsers, like most software, have bugs, and that different versions have different bugs. This may affect testing. If, for example, Firefox 1.5.0.9 includes a bug fix, a page may be rendered by 1.5.0.9 differently than it is by some of its progenitors. Since many people do not keep their browsers up to date, and since it is not feasible to test with every version, some people will encounter problems with versions you don’t test.
One strategy is to test with both the initial and final subversions of a browser, e.g. with both Firefox 1.5 and 1.5.0.12: but you must always remember that intermediate subversions may behave differently. For example, a regression error may have occurred: the fix for a bug in one version may be inadvertently omitted from a later version.
Ironically, the browser least susceptible to this issue is Internet Explorer. Microsoft typically only fixes bugs (other than security bugs) with major releases. This means that IE will tend to have many more bugs than other browsers, but it also means that all versions of a major release will have the same bugs. E.g. you can be pretty sure that, except for security-related bugs, all versions of IE 6 will have the same bugs. This is in contrast to (say) Mozilla 1.7, which has 13 subversions, each with bug fixes that may affect how pages are rendered.
When you try to find out which browsers your visitors use, you will naturally check the browser stats, but likely discover that the stats are unreliable or unavailable. For example, stats typically report how many use Gecko-based browsers, but not how many use which version of Gecko — because this information is not generally available — and knowing this would be very helpful because different versions have different capabilities: e.g. NN 7.0, with Gecko 1.0, is in many ways crippled when compared to NN 7.2, with Gecko 1.7.2.
A conservative strategy would be to deploy an initial site that supports very old browsers like Netscape 7.0, and then to study the access logs to decide whether the numbers justify supporting the browsers in site updates. With this strategy you may initially use features supported only by modern browsers, but only when this does not impair the site’s functionality. A side-effect of this strategy is that it compels you to make an initial site that is simpler, and this simplicity may result in a better site: needless complexity makes sites less effective.
It can also make sense to test with uncommon browsers which comply very well with standards: browsers are made more standards compliant as time goes on, so making your site work with today’s standards compliant browsers will help ensure your site will work well — or can be easily made to work well — with future versions of browsers which today are less compliant: e.g. if Opera does something properly which other browsers don’t, making your site work with Opera will help ensure that your site will continue to work properly when other browsers catch up to Opera.
It can also make sense to test with an uncommon, very standards compliant browser because this may reveal errors in your code which would not otherwise be obvious.
You need not test with several browsers which use the same browser engine, because they will render pages alike: e.g. it is a waste of time to test with both Netscape 7.1 and Mozilla 1.4.1, because both use the same Gecko 1.4.1 browser engine.
Common browser engines include:
Gecko: this is used by many browsers. Here are key Gecko browsers:
Presto: this is used only by Opera 7 and up. Here are the latest versions:
Trident (also known as MSHTML): this is Microsoft’s browser engine for Windows. It is used by many browsers, including IE4 and up, Microsoft’s MSN Explorer for Windows, Netscape 8, most AOL browsers, Avant, Maxthon, SlimBrowser, and many more. Here are the various versions:
WebKit: this is Apple’s browser engine for OS X. It is based on Konqueror’s KHTML engine. It is used by Apple’s Safari and by a small number of other browsers, e.g. OmniWeb. Here are the latest major versions:
More and more people are using mobile devices such as cellphones for web browsing. This presents major challenges for web design, which can be met in part by specifying CSS rules which are specific to such devices.
You should consider testing with a mobile browser, or with a browser than emulates a mobile browser, e.g. Opera using its Small-Screen-Rendering Mode.
You likely want to install multiple test browsers on a single PC. This is possible, but there are problems, and each browser must be handled differently. The following gives information about installing and running these test browsers:
Note : you can find many browsers for testing here, in the Browser News.
Note : to install multiple browsers, you need a moderate amount of hard disk space; to run multiple browsers at the same time, you need a large amount of RAM. Fortunately both are cheap.
Installing multiple versions of Gecko browsers is simple. You can install as many versions as you like, but must install each in its own directory. You must also create a unique profile for each version. How to do this is nicely documented in mozillaZine.
Running Gecko browsers is more complex. You have to invoke the browser with an option specifying the profile. E.g.:
Suppose you installed Firefox 1.5 in c:\test\gecko\firefox1.5\.
Suppose you created a profile for it named FF1.5.
You could then run Firefox 1.5 using this DOS command:
c:\test\gecko\firefox1.5\firefox.exe -P FF1.5.
It is easiest to do this in Windows by creating a .bat file with this command, and creating a shortcut to the .bat file. An example of such a file would be:
c:\test\gecko\firefox1.5\firefox.exe -P FF1.5
EXIT
The above only works, however, when you need to run only one version at a time. If you want to run more than one version at a time, you must first set an environment variable, MOZ_NO_REMOTE, e.g. in a .bat file:
SET MOZ_NO_REMOTE=1
c:\test\gecko\firefox1.5\firefox.exe -P FF1.5
EXIT
Installing multiple versions of Opera is simple. You can install as many versions as you like, but must install each in its own directory.
Running multiple versions of Opera is likewise simple: just run the version(s) you want.
Installing multiple versions of Internet Explorer on one PC is complex, and there are several approaches:
With a multi-boot facility, install multiple copies of Windows on one PC, each copy with its own hard disk partition and its own version of IE.
This is troublesome, because it is necessary to reboot in order to switch from one version of IE to another. It also is wasteful of hard disk space, which can be a problem unless the hard drive is very large. In addition, a software license is needed for each different version of Windows.
Using a technique discovered by Joe Maddalone of insert-title.com for installing multiple versions of IE, it is possible to install several versions of IE at once.
There are some drawbacks, however: it is not supported by Microsoft; only one version can be run at a time; older versions are somewhat unstable; and some features like IE’s conditional comments do not work properly. The bottom line is that this can be very useful, but not entirely reliable.
With Microsoft’s Virtual PC, a free product, one can install virtual copies of Windows and certain other operating systems. E.g. on a PC with Windows XP Pro SP2 (and up), one could install a virtual copy of Windows 98 with IE 5, and a second virtual copy of Windows 98 with IE 5.5. The number of virtual copies is limited only by hard disk space; the number of virtual copies you can run at one time is limited only by the amount of RAM and the speed of the CPU.
To use virtual copies of Windows, however, you need a license for each virtual copy. E.g. if you want to test sites with IE5, you can use Virtual PC to install a virtual copy of Windows 2000, but you must have a license for Windows 2000. Exception : Microsoft issues free time-limited pre-activated Virtual PC images of Windows XP SP2 and Vista, each with IE6, IE7, or IE8β1, for those who wish to test multiple recent versions of IE on a single PC; Microsoft releases new time-limited versions periodically, so it is necessary to periodically remove the expired image and installer the newer image.
Note : there is a Virtual PC newsgroup, microsoft.public.virtualpc.
A product similar to Microsoft’s Virtual PC is VMware’s free VMware Player. It also lets you install virtual copies of operating systems, but it is better at supporting a non-Windows O/S. Especially useful is that you can install Virtual Appliances, which are easy to install pre-configured images of operating systems, e.g. an image of Linux with KDE and KDE’s Konqueror browser. Note, however, that VMware Player can run only one virtual O/S at a time, whereas with Microsoft’s Virtual PC one can run as many as you want if you have enough CPU power and RAM.
The free VMware Player has a number of limitations, including the fact that it can only run a pre-built virtual machine: it cannot create a new virtual machine. For more flexibility you need a product designed to create test environments, e.g. VMware WorkStation for Windows or Linux.
There are several other approaches for testing with browsers when you don't have the right kind of PC or O/S:
You can test pages for Safari 3 compatibility by using Safari 3.1, which is available for both OS X and Windows. Note : older versions of Safari are for OS X only.
You can test pages with Safari remotely at iCapture.
You can test pages with Safari remotely at safaritest.
You can test pages with various browsers remotely at BrowserShots.
If you can’t install some browsers which you should have for testing, consider a commercial service, e.g. BrowserCam.com.
You can adopt a design methodology that improves various aspects of site development, including testing:
Keep it simple: simplicity means less to do; simplicity means less complexity in what you do; thoughtful simplicity means a better site that is easier to use ... and to test.
This does not mean that a site must be starkly plain. A site should enable a pleasant browsing experience and project a positive image of the site’s owner, so the site must look good. Pages should simply not be overly ornate.
Simplicity is the hallmark of great minds:
“Simplicity is the ultimate sophistication” — Leonardo da Vinci
“The cheapest, fastest, and most reliable components of a computer system are those that aren't there” — Graham Bell
“Complexity creates confusion, simplicity focus” — Edward de Bono
“Simplicity is prerequisite for reliability” — Edsger Wybe Dijkstra
“A complex system that works is invariably found to have evolved from a simple system that works” — John Gall
“The ability to simplify means to eliminate the unnecessary so that the necessary may speak” — Hans Hofmann
“Simplicity is the final achievement: after one has played a vast quantity of notes and more notes, it is simplicity that emerges as the crowning reward of art” — Frederic Chopin
“Perfection is achieved not when there is nothing more to add, but rather when there is nothing more to take away” — Antoine de Saint-Exupéry
“An honest tale speeds best being plainly told” — William Shakespeare
Keeping things simple means using the available technologies wisely. E.g. when coding a page, the wisest choice is usually to use HTML or xHTML to specify structure, and to use CSS to specify appearance, with carefully chosen CSS classes for page elements which recur throughout a site: other choices may result in bloated, complex code that takes much more time to create and maintain.
An often overlooked aspect of keeping things simple is to keep text simple. People want to find information quickly, and skim text to find what they want: they don’t want to wade through rivers of turgid text. Keep text simple, clear, and concise. This makes pages more usable, and text errors easier to find.
Document key information needed when developing or updating the site.
For example, the documentation could list and briefly describe each file and JavaScript function: e.g., as I did for a baseball team’s site. The documentation may also include information that you might otherwise put elsewhere, e.g. a change log. The documentation should not duplicate what appears in other files, but since comments in source files (e.g. HTML, CSS, and JavaScript files) increase page load times, you should document such source files elsewhere.
It is especially important to document software clearly and in detail — e.g. to specify what a method does, what its arguments and return value are, and how it responds to errors — and to do so during the design process, not later. I spent 27 years developing software before I began designing websites, and one thing I learned early on is that a major cause of bugs is poorly documented software. If you carefully document the behaviour of each software component before you implement it, you are much more likely to implement it correctly, and those using it will much more likely use it correctly.
Software design is a science and art in which great attention to detail is essential. Poorly documented software means that some details will be unclear, likely will be misunderstood, and will often cause errors.
Documentation must be up to date: errors are worse than useless. If you are not sure you can keep it up to date, you may be better off not creating the documentation in the first place. Note: the task of keeping documentation up to date is harder when the documentation is not in the same file as the things it documents: e.g. it can be easy to forget that changing a JavaScript file may affect documentation in a different file. You must exert self-discipline to ensure that documentation is up to date.
Paying close attention to details is essential for efficient, effective design. It can sometimes be so easy to slap page elements together that fine details are overlooked, and it is mainly in the details that errors lurk: as the old saying goes, “The Devil is in the details”.
Being able to focus on the details is a skill that must be practised consciously and assiduously over a long period of time, but your diligence will reward you with the ability to do better work in less time.
A good way to learn is to learn from your mistakes. When you find an error, ask yourself where you went wrong. Every failure is an opportunity to learn.
Design for what browsers do well: trying to force browsers to do what they do badly invites needless problems.
Heed the words of the poet, Henry Wadsworth Longfellow: “The talent of success is nothing more than doing what you can do well.”
If you find yourself fighting the browsers, trying to force them to do reluctantly what you want, you likely are trying to make them do something they do not do well: stop fighting; find another approach that the browsers do well.
It is very common, alas, to try to make browsers do things they do not do well, e.g. because the designer is using features that are not well supported, or is more familiar with a medium with much different fortés, or could not resist unwise client demands. One common error is to try to control layout too precisely.
It is also very common to fail to make browsers do things which they do especially well. For example, using CSS it is easy to tell browsers to make pages look different when printed than when displayed, e.g. by using fonts more suited for printing, by omitting menus which serve no purpose when printed, and by minimizing the use of colour to minimize the user’s print costs. Below is depicted one page I made as it appears when displayed, and as it appears when printed:

Don’t do something just because it is possible: do it because it makes the site more effective, or because it enables you to do your work more effectively.
Many technophiles are eager to use anything new or flashy, even when not needed for the task at hand: e.g. many designers create flash pages — entry pages with eye catching special effects having no functional purpose — adding to all phases of the development time, and annoying impatient visitors who simply want to use the site.
A survey revealed that business professionals consider these to be important qualities of a great website:
For an effective website, focus first on these qualities.
When creating new pages, or changing existing pages, do your work one step at a time, with verifiable results at each step.
This makes it easier to develop and test your work: if a new problem appears, you will know that it is caused by what you have just done, and therefore you only have to review the little bit of work you have done since your previous step. This process is called “incremental development”. Making massive changes before testing any of them makes testing — and debugging — a massive problem.
Reduce, Reuse, Recycle: this mantra helps reduce wasted time, in more ways that you might expect.
Reduce : as repeatedly said here, keep it simple and focus on effectiveness. You are designing the site for the user, not to show off your amazing technical virtuosity. Keeping it simple can result in a better site with simpler and smaller code, and this will of course be simpler to test.
For example, don't use software and image rollovers for buttons: instead, make simpler buttons — preferably using styled text, not images — and either don't do rollovers, or do CSS rollovers. I once inherited a site with a menu generated by 230 lines of HTML, plus Java to control rollovers; I had to change the menu because it was impaired by the Eolas update, and I made a nicer menu with just 16 lines of HTML and 4 lines of CSS, with CSS rollovers. The old and new menus are pictured below:

You might argue that what you want to do cannot be done without JavaScript or a plethora of image buttons, and this may be true, though CSS can do more than you might expect (as shown by the CSS styled text buttons depicted below): but is what you want truly needed? It may be that what you want is very pretty, but that something simpler will suffice; it may even be that something simpler will be better, e.g. because CSS styled text buttons like these are more accessible and load faster than image buttons.
![]()
Note : some of the above buttons have background images, and one uses an image (of a key) as content, but the buttons are still essentially text buttons: the set of buttons on a site all share the same background images, all styling and rollovers are done using CSS, and the buttons automatically resize when the user changes their preferred font size; none of this is possible with pure image buttons.
Reuse : create common elements that are reused throughout the site. By creating a common element, you reduce the need to reïnvent and retest it when it is used elsewhere in your site.
For example: use common blocks of code for elements such as headers and footers that appear on every page, perhaps using server side includes if your server lets you do this; create a template from one of the first pages you create, using the template when making later pages; create flexible CSS classes for common objects, e.g. sidebars. The sidebars on this page, for example, are styled using four CSS rules, plus one rule for the dropcap.
Using common elements also helps make pages look more consistent.
Recycle : think of future sites when you design a site. Sometimes you can spend just a bit more time making a component or perfecting a technique that is a bit more general than is strictly required for one site, but which may be recycled in later sites. If you create just one or two for each site you make, you can quickly amass a library of proven components and techniques which you can recycle in other sites, saving much time in the long run.
E.g. I made a browser sniffer for a site which I have used many times in other sites. It may do more than is needed in any given site — e.g. it identifies the Opera browser even when this does not matter for a given site — but the advantage of being able to use the same proven block of code over and over outweighs the overhead of a few redundant lines of code.
Tip : when designing software, object-oriented programming often makes it easier to think about making components which can be repurposed.
Location, Location, Location: this mantra encourages consistency in organizing files to reduce confusion and errors.
Create a simple, consistent, fairly flat file structure for a small site’s files.
E.g. I normally put all source files — the HTML, CSS, and JS files — in the home directory,
image files in img/, and document files in doc/.
One nasty factor to consider in picking pathnames is that Windows considers upper- and lowercase
characters in pathnames to be the same, whereas most other O/S’s consider them to be different. E.g. Windows will deem
BrowserNews/ and browsernews/ to be the same, but Linux will not.
This means that, if the case of a character in a pathname is wrong, and both the development PC and the server run Windows, you will likely not
notice the error during testing. This also means that if other sites link to your site — or if users set bookmarks to your site —
URLs with characters in the wrong case may not be noticed. But if the site is later moved to a non-Windows server,
the errors will become important, and the URLs will fail. You should therefore think twice
before picking pathnames with mixed case characters.
Note that this issue does not affect domain names: upper- and lowercase characters in a URL’s domain name are
defined to be the same, no matter the O/S. E.g. www.BrowserNews.com is always
the same as www.browsernews.com.
A simple, consistent, flat file structure makes it easier to locate files.
It can also help reduce coding errors: e.g. if you put all document files in
doc/, then you know that any document pathname will be doc/*.*. (This may sound trivial, but I
have often seen sites where images or documents did not appear simply because the designer had specified the wrong pathnames:
e.g. in Dec 2006, pointing to the Stories button on this page
makes the Stories button disappear, simply due to a faulty pathname.)
I go one step further and use a simple, consistent scheme to name files. E.g. all images that are buttons have
pathnames beginning with img/but_, images of icons have pathnames beginning with img/ico_,
and images of maps have pathnames beginning with img/map_. (Again this may sound trivial, but it
helps to organize and identify the files, and to reduce coding errors: e.g. you won't think that img/but_home.png
is anything other than the image of a button.)
You may prefer a different convention. That’s fine: the important thing is that you be consistent with whatever convention you adopt.
Also, be consistent in the internal organization of a file.
For example, I often organize a CSS file in four sections:
Simple rules that apply to the whole site, e.g. a rule for styling a normal link.
Sets of rules that apply to common elements on the site, e.g. rules for styling a sidebar.
Sets of rules that apply only to specific pages, e.g. rules for styling the sitemap on a Site Map page.
Sets of rules for printing, e.g. to specify a simpler monochrome look when printing pages.
Organizing CSS files in this way can make it easier to find a relevant rule and can reduce the likelihood that a rule will fail because of a related rule that is not nearby in the file.
There are many websites out there, some good, some great, many mediocre. There are also many textbooks that offer standard solutions to common problems. Study the websites. Study the books. Don’t reïnvent the wheel and create something from scratch when you can adapt existing, proven ideas and techniques. These ideas and techniques can save you much time and enable you to build better sites.
Especially valuable are the techniques for dealing with bugs and poor standards support. E.g. IE6 has a bug, the peekaboo bug, which sometimes wrongly hides content: ingenious designers have, often though trial and error, evolved non-obvious solutions for many bugs like this; you will save much time by finding out how to quickly find their solutions.
Books you can learn from include:
Plan how you will test a site. Create a checklist. And follow the plan.
For example, the test plan might define three types of testing: initial, secondary, and tertiary:
Initial testing is done early, after a small number of typical pages have been created. The purpose of initial testing is to make sure that the design works. If there is a fundamental flaw in the design, this is the time to fix it; if there is a problem with a certain browser, this is the time to cope with it..
Initial testing begins with the use of automated test tools. This is following by tests with browsers that are highly compliant with standards, then with major browsers that are less compliant with standards, and finally with all the remaining browsers in the test suite. Testing should be comprehensive, and testers should try hard to make the design fail.
Initial testing does not end until problems have been fixed
Initial testing may involve the client, e.g. to enable the client to review the design: many people are unable to envision something until they see it in action, and it is not uncommon for a client to see initial work and realize that it was not what they expected, or that it has unexpected usability problems. (Changes at this point may be chargeable, assuming that the client signed off on the initial design.)
Caution : problems can lurk in a site that looks fine, so testing may miss problems. It is therefore important to maintain a neutral or skeptical attitude during site development and testing.
Here is a sample test checklist:
Secondary testing is less formal, and is done repeatedly throughout the development cycle whenever the designer wants to check their work. The purpose of secondary testing is to see if the work done to date is okay.
Secondary testing begins with the use of automated test tools. This is following by tests with browsers that are highly compliant with standards, then perhaps with major browsers that are less compliant with standards. Minor browsers are not tested unless there is some reason to suspect that there may be a problem: secondary testing should be quick and therefore less comprehensive than initial testing; it is assumed than initial testing has already found and fixed critical problems with minor browsers. If a problem is found, it may be fixed then, or it may simply be added to a to-do list.
Secondary testing may end with an interim site which is made available to the client, who may wish to request changes, but it is important to make it clear that the work is incomplete and may have outstanding problems. (Changes requested by the client at this point may be chargeable, assuming that the client signed off on the initial design.)
Tertiary testing is done before deploying the site. The purpose of tertiary testing is to make sure that the site is ready for use.
Tertiary testing begins with the use of automated test tools. This is following by tests with browsers that are highly compliant with standards, then with major browsers that are less compliant with standards, and finally with all the remaining browsers in the test suite. Testing should be comprehensive. Problems should be fixed, with testing repeated on pages affected by any changes needed to fix the problems.
The client must sign off on the site when final testing has proven that the site meets the requirements.
The test plan should also define how changes will be handled, and how the site is to be re-tested:
It is most cost effective to add desired changes to a to-do list, and then to schedule the changes so that related changes and very minor changes are done at the same time.
It is critical to establish the scope of changes in order to determine what must be re-tested. In some cases, e.g. when changes are related, only one page or a set of pages need be re-tested; in some cases, e.g. when changes are very minor, it suffices to test with only one browser, or with a small set of browsers; and in some cases it is necessary to re-test the entire site with the full test suite. In the last case, as many changes as possible should be done together so that as many changes as possible can be tested at one time.