Style Guide & Coding Standards for HTML

last revised March 19, 2011
effective starting March 19, 2011


Contents

Introduction
Overview
File Naming Conventions
Blocks
CSS and Styles
Comments
Page Elements
Form Elements
Images
Google Analytics
Sample Page


Introduction

This document describes coding standards for HTML pages developed at Cliffson Solutions, LLC. Unless superseded by client requirements, these standards apply to all HTML pages developed by employees and subcontractors of this company for both internal use and client projects, including pages coexisting with or generated by PHP code.

The purpose of these standards is to bring consistency to the structure of HTML pages, including formatting and naming conventions. HTML, like many free-form programming languages, allows a fair amount of flexibility in in the underlying code of a Web page while still rendering the page in same fashion. This flexibility means only a relatively few, simple grammar rules are required, but if some guidelines and layout conventions are not applied as the pages are built, the code can become very difficult to read and maintain.

Some would argue that using Web page design and management tools eliminates the need for interaction with raw HTML code. However, our experience is that these tools will inevitably reach their limits in desired effects or introduce odd behaviors that must be remedied by hand-editing. The unfortunate truth is that most of these tools also generate very poorly structured code and a great deal of unnecessary garbage, which make working with the raw HTML even more difficult than it needs to be.

Historically, browsers are remarkably lax and wildly inconsistent in their interpretation of HTML tags, HTML and CSS standards, even adding support for their own unique codes and capabilities. This situation has improved in recent years, but many modern browsers still support old conventions and quirks for the sake of backwards compatibility — at the cost of rendering speeds and inconsistencies in displayed pages. Some browsers (such as Firefox) also automatically detect and correct some missing or mistyped end-tags, which although well-intentioned can actually obscure coding problems that cause problems in other browsers.

Our goal is to use tag conventions known to work with the widest variety of modern browsers following W3 standards. We do not spend a great deal of time accommodating the quirks of browsers that insist on flouting established standards.

Many clients only care if the pages appear in their favorite browswer correctly, not how consistently the pages are rendered by other browsers or how the underlying HTML is formatted. However, the practical consideration is that well-formatted and well-organized code is considerably easier to maintain and enhance, saving both the client and developers time and money in the long run.


Overview

We readily acknowledge that many of the conventions described here are strictly preferences and that such conventions can incite passions on par with the wildest religious and political convictions. However, these conventions have been developed based on years of building HTML pages and noting what works well and what does not. In some cases these may result in a bit more typing, but any programmer worth his/her salt will 1) already be a decent typist, and 2) realizes clear coding can save at least an order of magnitude in time quickly locating functional blocks.

This document discusses conventions for HTML coding. However, very few of our pages are pure HTML pages; most pages are largely virtual, being generated by scripting languages such as PHP. Many of these pages include chunks of Javascript as well. The standards described here complement programming standards for these scripts. Other documents that should also be consulted while developing Web pages:

Style Guide and Coding Standards for CSS
Style Guide and Coding Standards for Javascript
Style Guide and Coding Standards for PHP

All pages must be compliant with W3C DTD (World Wide Web Consortium Document Type Definitions) for XHTML Transitional or Strict standards. Whenever possible, all new pages created from scratch should conform to Strict standards, but this is not always possible. All pages must start with one of these two DOCTYPE tags:


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" >

        

or


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" >

        

In addition, the following should also be included in the head section:


    <meta http-equiv="content-type" content="text/html; charset=utf-8" />

        

All pages must pass all W3C Validator (Tidy and OpenSP) and Level I Accessibility tests. The easiest way to test individual pages is with the Firefox extension HTML Validator. All pages on Cliffon Solutions servers are also periodically scanned with automated tools that check the validity of HTML codes (as well as looking for broken links). All reported problems are fixed as soon as they are reported.

We use block-level indenting of two spaces, particularly for complicated layered page elements such as tables. Indenting tag blocks by two spaces is sufficient to make the blocks readily visible without using an inordinate amount of horizontal real estate. All code is written assuming a 80-column display.

Note that, contrary to some arguments, adding these additional characters really does not affect page download speeds noticeably. A 1.5 Mbps DSL connection will download the average 20 KB Web file in less than 0.2 seconds, and even adding 50% to the file size in extra spacing and end-of-line characters is still less than 0.3 seconds — a difference hardly noticeable to the normal user, especially as graphics tend to dominate overall download speeds. On the other hand, HTML code that appears as one or two never-wrapping run-on strings is extremely difficult to examine and tweak. See the section Blocks below for more details.

