Skip to main content

HTML defines the structure and meaning of web content.

Introduction

By nature, HTML is a forgiving language that allows poorly written code to execute and render with varying levels of accuracy. That said, just because code visually renders does not mean that code is semantically correct or standards-compliant.

  • HTML should be valid
    • No deprecated or non-standard code
    • Elements that are no longer part of the HTML specification should be avoided
  • HTML should be standards-compliant
    • Controls the structure
    • Does not impact the presentation
    • Remains fully functional without CSS
    • Does not contain inline or internal styling or scripting
  • HTML should be semantic and accessible
    • Choose HTML elements based on the content structure
    • Use sectioning elements, heading elements, and content elements accordingly
    • Use ARIA to supplement HTML so that interactions and widgets commonly used in applications can be passed to assistive technologies when there is not otherwise a mechanism — do not use ARIA as a replacement for native semantic HTML
    • Never use the HTML table element for presentation — the table element should only be used for tabular data
    • Always use the HTML form element for sections requiring user input
  • HTML should be as meaningful and minimal as possible
    • Avoid superfluous parent elements, e.g.:
      Do <img src="..." class="docs-logo" />
      Don't <span class="docs-logo"> <img src="..." /> </span>

Semantics

HTML provides a number of semantic constructs that allow automated tools like search engines and screen readers to make sense of the document and to understand relationships between pieces of content. Use semantic HTML whenever possible — that is to say use elements with specific meanings for specific purposes to convey the spirit of the markup.

Semantic elements

  • The <header> element represents introductory content, typically a group of introductory or navigational aids. It may contain some heading elements, like a h1-h6, a logo, a search bar, etc.
  • The <footer> element typically contains information about the author of the section, copyright data or links to related documents
  • The <nav> element represents a section of a page whose purpose is to provide navigational links, either within the current document or to other documents
    • A document may have several nav elements, for example, one for primary site navigation and one for secondary intra-page navigation
    • It's not necessary for all links to be contained in a nav element. The nav element is intended only for major block of navigation links. For example, a footer will typically contain a list of links that don't actually need to be in a nav element
    • Using the nav element provides screen reader users with a shortcut key to jump to the navigation
  • The <main> element represents the dominant content of the body of a document
    • There should only be one main element per document
    • Content that is repeated across a set of documents or document sections, such as the site or application's logo, navigation links, sidebar, etc. should not be nested in the main element
    • Adding an ID attribute to the main element allows it to be the target of a skip link. Skip links allow users to skip large sections of repeated content — like navigation — without having to tab through it or listen to it, and jump directly to the main content of the page
  • The <article> element represents a self-contained composition in a document, page, application, or site, which is intended to be independently distributable or reusable
    • A document can have multiple article elements in it
    • Each article should contain a nested heading element. For example, on an infinitely scrolling blog, each post would be contained in an article element
  • The <aside> element is for content that's only indirectly related to the main content. Asides are frequently used for sidebars or call-out boxes
  • The <section> element represents a standalone section that doesn't have a more specific semantic element to represent it
    • Typically, but not always, each section should contain a nested heading element
    • The section element is not a generic container element. When an element is needed purely for styling or scripting, you should use the div element instead. A general rule of thumb is that the section element is appropriate if the element's contents should logically appear in the outline of a document
  • Heading elements represent six levels of section headings
    • <h1> is the highest section level and <h6> is the lowest
    • There must be one, and only one, h1 per page
    • The h1 must be subject of the page
  • The <p> element represents a paragraph. That said, HTML paragraphs can be any structural grouping of related content
    • Breaking up content into paragraphs helps make a page more accessible
    • Assistive technologies provide shortcuts that allow users to skip to the previous or next paragraphs
    • Using empty paragraph elements to add white space is problematic for people who navigate the web with assistive technology because a screen reader may announce the paragraph, but not any content...because there is none, which can confuse and frustrate the user
  • The <dl> element represents a description list
    • The element encloses a list of groups of terms (specified using the <dt> element) and descriptions (provided by <dd> elements)
    • Common uses for this element are to implement a glossary or to display metadata as a list of key-value/name-value pairs, e.g.: a contact card
  • The <small> element represents side-comments such as small print, independent of styled presentation
    • Common uses for this element are: copyright information, disclaimers, caveats, legal restrictions, or licensing requirements
    • Do not use the small element to control font size. Use a semantic element and style it with CSS instead
  • The <a> element creates a link to other web pages, files, locations within the same page, email addresses, or any other URL
    • Anchor elements are often abused with onclick events to create pseudo-buttons by setting the href attribute to "#" or the JavaScript void operator in order to prevent the page from refreshing. These values cause unexpected behavior when copying/dragging links, opening links in a new tab/window, bookmarking, and when JavaScript is still downloading, errors out, or is disabled. This also conveys incorrect semantics to assistive technologies. In these cases, it is recommended to use a button element instead
    • In general, links should take the user to another place (another page, another place on the same page, a new tab, etc.) and buttons should perform an action (open a menu, open a modal, manipulate content on a page, submit form data)
  • The <button> element represents a clickable button which can be used in forms or anywhere in a document that needs simple, standard button functionality
    • The button element is described as a button by assistive technologies, and it has built-in keyboard controls like tab to focus and return/enter to "click"
    • Technically speaking, you can create pseudo buttons by using the input element with a type of "button" (<input type="button">), but the button element is the recommended way to create buttons
  • The <form> element represents a document section that contains interactive controls for submitting information to a web server. Many assistive technologies and browser plugins recognize form elements and implement special hooks to make them easier to use
  • The <label> element provides identification for a specific form control based on the matching values of the form control's ID attribute and the label's for attribute
    • The label element is the most important element if you want to build accessible forms
    • When implemented properly, assistive technologies will announce a form element's label along with any related instructions, and the form element will receive focus when a user clicks on the label
    • Input elements with a type of "button" should not be associated with a label element. Adding a label to an input element with a type of "button" could interfere with how assistive technology parses the button input
    • Do not use the label element for strings of text. Use paragraph or heading elements instead
  • The <input> element is used to create interactive form controls
    • How an input works depends on the value of its type attribute
    • All input fields (except for input elements with a type of "button") should be associated with a label element
    • The value of the label's for attribute must contain the value of the corresponding input's ID attribute. Keep in mind that IDs are unique and can only be used once per page
    • When implemented properly, the input field will receive focus when a user clicks on the label, and assistive technologies will announce a form element's label along with any related instructions
    • Input elements with a type of "button" should not be associated with a label element. Adding a label to an input element with a type of "button" could interfere with how assistive technology parses the button input
  • The <select> element represents a control that provides a menu of options
  • The <textarea> element represents a multi-line plain-text form control where users can type free-form text
  • The <table> element represents tabular data
    • Tables provide important semantic association between row and column headers and data
    • Do not use the table element unless the data is actually tabular
  • The <img> element embeds an image into a document
    • The alt attribute defines an alternative text description (alt text) for the image
    • Alt text is displayed on the page if the image can't be loaded for some reason, e.g.: network errors, content blocking, etc.
    • Alt text is read aloud by screen readers in order to provide context for non-text content
    • When an image contains words that are important to understanding the content, the alt text should include those words. Note: it does not necessarily describe the visual characteristics of the image itself, but it must convey the same meaning as the image
    • If the image doesn’t contain anything of relevance, the alt attribute should still be included and the value should be an empty string so screen readers will ignore it rather than read the name of the image file
    • Setting the alt attribute to an empty string indicates that non-visual browsers may omit it from rendering. Visual browsers will also hide the broken image icon if the alt is empty and the image failed to display
    • If an image doesn’t have a meaningful value, consider using a CSS background image instead of an inline image element

