HTML

Syntax

  • Use tabs rather than spaces to format the code as this enables the developer to set the indenting to their own preference.
  • Nested elements should be indented once (one tab).
  • Always use double quotes, never single quotes, on attributes.
  • Always include a trailing slash in self-closing elements.
  • Do not omit optional closing tags (eg. </li> or </body>).
  • Do not use an ID unless absolutely necessary to guarantee reuse on pages. IDs must be unique on a page.
<!DOCTYPE html>
<html>
	<head>
		<title>Page title</title>
	</head>
	<body>
		<img src="images/company-logo.png" decoding="async" width="..." height="..." alt="Company" />
		<h1 class="hello-world">Hello, world!</h1>
	</body>
</html>

HTML5 doctype

Enforce standards mode and more consistent rendering in every browser possible by including the doctype at the beginning of every HTML page.

<!DOCTYPE html>
<html>
	<head>
	</head>
	<body>
	</body>
</html>

Language attribute

Always include the language attribute. From the HTML5 spec:

Authors are encouraged to specify a lang attribute on the root html element, giving the document's language. This aids speech synthesis tools to determine what pronunciations to use, translation tools to determine what rules to use, and so forth.

Read more about the lang attribute in the spec and the possible language codes.

<html lang="en-us">
	<!-- ... -->
</html>

Character encoding

Always ensure that the web server is serving the HTML document with appropriate Content-Type header "text/html; charset=UTF-8" instead of specifying it as a meta tag within the document


Viewport

Always include a viewport meta tag, to ensure correct rendering across all sizes of devices set the viewport scale to be 1.

<meta name="viewport" content="width=device-width,initial-scale=1.0" />

IE compatibility mode

Internet Explorer supports the use of a document compatibility <meta> tag to specify what version of IE the page should be rendered as. Unless circumstances require otherwise, it's most useful to instruct IE to use the latest supported mode with edge mode.

<meta http-equiv="X-UA-Compatible" content="IE=Edge">

Canonical

Set the canonical tag on every page to ensure that they are only listed once in search engines no matter what protocol they are accessed through.

<link rel="canonical" href="./framework/" />

Including CSS and JavaScript

There is no need to specify a type when including CSS and JavaScript files as text/css and text/javascript are their respective defaults.

<!-- CSS -->
<link rel="stylesheet" href="framework.css" /><!-- JavaScript -->
<script src="framework.js"></script>

Attributes

Attribute order

HTML attributes should come in this particular order for easier reading of code.

  • class

  • id, name

  • data-*

  • src, for, type, href, value

  • role, aria-*

Classes make for great reusable components, so they come first. Ids are more specific and should be used sparingly (eg. for in-page bookmarks), so they come second.

<a class="..." id="..." data-toggle="o-modal" href="...">...</a><input class="form-control" type="text" /><img src="..." decoding="async" width="..." height="..." alt="..." />

Boolean attributes

Do not declare values for boolean attributes. XHTML required you to declare a value, but HTML5 has no such requirement.

<input type="text" disabled /><input type="checkbox" value="1" checked /><select>
	<option value="1" selected >1</option>
</select>

Markup

Reducing markup

Whenever possible, avoid superfluous parent elements when writing HTML. Many times this requires iteration and refactoring, but produces less HTML. Take the following example:

<!-- Ok -->
<span class="profile-image">
	<img src="..." decoding="async" width="..." height="..." alt="" />
</span><!-- Better -->
<img class="profile-image" src="..." decoding="async" width="..." height="..." alt="" />

Practicality over purity

Strive to maintain HTML standards and semantics, but not at the expense of practicality. Use the least amount of markup with the fewest intricacies whenever possible.

JavaScript generated markup

Writing markup in a JavaScript file makes the content harder to find, harder to edit, and less performant. Avoid it whenever possible.

Giving presentational elements semantic meaning

strong and em are semantic tags, meaning that they provide emphasis, which is rendered as bold/italic on a visual browser or in different speaking styles on a screen reader. Screen readers could pronounce STRONG and EM in a different voice or style.

Do not use the <i></i> and <b></b> presentational elements.

The em element represents stress emphasis of its contents:

<p>A paragraph with <em>emphasized text</em>.</p>

The strong element represents strong importance for its contents.

<p>A paragraph with some <strong>important text</strong>.</p>

Button type attribute

Always declare the type of a button explicitly, so that it gives clear context for the button by looking at the markup.

Possible values for the type attribute:

  • Submit - Submits form data to the server.
  • Reset - Reset values and controls to the default values.
  • Button - The button that triggers when an event occurs.
  • Menu - The button opens a popup menu.
<button type="submit">Submit</button>
<button type="reset">Reset</button>
<button type="button">Button</button>
<button type="menu" menu="popup-menu">Dropdown Menu</button>

Semantics

Semantic mark–up is HTML that describes the content, rather than the manner in which the content is presented. It allows the meaning to be delivered to users regardless of the browser they use, so that content can be provided to the widest possible audience.

Elements

All elements must be used appropriately for the content they contain. For example headings must be in a heading element and a list must be within the appropriate type of list element. Do not use elements for the presentational look that they will provide.

Attribute values

For attributes such as IDs and classes their values should be created so as to describe the content of the element and not how it will make them look. For example ‘error’ would be correct and ‘largeRed’ would be wrong.

Microdata

The Microdata specification was produced as part of the HTML5 specification and can also be used to add semantics to content. It is suggested to use the patterns available on https://schema.org/ for any Microdata included on a page.


Images

