Web development mistakes

Translations of this article are available.

This is a compilation of web development mistakes that I originally wrote about in the posts Web development mistakes and Web development mistakes, Redux.

The list contains mistakes that are commonly encountered on the web, along with an explanation of why I consider them mistakes. I also try to offer a way of avoiding each mistake, as well as links to more information on some of the mistakes.

DOCTYPE confusion
Completely missing, incorrect, or in the wrong place. I have seen HTML 4.0 Transitional used in documents containing XHTML markup as well as in <frameset> documents, DOCTYPE declarations appearing after the opening <html> tag, and incomplete DOCTYPES.
Why? Two reasons. First, it’s required, as stated in the W3C HTML 4.01 spec as well as in the W3C XHTML 1.0 spec. Second, modern web browsers use the specified DOCTYPE to decide which rendering mode to use. This is also known as “DOCTYPE switching”. For more consistent results across browsers, especially when using CSS, you’ll want browsers to use their “Standards compliance mode”. More info on DOCTYPE switching can be found in Fix Your Site With the Right DOCTYPE! and Activating the Right Layout Mode Using the Doctype Declaration.
<span> mania
A common way of styling something with CSS is to wrap it in a <span> element with a class attribute and use that to hook up the styling. I’m sure we’ve all seen things like <span class="heading"> and <span class="bodytext">.
Why? It is, in most cases, completely unnecessary, has no semantic value, and just clutters the markup. Use heading elements for headings, put paragraphs in paragraph elements, mark up lists with HTML list elements. Use CSS to style those elements. If necessary, add class or id attributes.
(too much) Visual thinking
Treating the web as WYSIWYG – starting off by focusing on how things look instead of thinking about structure first, and presentation later.
Why? While most people using the web are sighted, all are not. And there is no way of making the web WYSIWYG. There will always be variations as long as people use different browsers, operating systems, monitor sizes, screen resolutions, window sizes, colour calibration, and font sizes. The web is not print or television. Make your design flexible.
Lack of semantics
Non-semantic markup. Basing the choice of which HTML element to use on the way most graphical browsers render it by default, instead of on which meaning the element has.
Why? This mistake is closely related to “<span> mania”, in that it does not make proper use of existing HTML elements to give content meaning. Without semantic HTML, it is much harder for non-visual user agents to make sense of the content. Semantic HTML also tends to be easy to style with CSS.
Character encoding mismatches
Specifying one character encoding in the HTTP header sent by the server, and using another in the document. This may confuse browsers and make them display the document improperly.
Why? Because you want to make sure all your visitors can read your content.
Bad alt attributes
Missing or useless. <img> elements with missing alt attributes can be found in billions on the web. Not quite as common are useless attribute values like “spacer GIF used to make the layout look good”, “big blue bullet with dropshadow”, and “JPEG image, 123 KB”. Remember, the alt attribute is required for <img> and <area> elements.
Why? It’s required, and without it, any information in the image will be invisible to screen readers, text-only browsers, search engine robots, or users with images turned off. Note that alternate text should be relevant. Do not specify alternate text for decorative images or images used for layout. In those cases, specify an empty string, alt="".
Invalid id and class attributes

Multiple uses of the same value for the id attribute. Invalid characters used in id and class attributes and CSS selectors.

For CSS (CSS 2.1 Syntax and basic data types):

In CSS 2.1, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [A-Za-z0-9] and ISO 10646 characters U+00A1 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit.

For HTML (Basic HTML data types):

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

