Skip to content

HTML

Whenever you are on a website like this one, you are viewing the result of code being parsed and rendered by your browser.

The browser primarily interprets code written in three languages: HTML, CSS, and JavaScript. We'll also include SVG, which is particularly useful for data visualization.

  • HTML is a markup language. It is designed to provide structure to text and other contents on a page. (menu, sidebar, images, paragraphs of text)
  • CSS is a declarative language which helps you associate different appearances with parts of your page whose structure is already defined by HTML. ("Links are blue", "Images have borders") As with other declarative languages (SQL, for example), we declare what we want, not how to do it.
  • JavaScript is a programming language that will feel more familiar to people who have written in languages like Python. It is often used to provide interactivity on a page. ("When this button is pressed, more data is loaded." or "Hovering over this element shows a tooltip.")
  • SVG is a tag-based language similar to HTML used for defining vector graphics. This is particularly relevant to data visualization.

What is HTML?

HTML (HyperText Markup Language) is the most important building block of the web. While CSS and JavaScript are important for most sites, it is possible to make a site that doesn't use them. The same can't be said of HTML; it is the foundation that the rest build upon.

HTML is, as the name implies, a markup language. Its original purpose was entirely to mark up or annotate text for display on the web, most notably with "hyperlinks" (now just called links) that allow inline references to other documents.

HTML documents consist of elements nested within one another. Elements are defined by tags which can have attributes. They can contain inner text and other elements.

HTML Syntax

Elements & Attributes

Each HTML element has:

  • tag name: div, em, span, a, head, etc.
  • attributes: these are the additional optional parameters seen within a tag (such as style= and href=)
  • inner text: content between the opening and closing tag (if applicable)

An element is a portion of the page, or metadata about the page.

"Void elements" like <br> exist on their own and do not contain other elements or text. As such they do not need a closing tag. See quick reference for other void elements.

Most elements, however, require a pair of opening and closing tags, for example:

<p>this is inner text</p>

Elements can nest inside one another as well:

<div>
  <p>this is an inner element</p>
  <p>so is this</p>
</div>

Attributes are placed inside the angled brackets like <tag attrib="val">. A tag can have multiple attributes separated by spaces:

<tagname attrib="val" attrib2="val2">

Whitespace is collapsed to a single space, so the same tag could be written as:

<tagname
  attrib="val"
  attrib2="val2"
>

There is also a special comment tag:

<!--
  text between these symbols is ignored
-->

We'll see that different elements serve different purposes and may have unique attributes, for example <img> which embeds an image expects src= and alt= attributes defining the path to the image and replacement text, respectively.

There are a few attributes that are common to all elements, the most common of them being:

  • id= - sets a unique identifier for this item, which can be referenced by CSS & JS.
  • style= - allows setting CSS for this specific element, used in examples on this page, but generally discouraged as we'll see in the CSS chapter.
  • class= - sets one or more non-unique identifiers, assigning this element to a collection which can be referenced by CSS & JS.

We'll revisit these when we discuss CSS.

See more:

Permissiveness

One of the most notable things about HTML compared to most languages is how it is permissive of omitted syntax or outright mistakes.

Most HTML was written by hand, and people would forget closing tags, use special characters, and nest tags in unorthodox ways.1

For this reason, browsers remain very permissive, inserting missing quotes/closing tags/etc as needed. Something will be displayed, even if the browser guesses your intention incorrectly and doesn't display what you wanted.

Escaping Entities

Some characters, like < and >, have special meaning in HTML.

To include these characters on a page, you can use character entities of the form: &lt; (for <) or &gt; (for >).

Page Structure

The nature of tag-based languages like HTML is that everything forms a tree.

When we get to the JavaScript chapter, we'll revisit this tree structure as the Document Object Model, or DOM.

Example

<section style="border: 1px dashed red;">
    <p>The &lt;p&gt; tag makes a paragraph, which ends when we see the &lt;/p&gt; tag.</p>
    <p>Each p tag will, by default, start a new paragraph, visually distinct from the rest.</p>
    <p>
      There are some tags that allow markup within text, such as <strong>strong</strong> or <em>emphasis</em>, which (by default) will make the text within bold or italic.  These tags are intended to have semantic meaning, text that is emphasized might be italicized on my screen
    </p>
</section>

The <p> tag makes a paragraph, which ends when we see the </p> tag.

Each p tag will, by default, start a new paragraph, visually distinct from the rest.

There are some tags that allow markup within text, such as strong or emphasis, which (by default) will make the text within bold or italic. These tags are intended to have semantic meaning, text that is emphasized might be italicized on my screen

For the bit of HTML in the above example, our tree would resemble

graph TD
section-->A[p];
section-->B[p];
section-->C[p];
A --> D["text node"]
B --> E["text node"]
C --> F["text node"]
C --> G[strong]
C --> H["text node"]
C --> I[em]
G --> K["text node"]
I --> Z["text node"]