Non-semantic elements

  • The <div> and <span> elements are a simple, generic containers
    • They do not inherently represent anything
    • They have no effect on the content or layout until styled using CSS
    • They should be viewed as a last resort, and used only when no other semantic element is appropriate
    • The div element should be used with grid systems for grid classes (containers, rows, and columns)
  • The &nbsp; character entity prevents text wrapping
    • Do not use the non-breaking space character entity. Use the CSS white-space property with a value of nowrap instead

Commonly misused elements

There are a number of HTML elements that are often misused for presentation.

  • The <br> element produces a line break in text
    • The line break element should only be used for line breaks that are part of the content and where the division of lines is impactful, like with addresses and poems
    • Using the line break element to create white space is not only bad practice, it is also problematic for users who navigate the web with assistive technologies
    • Do not use the line break element to create white space, separate paragraphs, or separate lines of text. Use paragraph elements with proper opening and closing tags instead
  • The <hr> element represents a thematic break between paragraph-level elements, e.g.: a scene change in a story, or a transition to another topic within a section of a reference book. Historically, it's been used as a horizontal rule or line. While it may still be displayed as a horizontal rule in visual browsers, this element is now defined in semantic terms, rather than presentational terms.
  • In earlier versions of the HTML specification, the <b>, <i>, and <u> elements were simply presentational elements used to display bold and italicized text. This is no longer true, and these elements now have semantic meaning. In most cases, another element is likely to be more appropriate. Read the HTML specification to determine if a semantic HTML element or CSS is the best solution.

Formatting

In order to increase readability, please adhere to the following formatting standards.

  • Use a new line for opening and closing tags
  • Use one level of indentation (2 spaces) for nested elements
  • Do not omit optional end tags
  • Do not omit trailing slashes for void elements
  • Include white space before the trailing slashes for void elements
  • Use a standard attribute order
  • Use double quotes to surround attribute values
  • Omit values for boolean attributes
  • Mark TODOs and action items with a TODO comment and a ticket number
  • Examples:
    • </body>
    • </li>
    • <input type="text" id="myInput" class="form-control" required />
    • <img src="logo.svg" alt="Logo" />
    • <!-- TODO: HTML action item -->

Organization

  • The order of the content in the source code should match the visual presentation of the content
    • Do not use tabindex as a way to make up for disorganized source code
  • HTML attributes should be written in a consistent order to reduce the risk of human error and increase the readability of code

Attribute order

HTML attributes should come in this particular order for easier reading of code. Classes make for great reusable components, so they come first. IDs are more specific and should be used sparingly (e.g., for in-page bookmarks), so they come second.

  • React-specific attributes and/or inputs
  • type
  • id
  • for, href, src
  • title, alt
  • class
  • name
  • value
  • role, aria-, data-

Additional resources