Vol. 1: HTML5
Introduction
What is HTML5?
HTML5 is an umbrella term that refers to the latest living standard of HTML, maintained by WHATWG; as well as to a series of modern web technologies standards, such as the the DOM standard, the compatibility standard, or the fetch standard, among many others.
Background
HTML, or Hypertext Markup Language, is the World Wide Web's core markup language. First developed to write scientific documents at CERN in 1990, HTML now is a fundamental tool in how the World Wide Web operates and how internet browsers —such as Chrome, Safari, or Firefox— read and display content.
Due to the collaborative and open source nature of HTML5 and the WHATWG project, HTML can be seen as inconsistent —which is a factually true statement—, and in this document we will try to help the Author overcome this inconvenience by providing a clear and consistent structure across the whole text. Also it is worth to add the adaptive nature of this declarative language, in which not only the standard was law, but also user behaviour forced browsers many times in the past to accept or recognize blatant syntax errors that were committed too often.
Audience
This book is intended to be used as a auditing guide of HTML5 best practices for consultants, freelancers, and agencies, that work in the area of web development. Clients often have a myriad of legacy systems, often poorly maintained, that don't follow the latest HTML5 practices and that would greatly benefit from it. This handbook is designed to be framework agnostic, as the auditing process must evaluate the end HTML document and DOM created by the browser, not the actual original code — which might be written in plain React, Vue, or any other framework. Chapters 2, 3, and 4 are mainly dedicated to best practices and advice on multiple topics that conform the HTML living standard. Chapters 5, 6 and 7 are specially focused on recognizing bad practices quickly, auditing an HTML document, and coming up with improvements for maintainability, compatibility, accessibility and SEO.
Extensibility
HTML allows the user to extend semantics and elements beyond the living standard, via the class attribute, custom elements, or using custom metadata content. Users have several tools for accessing data with HTML, such with data-*=""
attributes, using <script type="">
, or via microdata using itemscope=""
and temprop=""
attributes. Authors can also extend APIs using JavaScript.
This means than in practice there are infinite possibilities in how to structure and organize an HTML document. However, that one can structure HTML as they wish, doesn't mean that one should. And that is exactly why this handbook exists.
Document Structure
A basic HTML document looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Sample page</title>
</head>
<body>
<h1>Sample page</h1>
<p>This is a <a href="demo.html">simple</a> sample.</p>
<!-- this is a comment -->
</body>
</html>
Note: <!DOCTYPE html>
does not represent an element, but a "DocumentType" node.
HTML documents consist of a tree of elements and text. Each element is denoted in the source by a start tag and an end tag. The above example contains a number of semantic elements ( <head>, <body>, <title>, <h1>
, and <a>
) which helps crawlers and text-assisted devices understand the meaning and structure of the content displayed. Certain elements are mandatory for any HTML document, such as <head>
and <body>
. The <html>
element, which is the root element that contains the entire document, can be omitted. This is, however, not recommended, since it contains the language attribute. You should always include the <html>
element in your document.
Tags have to be nested such that elements are all completely within each other, without overlapping:
<p>This is <em>very <strong>wrong</em>!</strong></p>
<p>This <em>is <strong>correct</strong>.</em></p>
Elements can have attributes, which control how the elements work. Attributes are placed inside the start tag, and consist of a name and a value, separated by an "=" character. The attribute value can remain unquoted if it doesn't contain whitespaces or ", ', `, =, <, or >. Regardless, you should always quote your attribute values.
The DOM
Web browsers then parse this markup from the HTML document, turning it into a DOM (Document Object Model) tree. A DOM tree is an in-memory representation of a document. The Document Object Model (DOM) is an API for manipulating DOM trees of HTML and XML documents. This API serves as a base for scripting on the web.
DOM trees contain several kinds of nodes, in particular a DocumentType node, Element nodes, Text nodes, Comment nodes, and in some cases ProcessingInstruction nodes. The markup snippet at the top of this section would be turned into the following DOM tree:
The document element of this tree is the html element, which is the element always found in that position in HTML documents. It contains two elements, head and body.
This DOM tree can be manipulated from scripts in the page. Scripts (typically in JavaScript) are small programs that can be embedded using the script element or using event handler content attributes. Each element in the DOM tree is represented by an object, and these objects have APIs so that they can be manipulated.
HTML documents represent a media-independent description of interactive content. HTML documents might be rendered to a screen, or through a speech synthesizer, or on a braille display. To influence exactly how such rendering takes place, authors can use a styling language such as CSS.
Similar to the DOM,the CSS Object Model (CSSOM) is a set of APIs that allow JavaScript to manipulate the CSS of a document, allowing users to read and modify CSS style dynamically.
HTML Conformance Checker: v.Nu
HTML conformance checkers, also called validators, are tools that help you catch unintended mistakes in HTML, CSS, and SVG. Running a conformance checker as a first audit layer is highly recommended, since they are a lightweight and easy tool to detect what otherwise would pass unnoticed. Of all conformance checkers v.Nu (Nu Html Checker) is the only one that supports up to date HTML5 consistently.
Authors can run v.Nu from the Official W3 Website, or locally downloading it from GitHub.
Security Basics
When HTML is used to create interactive sites, care needs to be taken to avoid introducing vulnerabilities through which attackers can compromise the integrity of the site itself or of the site's users.
Origins
The security model of the web is based on the concept of "origins", and correspondingly many of the potential attacks on the web involve cross-origin actions. Origins determine which content can interact with which—a core mechanism to stop malicious sites from accessing or messing with resources from other sites. An origin is, in the technical sense, a triple:
origin = (scheme, host, port)
Where:
- Scheme: The URI protocol (e.g. http, https, ftp)
- Host: The domain or IP (e.g. example.com, 192.0.2.5)
- Port: Explicit in the URL or the default for the scheme (80 for http, 443 for https)
Two resources are same origin only if all three parts match exactly. Therefore, only when all three match exactly can two resources be considered "same origin".
Same Origin Policy (SOP)
The same-origin policy is a critical security mechanism that restricts how a document or script loaded by one origin can interact with a resource from another origin. It helps isolate potentially malicious documents, reducing possible attack vectors. Under SOP, a script loaded from one origin can read or modify content only from resources with the exact same.
For example, it prevents a malicious website on the Internet from running JS in a browser to read data from a third-party webmail service (which the user is signed into) or a company intranet (which is protected from direct access by the attacker by not having a public IP address) and relaying that data to the attacker.
Cross-site scripting (XSS)
Untrusted input (comments, URL parameters, third-party messages, etc.) must be validated before use and escaped before display. Without this, attackers could inject fake data, run malicious scripts on every page view (spreading the attack), or even wipe server data. Validation should be safelist-based because blocklists can't anticipate all future attack methods.
Attackers can hide code in many ways, so safelist filters must be strict:
- Even for safe-looking elements like
<img>
, only allow specific attributes. Otherwise attackers could useonload
to run JS scripts. - If you accept URLs (e.g., in links), allow only specific schemes. Schemes like
javascript:
(and other custom ones) can execute malicious code. - Block
<base>
. Don't allow users to insert a<base>
element.<base>
elements rewrite how relative URLs resolve, letting attackers hijack<script src>
and redirect<form action>
to a hostile site.
Cross-site request forgery (CSRF)
If your site lets logged-in users do state-changing actions (post, purchase, apply, etc.), another site can trick them into submitting those actions unknowingly (classic CSRF). HTML forms can submit to other origins, so a malicious page can auto-submit a form to your site using the victim's session.
An author should:
- Include user-specific hidden tokens in forms and validate them server-side.
- Check the
origin
header on state-changing requests; reject when it's missing or doesn't match your site.
Clickjacking
A hostile site can embed your page in an iframe and trick users into clicking your controls (e.g., via a reaction game that moves the hidden iframe under the cursor). This makes users perform actions they didn't intend. Any page that lets users perform actions they might not want to (purchases, settings changes, admin actions, etc.).
If your page isn't meant to run in a frame, only enable the UI when you detect you're not framed (e.g., check window === top
before activating controls).
Common pitfalls with APIs
JavaScript in browsers runs with run-to-completion semantics: once a script starts, nothing else (no new events, no further parsing) happens until it finishes. Meanwhile, HTML parsing is incremental and can pause to execute scripts, then resume. The consequence is timing: if you attach event handlers too late, an event could have already fired. To avoid missed events, either define handlers inline via HTML event attributes (so they exist as the element is parsed) or create the element and attach its handlers within the same synchronous script—because scripts run to completion, no events can slip in before your handler is registered.
Syntax Errors
HTML syntax is deliberately constrained to prevent unintuitive DOM results, reduce ambiguity, and keep implementations interoperable. Parsers may halt on errors rather than performing convoluted recovery; constructs whose recovery behavior breaks streaming parsers are simply invalid. The spec also avoids situations that would force XML-based tools to coerce the HTML infoset, preserving consistency across processing models.
Rules prohibit patterns that cause disproportionate performance costs, rely on fragile historical quirks, or trigger known interoperability bugs in legacy user agents. Some restrictions exist purely for security (e.g., preventing encodings or patterns tied to XSS). Ambiguous markup, likely typos, and forms that could collide with future syntax are treated as errors to improve maintainability and forward-compatibility. For authors who prefer stricter discipline, conformance checkers can enforce conventions like always quoting attributes and including optional tags.
Beyond raw syntax, the spec restricts element content models and attribute values to preserve clear semantics. It forbids nesting or role combinations that contradict the elements' meanings, and blocks combinations whose default rendering or behavior would confuse users (for example, nesting interactive controls inside each other). These constraints steer authors toward structures that match the language's intent and users' expectations.
Additional limits exist to reduce author confusion and debugging pain: boolean attributes must be used correctly; duplicate IDs and similar pitfalls are disallowed because they lead to subtle script failures; and patterns with misleading parser behavior are flagged so authors don't waste time chasing non-issues. Some rules simply simplify the language—removing redundant synonyms or edge cases—so it's easier to learn and teach.
Finally, to ease HTML↔XML migration, certain attributes and namespace rules are constrained so documents behave similarly in both serializations. The spec also reserves parts of the language for future expansion and aligns with other standards (e.g., requiring valid media queries), ensuring today's documents won't block tomorrow's features and remain consistent with the broader web platform.
Structure and Semantics
Semantic HTML
HTML is semantic by design. One of the reasons why W3C recommends the use of HTML to display content on the internet—instead of using another markup language, e.g., XML— is that HTML excels at semantic structure. Every element in HTML is designed with meaning in mind, to give crawlers and browsers the necessary information about what the content of an element is.
To understand this, let's use as an example the most well known accessibility attribute, alt="This is an alternate description of an image."
, that specifies an alternate text for an image. Most authors and auditors are familiar with the fact that crawlers care a lot about this attribute, and that it is critical for SEO and accessibility. The reason is simple: Without the alt=" "
attribute crawlers cannot "see" how the image looks like. However few are aware that this same logic applies for most content present in your HTML, as crawlers and text-reading devices would like to know what is the structure and the meaning of the content of the document.
Thus, a code with proper semantics is not only easier to read and maintain, but it also improves your on-page SEO and accessibility, which are critical for ranking in search engine results.
Structure and Layouts
As we saw under the Document Structure section, a HTML document includes a document type declaration and a <html>
element at root, which contains nested on it the document head and document body. The head of the document is not visible to the viewer, but it is crucial, as it contains all the metadata, as well as icons for the browser tab and mobile home screen shortcut, and the behavior and styling of the content. We will cover all of the elements that can be nested inside the <head>
element under the Metadata section.
The visible content of the document is located in the <body>
. From this point onwards, HTML lets the user have complete freedom upon the structure of the visible content. One could, if desired, fill the content of the <body>
element with a long incomprehensible list of nested <div>
elements. This is, however, highly undesirable, as it gives no information about the meaning and structure of the content to the crawlers and accessibility devices.
More often than not, the nested elements inside <body>
are very well defined. One can normally find at least these three elements nested inside:
- A
<header>
element on top - A
<main>
element in the middle - A
<footer>
element at the bottom

The standard layout
There should be only one <main>
element per page, and every document should contain this element. As its name suggests <main>
identifies the main content of the document, and it is crucial for semantic purposes.
The site header is the <header>
element. The content of <header>
tends to often remain static across multiple pages, carrying most of the time the main navigation links and crucial site information.
Lastly, the site footer is the <footer>
element; which content remains most of the time static across multiple pages, often carrying the navigation links and site information that are not present in the header site.
When nested inside <body>
, all of these three elements are landmarks. Landmarks are special nodes in the AOM that carry semantic meaning and give out key information about the structure of the document. They are indispensable for accessibility. We will dive deeper in what landmarks are and what is the AOM in the section The AOM .
Note: The <header>
and <footer>
elements are not always landmarks. More information about the <main>
, <header>
, and <footer>
elements can be found in Sections.
As we just stated, nested inside the <body>
element we must always find the <main>
section, which contains most of the content, as well as a number of other sections. Together they form the layout of the page.
There are many different layouts, but for most websites the standard layout involves a <header>
, a <main>
, and a <footer>
elements nested inside <body>
. This layout provides a clean and simple structure, perfect for mobile screens and scrolling down. However, for very content heavy sites like blogs or newspapers, e-commerce shop pages, or dashboards pages in web apps, we tend to see more often the holy grail layout, or a variation of it. This layout typically consists of:
- A
<header>
element on top - A
<nav>
element on one side - A
<main>
element in the middle - A
<aside>
element on the other side - A
<footer>
element at the bottom

The holy-grail layout
The <nav>
element identifies content as navigation. When <nav>
nested in the <body>
or in the site heading, it is the main navigation for the site. If it was nested in an <article>
or <section>
, it would be internal navigation for that section only.
The <aside>
element is for content that is indirectly or tangentially related to the document's main content. It is specially common on content-heavy sites, like blogs or newspapers.
For styling purposes we will often find in this layout the <main>
, <nav>
and <aside>
elements wrapped inside the same <div>
element. This, however, doesn't have a negative impact on the SEO nor the semantics of the document.
Sections
According to the English Cambridge Dictionary, a section is one of the parts that something is divided into. We can section the content of the document to structure it in a way that is easier to read, maintain, and with proper semantics.
An example of a properly section structured document is the following:
<body>
<header>
<h1>This is the Page Title of the Document with Good Structure </h1>
<nav>
</nav>
</header>
<main>
<header>
<h2>This is the Content Title </h2>
</header>
<section id="intro">
<h3>This is the header of a section "intro". </h3>
</section>
<section id="about">
<h3>This is the header of the section "about". </h3>
</section>
<section id="cards">
<h3>This is the header of the section "cards". </h3>
<h4>Hey! This is a a subheader. </h4>
</section>
<section id="feedback">
<h3>This is the header of the section "feedback". </h3>
</section>
</main>
<footer>
<h2>Delivering accessible, performant, standards-compliant websites since 2023. </h2>
</footer>
</body>
Section headings
The <h1>
to <h6>
HTML elements represent six levels of section headings. <h1>
is the highest section level and <h6>
is the lowest. By default, all heading elements create a block-level box in the layout, starting on a new line and taking up the full width available in their containing block. While using multiple <h1>
elements on one page is allowed by the HTML standard (as long as they are not nested), this is not considered a best practice. A page should have a single <h1>
element that describes the content of the page.
A common navigation technique for users of screen reading software is to quickly jump from heading to heading in order to determine the content of the page. Because of this, it is important to not skip one or more heading levels.
<h1>Heading level 1</h1>
<h2>Heading level 2</h2>
<h3>Heading level 3</h3>
Headings may be nested as subsections to reflect the organization of the content of the page. Most screen readers can also generate an ordered list of all the headings on a page, which can help a person quickly determine the content hierarchy and navigate to different headings. Another example with heading nesting is the following:
<h1>Beetles</h1>
<h2>Etymology</h2>
<h2>Distribution and Diversity</h2>
<h2>Evolution</h2>
<h3>Late Paleozoic</h3>
<h3>Jurassic</h3>
<h3>Cretaceous</h3>
<h3>Cenozoic</h3>
<h2>External Morphology</h2>
<h3>Head</h3>
<h4>Mouthparts</h4>
<h3>Thorax</h3>
<h4>Prothorax</h4>
<h4>Pterothorax</h4>
<h3>Legs</h3>
<h3>Wings</h3>
<h3>Abdomen</h3>
Structured Data
Structured data is information organized in a consistent, machine-readable format. On the web, structured data makes content understandable not just for humans, but also for software such as search engines and crawlers.
Linked data is structured data which is associated with —linked to— other data, enabling semantic queries. By providing semantics, linked data allows machines to interpret not only the content, but also the relationships between entities.
JSON LD
JSON-LD is a lightweight Linked Data format that is easy for humans to read and write. It is based on the already successful JSON format and provides a way to help JSON data interoperate at Web-scale. It is a decoupled, script-based format that doesn't clutter HTML document. JSON-LD is the most recommended and SEO-friendly way to structure data and provide with extra semantics to crawlers.
Microdata
Microdata is used to nest metadata within existing content on web pages. Search engines and web crawlers can extract and process microdata from a web page and use it to provide a richer browsing experience for users. microdata consists of a group of name-value pairs. The groups are called items, and each name-value pair is a property. Items and properties are represented by regular elements. Authors can create items using the itemscope
attribute, and add properties using the itemprop
attribute.
Nowadays the use of microdata is not recommended for purely SEO-purposes, and the use of JSON-LD is encouraged instead.
The AOM
The Accessibility Object Model, or AOM, is an accessibility tree based on the DOM tree semantics. It is used by accessibility APIs to provide a document representation that can be understood by text-assisted technologies. The AOM contains information on element properties and interactivity. There are four semantic properties in an accessibility tree object:
- Name
- Description
- Role
- State
The Accessibility Object Model (AOM) is still a work in progress that aims to incubate APIs that make it easier to express accessibility semantics and potentially allow read access to the computed accessibility tree. In this section we will present a limited overview of landmark roles, for more information about the AOM and an in-depth dive in AOM roles and states, see Volume 2.
Landmark roles are a category of ARIA roles that provide a way to identify the organization and structure of a web page in the AOM. By classifying and labeling sections of a page, structural information conveyed visually through layout is represented programmatically. Screen readers use landmark roles to provide keyboard navigation to important sections of a page. There are the following landmark roles:
- banner (
<header>
) - complementary (
<aside>
) - contentinfo (
<footer>
) - form (
<form>
) - main (
<main>
) - navigation (
<nav>
) - region (
<section>
) - search (
<search>
)
Some landmark roles are always automatically added by browsers, like the roles for <main>
, <nav>
, and <search>
. In the other cases the landmark role is only added when certain conditions are met. The <header>
and <footer>
elements are only landmarks when they are direct children of <body>
. The <aside>
element is only a landmark when it is used outside of <article>
or <section>
. <section>
, <article>
, and <form>
elements aren't landmarks unless they have an accessible name, in which case the role is automatically added by the browser.
<section role="region">
<p>This section is not a landmark in the AOM.</p>
</section>
<section aria-label="Section Name">
<p>This section is now a landmark with role="region" in the AOM.</p>
</section>
Note: Use landmarks sparingly. Too many landmark roles make it difficult for screen readers to understand the overall layout of the page.
On-Page SEO
TBA
HTML Elements and Syntax
Metadata
Metadata is a type of data that describes data. In an HTML document the metadata is located in the <head>
element. The different elements that can be used to add metadata to a document are <title>
, <meta>
, <link>
, and <base>
.
The <title>
element
The <title>
element defines the document's title that is shown in the browse and it only contains text. It is very important for SEO and traffic purposes.
The <meta>
element
The <meta>
element represents metadata that cannot be represented by other meta-related elements. The attributes in the <meta>
element define the type of metadata provided by this element.
charset
This attribute declares the document's character encoding. If the attribute is present, its value must be an ASCII case-insensitive match for the string "utf-8"
, because UTF-8 is the only valid encoding for HTML5 documents. If the charset
attribute is set, the <meta>
element is a charset declaration.
name
The name
and content
attributes are used together to provide document metadata in terms of name-value pairs, with the name
attribute giving the metadata name, and the content
attribute giving the value. If the name
attribute is set, the <meta>
element provides document-level metadata.
http-equiv
Defines a pragma directive, which are instructions for the browser for processing the document. If the http-equiv
attribute is set, the <meta>
element acts as a pragma directive.
content
This attribute contains the value for the http-equiv
or name
attribute, depending on which is used.
media
The media
attribute defines which media the theme color defined in the content
attribute should be applied to.
The <link>
element
<link>
links the document with external resources. Is is typically used to link to stylesheets, stablish the site icons, and many other things. We can use certain attributes to define the functionality of <link>
:
href
and hreflang
href
specifies the URL —absolute or relative— of the linked resource. hreflang
indicates the language of the linked resource and it is purely advisory.
rel
One of the key features of <link>
is the rel
attribute. rel
stands for "relationship", and it defines the relationship between the document and the linked external resource. You can find the full list of rel
values on MDN. The rel
keywords that are the most relevant for the <link>
element are:
stylesheet
- To import a style sheet.
icon
- To import an icon to represent the current document.
canonical
- To define the preferred URL for the current document.
alternate
- To define an alternate representation of the current document.
manifest
- To define a PWA manifest.
preload
- To order the browser to preemptively fetch and cache the target resource. It needs the
as
as attribute to correctly function. More information about theas
attribute and its keywords can be found at MDN.
media
This attribute specifies the media that the linked resource applies to. Its value must be a CSS media query.
sizes
This attribute defines the sizes of the icons for visual media contained in the resource. It must be present only if the rel contains a value of icon
.
The <base>
element
The <base>
element specifies the base URL to use for all relative URLs in a document. There can be only one <base>
element in a document, and it must have a have an href
attribute, a target
attribute, or both.
Boilerplate
<head>
<meta charset="utf-8" />
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Short description of the page" />
<link rel="stylesheet" href="css/styles.css" />
<link rel="icon" type="image/png" href="/images/favicon.png" />
<link rel="alternate" href="https://example.com/fr/" hreflang="fr-FR" />
<link rel="alternate" href="https://example.com/pt/" hreflang="pt-BR" />
<link rel="canonical" href="https://example.com/page" />
<link rel="manifest" href="/site.webmanifest" />
</head>
Content Sectioning
Sectioning Elements
In an HTML we can use certain elements to structure the content into different sections. Those elements are <section>
, <article>
, <nav>
, and <aside>
elements.
<section>
The <section>
element is used to encompass generic standalone sections of a document when there is no more specific semantic element to use. Sections should always have a heading, with very few exceptions.
<article>
An <article>
represents a complete, or self-contained, section of content that is, in principle, independently reusable. Think of an article as you would an article in a newspaper or a post in a blog.
<nav>
The <nav>
element represents a section of a page whose purpose is to provide navigation links. <nav>
can be used to create tables of contents, page breadcrumbs, or local and global navigation sections.
An example of a breadcrumb navigation is the following:
<nav aria-label="breadcrumbs">
<ol role="list">
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/learn">Learn</a>
</li>
<li>
<a href="/learn/html">Learn HTML!</a>
</li>
<li aria-current="page">
Navigation
</li>
</ol>
</nav>
<aside>
The <aside>
element represents a portion of a document whose content is only indirectly related to the document's main content. Asides are frequently presented as sidebars or call-out boxes.
Note: <main>
, <header>
and <footer>
are not sectioning elements, but sectioning related elements. Instead of creating sections, they provide structuring information about the content of the element they are nested in.
Sectioning Root Elements
Root sectioning elements are elements that creates an independent outline. Those include <body>
, <figure>
, and <blockquote>
.
<body>
is an unique element that represents the content of the document. Every document must contain it, and it must be always unique, and direct child of <html>
.
<header>
represents self-contained content, with an optional caption which is specified using the <figcaption>
element.
<blockquote>
is the block quotation element. Other quotation elements can be found under Text Content.
Sectioning-Related Elements
To add even more confusion to HTML5 syntax, there are a set of elements that technically are not sectioning elements, but in practice they behave very similarly. Those elements are <main>
, <header>
, <footer>
, and <address>
.
<main>
<main>
represents the dominant content of the <body>
of a document. A document mustn't have more than one <main>
element. <main>
doesn't contribute to the document's outline; therefore, it doesn't affect the DOM structure and is strictly informative.
<header>
The <header>
element represents introductory content, typically a group of introductory or navigational aids. It may contain some heading elements but also a logo, a search form, an author name, and other elements. When not nested within sectioning content or <main>
, then the <header>
element automatically adopts the banner
landmark role. Otherwise, when nested within said elements, it loses its landmark status and represents a group of introductory or navigational aids for the surrounding section.
<footer>
Similarly, the <footer>
element represents a footer for its nearest ancestor sectioning content or sectioning root element. It typically contains information about the author of the section, copyright data or links to related documents. When the nearest ancestor is the <body>
element the <footer>
applies to the whole page and it is considered a landmark.
<address>
<address>
indicates that the enclosed HTML provides contact information for a person or people, or for an organization. It is advised to include information about the author in an <address>
element that can be included into the <footer>
element. The <address>
element should include the name of the person, people, or organization to which the contact information refers.
Text Content
Headings & Paragraphs
As previously seen in Section Headings, there are six section heading elements, with <h1>
being most important and <h6>
the least.
Paragraphs are marked up with the <p>
tag.
Quotes & Citations
For quotes and citations the corresponding elements are <blockquote>
, <q>
, and <cite>
. <blockquote>
displays a quote which is its own block, whereas <q>
displays an inline quote. The <cite>
element displays a visible citation on screen; using instead the attribute cite
makes the citation only visible to crawlers.
Inline Text
HTML includes many elements that provide text semantics for documentation. Among others, the most important elements—that have not been previously discussed in this text— are <data>
, <time>
, <code>
, or <pre>
.
HTML Entities
A character reference is an escape sequence of characters that is used to represent another character in the rendered web page. Because HTML reserves certain characters, one must use character references, also called entities, to display them. The reserved HTML characters are <
, >
, and ©
, and their respective equivalent entities are <
, >
, and ©
.
Containers & Lists
Containers
<div>
<div>
is the generic container for flow content. It has no effect on the content or layout until styled in some way using CSS. It does not inherently represent anything. The <div>
element should be used only when no other semantic element is appropriate.
<span>
The <span>
element is a generic inline container for phrasing content, which does not inherently represent anything. It can be used to group elements for styling purposes (using class
or id
), or because they share attribute values. It should be used only when no other semantic element is appropriate. <span>
is very much like <div>
, but <span>
is a block-level element whereas a <span>
is an inline-level element.
Lists
HTML provides us with a few different ways to mark up lists. There are ordered lists, unordered lists, and description lists.
Unordered Lists
The <ul>
element is the parent element for unordered lists of items. The only children of a <ul>
are one or more <li>
list item elements.
Ordered Lists
The <ol>
element is the parent element for ordered lists of items. The only children of an <ol>
are one or more <li>
elements, or list items. The "bullets" in this case, though, are numbers of a multitude of types. The type can be defined in CSS with the list-style-type
property or with the type
attribute. The <ol>
has three element-specific attributes: type
, reversed
, and start
.
Description Lists
A description list consist of a <dl>
element containing a series of description terms (<dt>
) and their description details (<dd>
). They are made up of key/value pairs, with <dl>
being the parent container of <dt>
and <dd>
.
Links
Links represent a connection between two resources, one of which is the current document. Links can be created by <a>
, <link>
, <area>
, and <form>
. This section will only cover the <a>
element in depth.
The <a>
element creates a hyperlink to a given web address via URL. While not required, the href
attribute is found in almost all <a>
tags.
The href
attribute can link to any URL schema supported by modern browsers, including tel:
, mailto:
, and sms:
. It can also link to other elements of the document using #
followed by the id
attribute of said element. For accessibility purposes authors can use a hreflang
element to indicate to screen-read devices the language of the linked URL.
<a href="https://docs.jbroldan.dev">Access my documentation webpage! </a>
<a href="#links">Links section. </a>
<a href="https://docs.jbroldan.dev/volume-1/#links">Links section. </a>
<a href="mailto:contact@jbroldan.dev">Email Me</a>
<a href="tel:8005551212">Call Me</a>
The <a>
element allows a long list of other global attributes, from which one should highlight the download
, rel
, target
, type
and ping
attributes.
The download
attribute causes the browser to link to a downloadable resource. Using a filename
value gives a name to the downloaded resource; without it, the browser will suggest a filename/extension to the user.
The rel
attribute controls what kinds of links the link creates, defining the relationship between the current document and the resource linked to in the hyperlink. It is a valid attribute for any link element, but not all its possible values are allowed for every element. Differently from a class
name, which does not express semantics, the rel
attribute must express tokens that are semantically valid for both machines and humans. The rel
attribute is of extreme importance for metadata and routing in the HTML document. You can find the full list of rel
values on MDN. The rel
values that are the most relevant for the <a>
element are:
nofollow
- Indicates that the publisher does not endorse the referenced document. Spiders won't follow this link.
external
- Indicates that the link directs to an external URL.
prev
andnext
- Indicate that the links point to the previous and next document in a series.
alternate
- Indicates that the link follows an alternate representation of the current document.
The target
attribute tells the browser where to display the linked URL; it is an enumerated attribute that can take the following values:
_self
- Default value. Opens the new link in the current browser context.
_blank
- Opens the new link in a new browser page.
_parent
- Opens the parent browsing context of the current one.
_top
- Opens the topmost browsing context ancestor of the current one.
_unfencedTop
- Allows embedded fenced frames to navigate the top-level frame.
The type
attribute can describe the linked URL content's format with a MIME type. It works as a filename extension for purely semantic purposes.
<a href="/es.pdf" hreflang="es-ES" rel="alternate" lang="es-ES" type="application/x-pdf" download="Manual-HTML5.pdf">Manual de HTML5 (pdf) </a>
Using the ping
attribute in a URL, authors track user interaction when the link is clicked. It includes a space-separated list of URLs. When the link is followed, the browser will send POST
requests with the body PING
to these URLs.
<link>
The <link>
element specifies relationships between the current document and an external resource. It is classified as a metadata content element. A further review of this element can be found under Metadata.
<area>
The <area>
element defines an area inside an image map that has predefined clickable areas. An image map allows geometric areas on an image to be associated with hypertext links. This element can only be used nested within a <map>
element. You can find more information about image maps in the Graphics section.
<form>
The <form>
element represents a document section containing interactive controls for submitting information. An in-depth review of the <form>
element and its attributes can be found under the Forms section.
Tables
Tables are used for displaying tabular data with rows and columns. The <table>
tag wraps the table content, including all the table elements. The implicit ARIA role of a <table>
is table; assistive technologies know this element is a table structure containing data arranged in rows and columns.
Inside the <table>
, you'll find the table headers (<thead>
), table bodies (<tbody>
), and, optionally, table footers (<tfoot>
). Each of these is made up of table rows (<tr>
). Rows contain table header (<th>
) and table data (<td>
) cells. In the DOM there are also two additional features: the table caption (<caption>
) and column groups (<colgroup>
). If the <colgroup>
has a span
attribute, it will contain table column (<col>
) elements.
The table's children are, in order:
<caption>
element<colgroup>
elements<thread>
elements<tbody>
elements<tfoot>
elements
<caption>
is the preferred method of giving a name to a table and it should be the first element nested in the <table>
element.
The content of tables is made up of up to three sections: zero or more table headers (<thread>
) , table bodies (<tbody>
), and table footers (<tfoot>
).
Each table row <tr>
contains one or more cells. If a cell is a header cell, use <th>
. Otherwise, use <td>
. The <th>
cell has semantic meaning, with implicit ARIA roles of columnheader or rowheader.
It is possible to join multiple cells into a single cell. The colspan
attribute is used to merge two or more adjacent cells within a single row. The rowspan
attribute is used to merge cells across rows, being placed on the cell in the top row.
The colgroup
element is used to define groups of columns, or col
elements, within a table. They allow for limited column styling.
An example code of a table is the following:
<table>
<caption>MLW Alumni</caption>
<thead>
<tr>
<th rowspan="2" id="name" scope="col">Name</th>
<th colspan="2" id="path">Career path</th>
<th rowspan="2" id="year">Year</th>
</tr>
<tr>
<th id="past" scope="col">Past</th>
<th id="future" scope="col">Destiny</th>
</tr>
</thead>
<tbody>
<tr>
<th id="hal" scope="row">Hal Gibrah</th>
<td headers="hal path past">Calculator</td>
<td headers="hal path future">Mars rover</td>
<td>2020</td>
</tr>
<tr>
<th id="cathy" scope="row">Cathy Terr</th>
<td headers="cathy path past">Waste disposal</td>
<td headers="cathy path future">Automated teller</td>
<td>2018</td>
</tr>
<tr>
<th id="lou" scope="row">Lou Minious</th>
<td headers="lou path past">Lightbulb</td>
<td headers="lou path future">Smart bulb</td>
<td>1956</td>
</tr>
</tbody>
</table>
Forms
The <form>
element represents a document section containing interactive controls for submitting information. Nested in a <form>
you'll find all the interactive (and non-interactive) form controls that make it up.
Forms are submitted when the user activates a submit button nested within the form. When using <input>
for buttons, the 'value' is the button's label, and is displayed in the button. When using <button>
, the label is the text between the opening and closing <button>
tags.
Graphics
Decorative images, such as background gradients on buttons or background images on sections of content or the full page, are presentational and should be applied with CSS. When an image adds context to a document, it is content and should be embedded with HTML. The main method including images is the <img>
tag using the src
attribute —to reference the image resoult— and the alt
attribute to describe the image.
We can extend this functionality to multiple image sources —associated to media queries— with the srcset
attrbute, serving the most appropriate image file for each server request. This can also be done with the <picture>
element, along with source
children, which takes an <img>
as a default source.
<img src="images/eve.png" alt="Eve"
srcset="images/eve.png 400w, images/eve-xl.jpg 800w"
sizes="(max-width: 800px) 400px, 800px" />
To increase rendering performance and Content Layout Shift (CLS), the <img>
tag can include height
and width
attributes to set the image's aspect ratio, and the lazy
attribute enables lazy loading. HTML also supports the inclusion of SVG images using the <svg>
directly; if so, do include a role="img"
attribute.
Regarding the alt
attribute, it is important to not be redundant in the text value, and limit yourself to describe the image in a short and efficient manner. For decorative images the correct attribute value is alt=""
In order to provide a responsive HTML document, authors must adapt it to the most common viewport and screen resolutions. One way of doing this with images is to include multiple image sources with srcset
<picture>
element. The <picture>
element is a container element for multiple image options listed in an unlimited number of <source>
elements and a single required <img>
element.
The <source>
attributes include srcset
, sizes
, media
, width
, and height
. The browser considers each child <source>
element and choose the best match among them.
For performance considerations most images that do not need to be loaded quickly should be loaded using the value "lazy", this saves badwidth and CPU usage. Browsers start rendering HTML when it is received, making requests for assets when encountered. This means the browser is already rendering the HTML when it encounters the <img>
tag and makes the request. And images can take a while to load. By default, browsers don't reserve space for images other than the size required to render alt
text. In the past, to avoid CLS authors used to define a certain width
and height
in the <img>
tag, but this fell out of favor of CSS, since it is way less painful. Instead, the most effective way to circunvent CLS problems is by setting the aspect ratio of the image.
The <img>
element also supports crossorigin
, decoding
, referrerpolicy
, and fetchpriority
attributes.
Multimedia
Scripting & Styling
Other important HTML elements include <style>
or <script>
, among many others. A full list of all HTML elements can be found at MDN.
Templates & Custom Elements
Attributes
Attributes are names and name/value pairs appearing in the opening tag of an element, changing its behavior or providing metadata. Attributes are normally formed by a name and a value; values should always be quoted.
Boolean attributes
If a boolean attribute is present, it is always true, if it is absent, then it is false. The list of boolean attributes is the following:
- autofocus
- inert
- checked
- disabled
- required
- reversed
- allowfullscreen
- default
- loop
- autoplay
- controls
- muted
- readonly
- multiple
- selected
<input disabled>
<input disabled="disabled">
<input disabled="false"> <!-- still true! -->
<input disabled="0"> <!-- still true! -->
When toggling between true and false, add and remove the attribute altogether with JavaScript rather than toggling the value.
Enumerated attributes
Some attributes, called enumerated attributes, take on a finite set of states. Like boolean attributes, they have a default value if the attribute is present but the value is missing. Unlike boolean attributes, though, omitting the attribute doesn't mean it's false, and attributes aren't automatically "true" if present. In most cases with enumerated attributes, missing and invalid values are the same. For example, if the attribute
on an <input>
is missing, present but without a value, or has an invalid value, it defaults to text
.
Global attributes
Global attributes are attributes that can be set on any HTML element, including elements in the <head>
. There are more than 30 global attributes.
id
The global attribute id
is used to define a unique identifier for an element. Its value is a string with no spaces, and it should always be unique. Stick to a naming convention, as id
values are case sensitive.
If a href
attribute has as a value the id
of an element preceded by #
, then upon interacting with the hyperlink the page will scroll to the position of that element.
In CSS, you can target each section using an id
selector.
class
The class
attribute provides an additional way of targeting elements with CSS (and JavaScript), but serves no other purpose in HTML.
style
The style
attribute enables applying inline styles, which are styles applied to the single element on which the attribute is set. The style
attribute takes as its value CSS property value pairs, with the value's syntax being the same as the contents of a CSS style block: properties are followed by a colon, just like in CSS, and semicolons end each declaration, coming after the value. While style
is indeed a global attribute, using it is not recommended. Rather, define styles in a separate file or files. That said, it can come in handy during development to enable quick styling such as for testing purposes.
tabindex
The tabindex
attribute can be added to any element to enable it to receive focus. The tabindex
value defines whether it gets added to the tab order, and, optionally, into a non-default tabbing order. This attribute takes as its value an integer. A negative value (the convention is to use -1
) makes an element capable of receiving focus, such as via JavaScript, but does not add the element to the tabbing sequence. A tabindex value of 0
makes the element focusable and reachable via tabbing, adding it to the default tab order of the page in source code order. A value of 1
or more puts the element into a prioritized focus sequence and is not recommended.
role
The role
attribute is part of the ARIA specification. As seen previously in The AOM it can be used to provide semantic meaning to content, enabling screen readers to inform site users of an object's expected user interaction. There are a few common UI widgets, such as comboboxes
, menubars
, tablists
, and treegrids
, that have no native HTML equivalent; in such cases, using the role
attribute can help the AOM of the document.
contenteditable
An element with the contenteditable
attribute set to true
is editable, is focusable, and is added to the tab order as if tabindex="0"
were set. Contenteditable
is an enumerated attribute supporting the values true
and false
, with a default value of inherit
if the attribute is not present or has an invalid value.
Custom attributes
You can create any custom attribute you want by adding the data-
prefix. While browsers won't implement default behaviors for any specific data-
prefixed attribute, there is a built-in dataset API to iterate through your custom attributes. Custom properties are an excellent way of communicating application-specific information via JavaScript. Add custom attributes to elements in the form of data-name
and access these through the DOM using dataset[name]
on the element in question.
You can use getAttribute()
using the full attribute name, or you can take advantage of the simpler dataset
property. The dataset
property returns a DOMStringMap
object of each element's data-
attributes. There are several custom attributes on the <blockquote>
.
User Interaction and Web APIs
TBA