On a full page, the tag at the root of the tree is named <html>. This tag typically contains two tags <head> and <body>:

<head> contains tags that link to CSS & JS files, as well as metadata. It does not contain content that will appear on the page. (not to be confused with heading tags like <h1>)

<body> contains the actual content that'll be shown on the page itself. So in practice a typical page has a structure like this.

graph TD
html-->head;
html-->body;
head-->S[style];
head-->link;
head-->script;
head-->title;
head-->meta;
body-->div;
body-->section;
body-->footer

Starter Template

A typical HTML page will start with a template resembling:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>
    name of page used in tabs / bookmarks
  </title>
</head>
<body>
  Visible content goes here.
</body>
</html>

Try copying this into a file named myfirst.html. Make edits in your text editor, and open the page in your browser to see how it affects the page. (Refresh in the browser to see updates reflected.)

The starting <!DOCTYPE html> is a special declaration which tells the browser we're using modern HTML (HTML5) and disables "quirks mode" which emulates old browser behaviors.

The meta tags describe arbitrary metadata, some of which provide hints to the browser about how to interpret the content.

For a full list of elements that can appear inside <head> see: MDN: Head element

Elements

Display Elements

The majority of a page, anything visible in the browser viewport, lives within the <body>.

There are two subcategories of these display elements:

  • block elements create distinct blocks on the page, pushing other content further down the page (by default)
  • inline elements annotate text within an existing element

Block Elements

Block elements create a distinct new part of the page, which will have a width and height determined by its contents & various CSS rules.

Some of the most common block elements are <p>, <h1>, <h2>, ... <h6>, <pre>, and <div>. See quick reference for more.

We try to favor the element with the closest semantic meaning to what we intend to live within that tag: a menu might be within a <nav> element, and consist of an unordered list of items <ul>, <li>.

When there is no clear match, <div> is used as a catch-all option for dividing a page up into smaller components.

Block Elements

<div style="display: grid;">
  <div style="border: 1px dashed green; margin-bottom: 2px;  grid-column: 1; ">
    <P style="border: 1px dotted red;">Div 1; Paragraph 1</p>
    <p style="border: 1px dotted red;">Div 1; Paragraph 2<br><br><br></p>
  </div>
  <div style="border: 1px dashed blue;  grid-column: 2;">
    <p style="border: 1px dotted red;">Div 2; Paragraph 1</p>
    <p style="border: 1px dotted red;">Div 2; Paragraph 2</p>
  </div>
</div>

Div 1; Paragraph 1

Div 1; Paragraph 2


Div 2; Paragraph 1

Div 2; Paragraph 2

The borders help you see how these block elements nest.

Inline Elements

Not all elements create a new block; elements like <em>, <strong>, and <a> can be used inline. There is also a generic <span> element that marks a span of text for styling, and similarly to <div>, has no inherent meaning.

Some of the most common inline elements are <a>, <em>, <strong>, and <span>. See quick reference for more.

Example

<div>
  This is a single div, within it there are multiple inline elements:
  <em>em</em>, 
  <strong>strong</strong>, 
  <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a">a (for links)</a>, 
  and a <span style="color: green; border: 3px dotted orange;">span, with some styling added for demonstration</span>.
</div>

This is a single div, within it there are multiple inline elements: em, strong, a (for links), and a span, with some styling added for demonstration.

A particularly important element is the <a> tag which is used to make links. The HT in HTML stands for Hypertext, coined to describe documents that linked to one another as we just did there.

The <a> tag is used to create links to other pages, or parts of pages:

<a href="https://example.com/">
   creates a link to another page
</a>

<a href="/elsewhere-on-site/">
   without protocol, creates a link to other pages on same domain
</a>

<a href="#fragment">
   Link to a named portion of the current page.
</a>

<a href="/other-page/#fragment">
   Link to a named portion of another page.
</a>


<h3 id="fragment">
  the above link would link to this item, using its id
</h3>

Form / Input Elements

In addition to the elements discussed above there are elements meant to take user input.

In a traditional web application those would exist inside of a <form> which indicates how clicking a submit button would transmit the filled information to a backend server. When you log in to a website, you are filling out an HTML <form> and submitting it.

For an interactive visualization, we might include form elements and override their default behavior using JavaScript. We'll cover events in JavaScript eventually, but for now, let's look at a few of the HTML form elements:

Example

Text Input: <input type="text" placeholder="this text shows up until typing begins">

<br>

Range Input
<input
  type="range"
  min="0"
  max="100"
  step="1"
  value="50" />

<br>

Select (dropdown):
<select>
  <option>Red</option>
  <option>Blue</option>
  <option>Green</option>
</select>

<br>

Multiselect:
<select multiple>
  <option>Red</option>
  <option>Blue</option>
  <option>Green</option>