We also use specific naming conventions for class and id values used in page elements, particularly in form elements and <div> blocks. These make tracking of element types much easier, and they are an extension of similar one- and two-letter prefixes on Javascript and PHP variables. The benefit of telling at a glance what type of element the value is referring to is well-worth the time taken to type these one- to three-letter prefixes. See the sections Page Elements and Form Elements below for more details.

Note that converting existing HTML code to the guidelines described here may be largely automated by using an in-house reformatting utility (PageMaid). This tool will also detect and correct missing end-tags, although manual intervention will be required if the page is seriously malformed.


File Naming Conventions

Pure HTML files may be named using .html or .htm extensions, although the former is preferred. Pages which included or are generated by PHP must use .php extensions in order to be parsed correctly by the Apache Web server.

In general, the names of Web page files are all lowercase. This differentiates them from directories, which always start with capital letters. Underscores may be used to make names more meaningful. Spaces and dashes are not used in either file or directory names.

All directories should contain an default index file (index.html, index.htm, or index.php). The Apache server is configured to not display directory contents when one of these files is not present for server security reasons, but including a default Web page for every directory is much more user-friendly. Commonly, the index file is a symbolic link to a file with a more meaningful name (e.g., about_us.php or site_map.html).


Blocks

All HTML blocks are indented by two spaces per level. Blocks are defined as text enclosed by tags which normally appear on more than one line or which have many sub-tags under them. For example, sub-tags under <table> (row, cells, headers) are always indented, but short self-contained tags such as <span> ... </span>, <h3> ... </h3>, <title> ... </title>, <img ... />, <a href= ... > ... </a>, and the like may be written on a single line, indented to the current level.

Example:


          <table summary="test table">
            <tr>
              <td>
                This is cell #1
              </td>
              <td>
                <span class="font_error">This is an error</span>
                <br />
                in cell #2
              </td>
            </tr>
          </table>

        

Example:


          <ul>
            <li>
              item #1
            </li>
            <li>
              item #2
            </li>
            <li>
              item #3
            </li>
          <ul>

        

Other tags that mark breaks in text or blocks should appear on lines by themselves, indented to the level appropriate at that point. These include:


          <br />

          <hr />

          <p>
            ... 
          </p>

          <div>
            ...
          </div>

        

Example:


          <p>
            This is a test paragraph.
            <br />
            <br />
            <img src="my_logo.png" alt="business logo" />
          </p>
          <br />
          <br />
          <hr />

        

Indenting within <head> ... </head> and <body> ... </body> tags is optional. Although such indenting makes finding these two major tags somewhat easier, indenting the vast majority of HTML contents in a page is tedious to type and wastes precious horizontal space.

Note that embedded PHP code is indented independently of HTML indenting. Refer to the Style Guide & Coding Standards for PHP for more details.

Tabs are never used for indenting, as they do not always render consistently across different terminal software. Editors which handle indents as an optimal mix of tabs (assuming tabs are equivalent to eight characters) and spaces must have this feature configured to use spaces only or this feature must be disabled.

All statements which are longer than 80 characters after indenting must be manually wrapped to fit in an 80-column display. Breaks in such lines should be made where convenient (e.g., at commas and spaces between words or between tag components). Continuation lines should always be indented one space until the entire logical line is complete.

Example:


    <p>
      For more information, please click on
      <a href="http://some-really-long-site-name.com/Moreinfo.hmtl">This
       link</a>
      or call 1-888-555-1234
    </p>

        

Example:


    <form name="frmRegistration" id="frmRegistration" method="post"
     action="process_form.php">
      <Name:>
      &nbsp;
      <input type="text" size="20" maxlength="35" 
       onchange="fnValidate_Input()"
    </form>

        

CSS and Styles

Styles should be defined in a separate .css file for all major projects, particularly those where multiple pages share common style settings. On rare occasions, where the page is standalone and not tied to a particular application or site design, styles may be defined in-line in the <head> section. The format of such definitions are illustrated here:


          <head>
            <style type="text/css">
              .font_required
              {
                color: $cc0000;
              }
            </style>
          </head>

        

Local definitions or overrides of style definitions within the page elements tags should be used only if one or two settings need to be tweaked and then only if similar tweaks are not used in other elements. Otherwise, a new class definition should be added to the accompanying .css file.

All styles are associated with classes, not IDs. We use IDs strictly for DOM manipulation (as in Javascript functions), never for style definitions. This convention derives from the fact that IDs must be unique within the page, but classes may be referenced by as many page elements as is appropriate. Defining a style in terms of an ID that can only be used once is not particularly flexible.

Use of  &nbsp;  tags to control page layout should be extremely limited. Instead, layouts should be controlled by using div blocks and adjusting margin and padding settings in the corresponding CSS classes.