Why? Browsers that follow the specification will not display your document as intended. If a document has multiple occurrences of the same id value, any JavaScript using that value is likely to break or behave unpredictably.
Browser sniffing
Using scripts, server or client side, in an attempt to detect the visitor’s browser, and send or execute browser-specific code. Very commonly fails for reasons like new browsers, updated browsers, and user agent spoofing (Opera does this by default).
Why? It adds unnecessary complexity, and will break eventually.
Missing units in CSS
Length values (horizontal or vertical measurements) require units in CSS, except when the value is zero. It’s not like in HTML, where you can type width="10". In CSS, it has to be width:10px; (or whatever unit you’re using).
Why? It doesn’t work in browsers that follow the specification.
Browser-specific CSS.
Scrollbar styling, expressions, filters etc. Proprietary CSS that only works in Internet Explorer. Invalid, too.
Why? Only works in a specific browser. If you really must use IE-specific CSS, move it to a separate file and use conditional comments, or some other means, to make sure only IE sees the invalid rules.
JavaScript dependency
Making a site depend on JavaScript. More people than you’d like are either using a browser with no JavaScript support, or have disabled JavaScript in their browser. Current stats (Browser Statistics at W3Schools, TheCounter.com) indicate that this is 8-10 percent of web users. Search engine robots currently don’t interpret JavaScript very well either, even though there are reports that Google are working on JavaScript support for Googlebot. If your site requires JavaScript to navigate, don’t expect great search engine rankings.
Why? Inaccessible and bad for search engine rankings.
Flash dependency
Assuming everybody has Flash installed. Not everybody has. And most search engine robots do not (Google has reportedly started experimenting with indexing of Flash files, but they still recommend that you make sure all your text content and navigation is available in HTML files), so if your whole site, or your site navigation, depends on Flash being available, you’re not going to score high with search engines.
Why? Inaccessible and bad for search engine rankings. I’m not saying you shouldn’t use Flash at all, just that you should use it sensibly.
Text as image
Making images of text, and not providing a more accessible alternative. Not only does it take longer for visitors to download images instead of text, you also make it impossible for all visitors to copy the text, and for most visitors to enlarge it.
Why? Inaccessible, increases load time, bad for search engine rankings.
Bad forms
Inaccessible, hard-to-use forms. Learn to use the <label>, <fieldset>, and <legend> elements, and do not use a “Reset” button.
Why? Inaccessible, decreased usability. Read Creating Accessible Forms, Better Accessible Forms, and Reset and Cancel Buttons to learn more about creating accessible and usable forms.
Old skool HTML
Multiple nested tables, spacer GIFs, <font> elements, presentational markup. So common I don’t really have to mention it here.
Why? Increased complexity, bloated pages, slow, inaccessible, bad for search engine rankings.
Being IE-centric
Coding for IE/Win first, then adjusting for others, if there is time.
Why? Takes more time, encourages bad coding practices. IE/Win is notorious for accepting sloppy, invalid HTML, which breaks in many other browsers. IE also accepts well-formed, valid HTML, which works in all browsers, so by using valid HTML you make all browsers happy, and it doesn’t take more time or cost more. Also see The IE Factor.
Invalid HTML attributes
Using deprecated or browser specific attributes like marginwidth, leftmargin, language, height for <table> elements, border for <img> elements etc.
Why? Invalid and unnecessary. Use CSS instead. For <script> elements, use type, not language, to specify the scripting language (almost always JavaScript).
Unencoded ampersands
Many URIs contain long query strings with unencoded ampersands (&). This is invalid, and may cause problems. Ampersands must be written as &amp;.
Why? An explanation as well as an example of what can go wrong can be found in Ampersands and validation.
Frames
Using frames to split the browser viewport into several independent documents.
Why? First of all, let me say that frames may be useful, if used in the right way, in intranets and certain web applications. For a public website, however, frames have too many accessibility and usability problems. Bookmarking problems, printing difficulties, trouble with deep linking, and having to do search engine workarounds are a few of the drawbacks to using frames.
Inaccessible data tables
Tables containing tabular data, but marked up as if they were layout tables, not using any of the many elements and attributes that are available for making tables structured and accessible.
Why? Screen readers and other assistive technologies have no way to make sense of a data table unless it is marked up correctly. A whole bunch of links to articles describing how to mark up data tables can be found in A table, s’il vous plaît, at the Web Standards Project.
Divitis and classitis
Related to <span> mania. Adding unnecessary div elements and class attributes.
Why? See “<span> mania” and “lack of semantics”.
Too wide fixed width
If you use a fixed width design, don’t make it too wide. Note: I’m not getting into the whole debate on fixed vs fluid width here.
Why? If your specified width is wider than your visitors can fit on their monitor, you force them to scroll horizontally, which is really bad for usability.
Vague and/or presentational class and id names
Naming a class or id based on how it looks rather than on what it does.
Why? Doing this is asking for confusion when you redesign. A class named largeblue may end up making text small and red. An id named leftcol may be displayed to the right.
No background colour
Failure to declare a background colour for the body element.
Why? Many users do not have their browser set to display the same default background colour as you do.
Non well-formed XHTML
Using XHTML that is not well-formed.
Why? If XHTML is served as application/xhtml+xml, which it should be, strictly compliant browsers, like those based on Mozilla, will not render non well-formed XHTML. Note that this site currently does not serve all documents as application/xhtml+xml, for certain reasons explained in my post on Content negotiation.
Incomplete colours for text input fields
Specifying only background or text colour for form fields, especially single and multi-line text inputs (input type="text" and textarea).

Why? Some people set their browser or operating system to use inverted colours. The default for a text input would then be white text on a black background, instead of black on white.

If you set the text colour for text inputs to dark grey, and don't specify a background colour, people with inverted colours would get dark grey text on a black background, which is next to impossible to read. The opposite will also cause problems – specifying a light grey background without specifying the text colour would lead to white text on a light grey background.

Always specify either both text and background colours, or none at all, for text input fields.

That’s a pretty long list of things to watch out for. Avoid them all and you’re doing very well. If you’re currently making some of these mistakes, well, if it’s any consolation, I’ve been guilty of making a lot of them at some point. Hopefully this list will help you make fewer mistakes in the future.

Comments are still open for the original blog post, Web development mistakes, redux, if you’d like to add one.