An HTML img element should be used to insert images that are integral to the content. Image elements must be self–closing and include a src attribute and an alt attribute. If the same visual presentation can be made using text alone, an image should not be used to present that text.

Text must only be used within an image for decoration (images must not convey content) OR when the information cannot be presented with text alone, in this case the alt attribute must be used. The alt attribute must be included in all img elements and provides alternative text to the image. This text should be an appropriate replacement of the image and not purely a description of what the image is.

Where images are for decoration only they should be background images instead of inline elements. These should be formed of image sprites wherever possible. For more information on this see the CSS guidelines.

Image maps must not be used unless the data and/or functionality they provide is replicated elsewhere on the page. However wherever possible we would recommend alternative methods of providing this type of behaviour.

The format of the image should be appropriate to the image being displayed and one of – GIF, JPEG or PNG. When choosing an appropriate format special care must be taken with the file size of the image. This should be minimised as far as possible without degrading the quality of the image significantly.


Forms

It is recommend the following coding practices to improve the accessibility and usability of forms.

Labels and inputs

The label and input elements should be used appropriately and associated with each other by using the for and id attributes. A basic example of this would be:

<label for="answer1">Answer 1</label><input type="text" id="answer1" />

When using multiple inputs for something such as a date ensure that each input has a corresponding label. These can then be hidden using CSS by positioning off the screen, do not set display:none on them.

Fieldset and legend

The fieldset element should be used to group together thematically related controls and labels. Grouping controls makes it easier for users to understand their purpose while simultaneously facilitating tabbing navigation for visual user agents and speech navigation for speech–oriented user agents.

If a fieldset is declared, the legend element must appear immediately after the opening fieldset tag and be used as the caption for the fieldset.

Input changes

When a user inputs information or interacts with a control, it must not result in a substantial change to the page, the spawning of a pop–up window, an additional change of keyboard focus, or any other change that could confuse or disorient the user unless the user is informed of the change ahead of time.

Input types

Care should be taken when choosing input field types for various uses, particularly with regard to number entry, as making the wrong selection could prevent users from inputting the required details into a form. Basic details are listed below, and further information can be found on the MDN web docs site page.

<input type="number">

  • Does not stop entry beyond a maximum number (just highlights as invalid)
  • Does not support leading zeros (stripped off by some browsers, so unsuitable for telephone number, CVV or two-digit day/month entries)
  • Does not support spaces (cannot be used for visually formatting credit cards, telephone numbers, etc)
  • Numeric keyboard implementations vary and many do not correctly implement the specification's requirements for negative numbers and decimal points.

<input type="tel">

Should ONLY be used for telephone numbers; using this incorrectly for other number entries may produce a visually pleasing result but will leave code open to changes in how browsers interpret/support/validate entries of this type.

<input type="text">

  • Possible to control the maximum number of characters entered into the field
  • Possible to use regex patterns to help with validation of entries
  • Cannot control which keyboard is displayed (full / abbreviated / numeric) across touch devices. Keyboard types can be suggested for a few leading-edge browsers via the inputmode attribute, however it should be used with caution and should very much be considered as a progressive enhancement rather than being relied upon.

Error identification

Required form elements or form elements that require a specific format, value, or length provide this information within the element’s label (or if a label is not provided, within the element’s title attribute).

If utilized, form validation cues and errors (client–side or server–side) should alert users to errors in an efficient, intuitive, and accessible manner. The error should be clearly identified, quick access to the problematic element should be provided, and the user should be allowed to easily fix the error and resubmit the form.

Security

The level of security required for a form will depend on the data being accepted by it.


Tables

Tables must only be used to display tabular data and not for page layout. The incorrect use of tables presents accessibility problems, a table element tells the user–agent that the content is tabular data and it will interpret it as such to the user. Developers must use style sheets and meaningful mark up to control the layout of anything other than tabular data.

Caption and summary

The caption element should be used on each table to describe the nature of the table. When the caption element is included it must appear immediately after the opening table tag. The summary attribute should not be used unless the complexity of the table requires it, however in the case we would recommend simplifying the table rather than using a summary.

Table cells

Headers and general cell data must be distinguished using the appropriate th (table header) and td (table data) elements. Table header data can form columns or rows.

The scope attribute

The scope attribute should be used to explicitly associate a table header (th) element with a column or row.


iframes

iframes should not be used except where there is no other option (ie Third–party analytics code), although their use (and any possible alternatives to them) does depend on the exact situation they are being considered for. Here is a brief overview of why they should be avoided:

Accessibility
  • There is no fallback if the user’s browser cannot display iframes (this includes many mobile/tablet devices).
  • Many accessibility aids such as screen readers do not support iframes or cannot use them correctly leaving the user unable to use the website.
Usability
  • Where accessibility aids do support them they can still leave the page very difficult to use and confusing to the user.
  • iframes can break the browsers forward/back functionality.
  • Due to being a fixed size they cannot scale to the content being inserted into them potentially producing multiple scrollbars that can confuse the user and produces a maintenance risk and overhead where later changes can have unintended consequences.
Performance

iframes have a significant effect on page load speed slowing the rendering of the page considerably.

Security

There are also potential security issues to their use, such as cross domain exploits and cross–site–scripting. This risk must always be considered in their use.


Linting

There is a standardised set of HTML linting rules available to ensure that all code produced is consistently formatted.

For more information see the code linting documentation.


Editor preferences

Set your editor to the following settings to avoid common code inconsistencies and dirty diffs:

  • Use tabs rather than soft tabs.
  • Trim trailing white space on save.
  • Set encoding to UTF-8.
  • Add new line at end of files.