Careful attention should be paid to background and text color choices. All pages should be reviewed on multiple computers using several browsers (Firefox, IE 8 or later, and Safari at minimum) to make sure color selections and page layouts are working as expected. Blinking text is not allowed, and the use of automatically running animations and flash slideshows should be minimized to avoid overwhelming visitors with pages that are unnecessarily busy.

For more information, refer to the document Style Guide & Coding Standards for CSS.


Comments

Comments may be used throughout the page using the normal <! -- ... --> convention. If the page contains embedded PHP code, specific rules for PHP comments apply; see Style Guide & Coding Standards for PHP for more information.

One comment is required in all pages which contains the date and author of the most recent revision. This comment should appear between the <html> and <head> tags as follows:


        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" > 

        <!-- Revised 3/19/2011, L.Pritchett -->

        <head>

        

If the header portion of the file is generated from a script, rather than being from a static HTML file, this comment must include the name of the script that generated the virtual page:


        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" > 

        <!-- virtual page generated by test.php, 3/19/2011 -->

        <head>
      
        

Page Elements

In addition to the DOCTYPE and character set definitions discussed in the section Overview above, several other elements are required in the head section. These are:


          <meta name="keywords" content=" ... " />

          <meta name="description" content=" ... " />

          <title>[site name]: [page name] />

          <link rel="shortcut icon" href="/favicon.ico" />
        

In addition, most pages also require this:


          <link rel="stylesheet" href="[location and name].css" type="text/css" />

        

Finally, although not required, we suggest including code that detects old browsers such as IE6 and Netscape and displays a message encouraging the user to upgrade to a more modern browser.

Layers and blocks that are defined by <div> tags must be indented following conventions described in Blocks above. If the block is to be manipulated dynamically, it must include an id value. All such values are prefixed with div to make tracking of page elements easier, and these IDs should be named to clearly represent their purpose. References to styles must be through class names; styles are never defined in terms of id values.

Example:


          <div id="divError_Msg" class="font_error">
            stuff in here that is normally hidden, but may be enabled by
             the appropriate Javascript validation function
          <div>

        

If <div> elements are self-contained (include background images, buttons, etc. defined in CSS, but no explicit contents in the HTML page itself), the </div> tag must appear on the next line by itself. This is done to be consistent with indenting rules and to avoid the appearance of an unfinished tag.

Example:


          <div class="box_logo">
          </div>
    
        

Similarly, if external scripts are referenced, the closing </script> tag should be on the next line.

Example:


    <script language="text/javascript" src="/Scripts/validation.js">
    </script>

        

Note that if hidden layers are used to display error messages (in preference to pop-up windows or alert boxes), the displayed page may shift and reorganize itself when the layer is displayed, particularly if the layer is inside a table. When this effect is severe or objectionable, a corresponding active layer may be used to occupy the same amount of space which is toggled off as the normally hidden layer is toggled on.

All tables must include a meaningful summary value to meet accessibility requirements.

The text contained in a clickable link should be as meaningful as possible. This means generally avoiding click this and similarly worded links. This allows search engines such as Google to get more meaningful information about what the link really references.


Form Elements

Form elements, which include text boxes, checkboxes, radio buttons, and drop-down lists, are usually validated by Javascript functions, and therefore must have id values defined. In addition, in order to pass these values back to the server as POST or GET calls, these elements must have defined name values. Exceptions to this are submit, cancel, or reset buttons, which do not need to be sent to the server.

Hidden form elements, when used, should appear immediately below the <form> tag before other dynamic elements are defined.

All name and id values are prefixed with 1- to 3-letter prefixes to indicate what type of values they are. These codes are:

          frm               [form element]
          bttn              [button element]
          r                 [radio button element]

          s                 [string values]
          i                 [integer values]
          f                 [floating point values]
          b                 [Boolean values]
        

Note that <text>, <textarea>, and <select> elements are considered to be strings (using prefix s), unless a numeric value is expected.

Example:


    <form id="frmLogin" method="post" action="process_login.php"
     onsubmit="return fnValidation_Form()">
      first name:
      <input type="text" name="sFirstName" id="sFirstName" length="20" />
      <br />
      last name:
      <input type="text" name="sLastName" id="sLastName" length="20" />
      <br />
      gender:
      <input type="radio" name="rGender" id="rGender_Male" value="M" /> male
      <input type="radio" name="rGender" id="rGender_Female" value="F" /> female
      <br />
      age:
      <input type="text" name="iAge" id="iAge" size="2" maxlength="3"
       onchange="fnKey_Pressed(this)" />
      <br />
      <input type="submit" value="Continue ..." />
    </form>

        