</select>

Text Input:


Range Input


Select (dropdown):


Multiselect:

See more:

Element Quick Reference

Tag Kind Purpose
<html> structure Root of the page; contains <head> and <body>
<head> structure Metadata and links to CSS/JS; not displayed
<body> structure All visible content
<title> structure Page name shown in tabs and bookmarks, in <head>
<meta> void Metadata, in <head>
<link> void Link to external CSS, in <head>
<script> structure Link to external JavaScript, in <head>
<h1>-<h6> block Hierarchical headings
<p> block Paragraph of text
<div> block Generic container with no meaning
<header>, <nav>, <main>, <section>, <footer> block Named regions of the page. No special styling.
<ul>, <ol>, <li> block Bulleted list, numbered list, and list item
<dl>, <dt>, <dd> block Dictionary/Description list: a term and its details
<table>, <tr>, <th>, <td> block Table, row, header cell, and data cell
<pre> block Preformatted text; whitespace preserved
<span> inline Generic inline container with no meaning
<a> inline Link (href= gives the destination)
<em>, <strong> inline Emphasized and strongly emphasized text
<code> inline Inline code, usually shown in monospace
<br> inline, void Line break within text
<img> inline, void Image (src=, alt=)
<input> inline, void Form input such as text box or checkbox
<canvas>, <video> inline Embedded graphics and video

Evolution of HTML

HTML is a quirky language saddled with decades of backwards compatibility.

It is the oldest of the web languages; the first "formal" definition was the HTML 2.0 specification2 published in 1995. HTML evolved as a standard controlled by the IETF, then the W3C, founded by Tim Berners-Lee, inventor of the web.

Early HTML was mostly focused on presentation. It contained tags mostly designed to mimic what was common in print:

Example

<table>
<tr>
    <th>item</th><th>price</th>
</tr>
<tr>
    <td>pancake</td><td>3.99</td>
</tr>
<tr>
   <td>egg</td><td>1.25</td>
</tr>
<tr>
   <td>toast</td><td>1.99</td>
</tr>
</table>

<i>this creates italic text</i>
<br>
<b>this creates bold text</b>
<marquee>there were even elements that animated text</marquee>

itemprice
pancake3.99
egg1.25
toast1.99

this creates italic text
this creates bold text there were even elements that animated text

Semantic HTML

In the late 1990s and early 2000s the W3C released several revisions of HTML under the name HTML 4.

The goal was to try to update & standardize HTML since competing browsers were adding incompatible features.

There was also a push towards a concept of semantic HTML, the idea that markup should not specify how the information should be displayed. It should instead denote what the information is, and allow the browser (or other program, such as a screenreader for the visually impaired) to decide how to present the page content.

<b>mitochondria</b>: the powerhouse of the cell <br>

This HTML creates a bold term, followed by a definition, and ends with a <br> tag which creates a line break in the page. The markup here serves the purpose of denoting how it should be displayed.

Instead, a semantic approach might be:

<dl>
  <dt>mitochondria</dt>
  <dd>the powerhouse of the cell</dd>
</dl>

This uses the "dictionary term" and "dictionary definition" tag, which indicate that the relationship between these items is akin to a dictionary.

The browser would then apply default styling to these, which the user could override with CSS.

HTML5

There were no formal revisions to the HTML spec from roughly 2000-2009. Instead, the W3C introduced a very unpopular revision, XHTML, which introduced new strict rules but wasn't widely adopted.

This led browser makers to form the Web Hypertext Application Technology Working Group (WHATWG) and begin work on the HTML5 spec in 2004.

HTML5 encouraged more semantic HTML, standardized dozens of new elements like <canvas> for dynamic graphics, and added lots of new JavaScript APIs that reflected the growing dynamic nature of web sites and applications. HTML5 also standardized the permissiveness rules which had, until then, been implemented differently in each browser. This led to a web where different browsers are far more likely to render a malformed page in the same way.

HTML continues to evolve under WHATWG, as the HTML living standard which has now superseded HTML5.

Browser support is always evolving as new features are adopted. The site caniuse is a great resource for knowing which features have been implemented in your browser(s) of choice.



  1. It isn't fair to blame humans alone for this. Lots of tools that generated "webpages" produced atrocious HTML. It was not rare to see each character wrapped in its own tag(s), for example:

    <i>e</i><i>v</i><i>e</i><i>r</i><i>y</i>
    <i> </i>
    <i>l</i><i>e</i><i>t</i><i>t</i><i>e</i><i>r</i>
    <i> </i>
    <i>i</i><i>n</i>
    <i> </i>
    <i>a</i>
    <i> </i>
    <i>t</i><i>a</i><i>g</i>
    
     ↩

  2. This document is what is known as an RFC, a type of technical memo used to define internet protocols. ↩