Images

Graphics that are dynamically hidden and exposed or dynamically replaced by Javascript code must include an id value which is prefixed with img. In addition, all graphics must include an alt value to meet accessibility standards.

Example:


          <img src="/Graphics/site_logo_110x400_color.png" alt="site logo"
           id="imgLogo" />

        

Graphic files should be in PNG or JPEG formats (with file name extensions of .png and .jpeg/.jpg, respectively). Generally file sizes should be no larger than 40KB for reasonable download performance, and resolutions should be adjusted to 75 dpi. Graphics which require hard edges and text (such as scientific graphs) should use the PNG format. The JPEG format should be reserved for photos and other graphics that need more color options but that do not suffer from the JPEG lossy compression algorithm.

Browser resizing of images should be avoided if possible; if specific sizes are required, they should be generated as static graphical files. One exception to this rule is if the graphic is from another site and storing a local copy is not a good idea; two examples of this circumstance is inclusion of gravatars and SSL certificate seals.

If the page is delivered over a secure (https://) connection, all included graphics also must be delivered from https sources. Mixed references to to secure and non-secure resources will cause most modern browsers to complain. The lock icon on the browser must be completely closed to indicate all elements of the page are fully secured.


Google Analytics

All publicly accessible pages hosted on our servers are tracked by Google Analytics. This is accomplished by means of a small snippet of code located in the <head> section of the pages. Usually this code is automatically included as part of the site's page templates. Note that we have reformatted the code to conform to our local standards for Javascript. The code looks like this:


      <head>
      ...

      <script type="text/javascript">
        // Google analytics tracker

        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-xxxxxxxx-x']);
        _gaq.push(['_trackPageview']);
    
        (function()
        {
          var ga = document.createElement('script');
          ga.type = 'text/javascript';
          ga.async = true;
          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 
           'http://www') + '.google-analytics.com/ga.js';
          var s = document.getElementsByTagName('script')[0];
          s.parentNode.insertBefore(ga, s);
        })();
      </script>

      ...
      </head>

        

Sample Code

The following is an example of a typical Web page demonstrating all major expected HTML components for pages developed at Cliffson Solutions, LLC.


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" >

    <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8" />

      <meta name="keywords" content="Cliffson,'Cliffson Solutions',
       Reno,Nevada,'Web hosting','software development',programming,
       'custom Web design','custom business applications','custom Web databases',
       PHP,postgres" />
      <meta name="description" content="Cliffson Solutions, LLC, provides 
       affordable software solutions and customized Web site design, maintenance,
       and hosting for small and medium size businesses." />

      <title>Cliffson Solutions: User Registration</title>

      <link rel="shortcut icon" href="/favicon.ico" />

      <link rel="stylesheet" href="/Style/cliffson.css" type="text/css" />

      <script type="text/javascript" src="/Scripts/validation.js">
      </script>

      <script type="text/javascript">
        // Google analytics tracker

        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-20325301-1']);
        _gaq.push(['_trackPageview']);

        (function()
        {
          var ga = document.createElement('script');
          ga.type = 'text/javascript';
          ga.async = true;
          ga.src = ('https:' == document.location.protocol ? 'https://ssl' :
           'http://www') + '.google-analytics.com/ga.js';
          var s = document.getElementsByTagName('script')[0];
          s.parentNode.insertBefore(ga, s);
        })();
      </script>
    </head>

    <body>
    <div class="box_content_wrapper">
      <div class="box_banner">
        <a href="http://www.cliffson.com/">
        <img src="/Graphics/cliffson_logo_full_border.png"
         alt="Cliffson Solutions logo" border="0" /></a>
      </div>

      <div class="box_content">
        <h2>User Registration</h2>
        <br />
        <form id="frmLogin" method="post" action="process_login.php"
         onsubmit="return fnValidation_Form()">
          first name:
          <input type="text" name="sFirstName" id="sFirstName" length="20" />
          <br />
          last name:
          <input type="text" name="sLastName" id="sLastName" length="20" />
          <br />
          gender:
          <input type="radio" name="rGender" id="rGender_Male" value="M" /> male
          <input type="radio" name="rGender" id="rGender_Female" value="F" /> female
          <br />
          age:
          <input type="text" name="iAge" id="iAge" size="2" maxlength="3"
           onchange="fnKey_Pressed(this)" />
          <br />
          <input type="submit" value="Continue ..." />
        </form>
      </div>

      <div class="box_footer">
        <div class="box_copyright">
          &copy; 2011,
          <br />
        </div>
      </div>
    </div>

    </body>
    </html>