HTML

HTML forms the foundation on which all of the web is built. As the name states (HyperText Markup Language) it is a markup language, that allows you to annotate your content with tags that attach semantic or presentational roles to the content. The most important thing when creating HTML documents is to remember that the aim is to markup with roles not with specific styles. Styling is attached later through CSS.

Core Concepts

Before we get into actually creating HTML documents, we will briefly look at the two core concepts of HTML: elements and attributes.

Element

The core element for marking up the content is the HTML element. At the basic level an element consists of three parts. The opening tag <tag-name> which indicates where the content marked up with that element starts, the content of the element, and the closing tag </tag-name>:

<tag-name>Element content</tag-name>

You should always use lowercase letters for the tag names. While not technically binding, it is the recommended convention and makes your HTML more readable for other developers.

In some cases your element will not have any content. In that case you can put the closing / directly at the end of the opening <tag-name>:

<tag-name/>

The main use of such self-closing elements is to indicate locations to include content from outside the HTML page (images, videos, stylesheets, …), as we will see later.

Warning

You will sometimes find tutorials that state that in HTML5 you do not need to close your elements. While technically correct, it means that you are leaving the decision on when and where an element is closed to the browser’s internal logic. This might not be consistent across browsers and is potentially liable to future change. You should therefor not do this. Always explicitly close your elements.

The full power of HTML comes from the ability to nest elements inside other elements as in the following example:

<parent-tag>Content <child-tag>in the tag</child-tag></parent-tag>

The important thing when nesting elements is that the elements must form a tree structure. That means that all child elements must be closed before their parent element can be closed. For example the following HTML is invalid, as the parent-tag is closed before its child-tag:

<parent-tag>Content <child-tag>in the</parent-tag> tag</child-tag>

In practice, when the browser encounters a situation like this, it attempts to automatically fix this, by adding additional opening and closing tags, resulting in a structure that might be something like this:

<parent-tag>Content <child-tag>in the</child-tag></parent-tag><child-tag> tag</child-tag>

Since it is unlikely that this is what you intended, you should always check that you have correctly nested and closed your elements. Use a decent code editor and that will automatically highlight any such errors.

Note

The label tag is sometimes also used as a synonym for element. Tag should really only be applied to the opening or closing <tag> and element to the whole opening/content/closing block. However, you will often read things like “That is contained in a div tag”, even though they mean that it is contained in a <div> element. Annoying, but there it is.

Attributes

To provide further flexibility to the markup, elements can be further modified through the inclusion of attributes in the opening tag. Attributes are simply given as name="value" pairs inside the opening tag:

<tag-name attr-name="attr-value"/>

Each attribute name can only appear once in a tag. However, you can have multiple attributes in a single element, with the attributes separated from each other by a space:

<tag-name attr-1-name="attr-1-value" attr-2-name="attr-2-value"/>

Attribute values are always string values. Later, when we get to interacting with the HTML through JavaScript we will have to look at transforming values into other data-types, but at the HTML level, all content is text.

Basic Structure

The basic structure of an HTML document is as follows:

<!DOCTYPE html>
<html xml:lang="en">
<head>
  Non-content elements go in here
</head>
<body>
  Displayed content goes in here
</body>
</html>

Doctype

HTML has evolved over the years and for different version, the specifications have defined slightly different interpretations and default settings for how to render the HTML code. The <!DOCTYPE XXXX> directive lets the browser know which HTML version the document is and thus which rules and interpretation to apply when rendering the content. To specify that the latest HTML5 specification is to be applied — which you should always do — we use <!DOCTYPE html>.

Html

Next comes the <html> element. An HTML document must only have one root element and this element must be the <html> element. The <html> element must only have two child elements, <head> and <body> in that order.

Note

As with all other HTML errors, the browser will never throw an error if you have multiple <html> elements or none at all. Instead it will simply try to fix the bugs silently and display what it thought you wanted.

Body

The <body> element contains all content elements, irrespective of whether these are immediately visible, require loading external content, or a JavaScript content.

Meta-data Elements

<meta>

The <meta> element is used to specify meta-data for the HTML document. The three most common uses of the <meta> element is to specify the encoding used for the HTML content:

<meta charset="utf-8"/>

to specify how the browser should render the page:

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

and to specify an author for the page:

<meta name="author" value="Mark Hall"/>

The “viewport” setting is the most important one here. It is used to tell mobile browsers that your HTML and styling is smart enough to be able to handle different screen sizes. If you do not specify this, then mobile browsers will generally render your page on a virtual screen of approximately 1024x768 pixels and then let the user navigate that by zooming and panning around. Obviously that is not the most pleasant experience, thus by specifying the viewport as above, we let the browser know that the styling will handle different screen sizes.

Full documentation on the <meta> element can be found here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta.

<title>

The <title> element is used to specify the page’s title, which most browsers display as the window and/or tab title.

<title>Athena - Login</title>

<link>

The <link> element is used to create links between the current document and other URLs. The most common use of this is to load in external CSS stylesheets:

<link rel="stylesheet" href="style.css"/>

The rel attribute is used to define the relationship between the other URL and this document. By specifying “stylesheet” as the value, the browser knows to load the URL specified in href and then apply it as a CSS stylesheet to the current document.

There are other elements that can be used in the <head>, see here for details: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head.

Block Elements

In the main <body> content, HTML elements are split into two groups: block elements and inline elements. The main distinction between the two is that block elements form a vertical structure. After each closing tag of a block element, the browser essentially adds a new-line, so that the next element appears below the current one. This is not the case for inline elements.

The list of elements here is not complete, but represents the most commonly used and needed elements.

Generic

Sometimes it is necessary to group together content, primarily for styling purposes, but there is no specific HTML element that has the necessary semantics, or we explicitly do not want to attach any semantics to the block of content. In that case, the <div> element creates a generic, arbitrary block:

<div>

An example for the use of a <div> element is the following code snippet, which attaches some styling — via the class attribute and the “text-right” styling — to ensure that the button it contains is aligned to the right:

<div class="text-right">
  <button tabindex="3">Login</button>
</div>

There are no semantics to this structure, simply a way to mark out content to then apply the styling to, thus <div> is ideal.

Structural

While it is possible to only use <div> to mark up the complete document, this is to be avoided, as for many types of content, more specific HTML elements exist. By using these instead of <div>, the browser “knows” what the semantics are of that part of the content and can react appropriately, in particular it can provide more information to assistive technologies such as screen readers. Structural elements generally do not contain text content themselves, rather they define the logical and semantic structure of the document.

<main>

The <main> element is used to mark out the main content area of the document and in particular distinguish it from any headers, footers, or other supplementary materials

<header>

The <header> element is used to specify content that acts as a header. This can be placed both outside the <main> to indicate a header for the whole document, but also within more specific elements inside the <main> to specify a header for that area.

<footer>

The <footer> element is the footer equivalent to the <header>.

<aside>

The <aside> element is used to indicate content that is supplementary to the <main> content. An example might be on an e-commerce site, the <main> content would be the object to buy that the user is currently viewing, while the <aside> content could be the recommendations for related content.

<nav>

The <nav> element is used to indicate that the content represents navigation, either within the document or between multiple documents. The actual navigation is generally implemented via lists and link tags.

<section>

The <section> element is used to indicate content that is semantically related, but for which no more specific element exists. It distinguish itself from the <div> element in that it indicates to the browser that there is a semantic grouping of the content inside it, not just a logical one within the HTML document. In particular for assistive technologies, it is possible to attach specific roles to elements and where such a role is to be attached, it is better to use a <section>, rather than the <div>.

Text

Text elements are used to represent actual textual content. They generally only contain text and inline elements.

<h1>

The <h1> element (and its cousins <h2>, <h3>, <h4>, <h5>, and <h6>) are used to specify headings within the document. You should ensure that you have a logical structure to your heading elements. For example in a flat structure something like this is appropriate:

<h1>Page Title</h1>
...
<h2>Section Title</h2>
...
<h2>Section Title</h2>

For a more nested structure, you might have something like this:

<main>
  <h1>Page Title</h1>
  <section>
    <h2>Section Title</h2>
    <nav>
      <h3>Navigation Title</h3>
    </nav>
  </section>
  <section>
    <h2>Section Title</h2>
  </section>
</main>

What you should never have is a structure like this:

<h2>Application Title</h2>
<h1>Page Title</h1>
<h2>Section Title</h2>

Similarly, you should not skip heading levels:

<h1>Page Title</h1>
<h3>Section Title</h3>

<p>

<p> elements are used to define a paragraph of text. What is important is that you should only use <p> when the text truly represents a paragraph of text. Where it is simply a short line of text that is, for example, a label or a notification, it is not necessary and generally recommended not to wrap that in a <p> element.

Lists

Lists represent content that is itemised and in some cases also has an inate ordering.

<ul>

The <ul> element is used to define an unordered list (generally rendered as a list of bullet points).

<ol>

The <ol> element is used to define an ordered list. You should only use <ol> if there is an explicit ordering of the list items that is important to explicitly model. If, as in the case of a menu, the items are ordered, but the ordering is quasi-arbitrary, you should not use <ol>, but should stick with <ul>.

<li>

The <ul> and <ol> elements define that their content is a list. The <li> element defines a single item in that list.

Lists can be nested to an arbitrary depth, but nested lists must always be placed inside a <li> element:

<ol>
  <li>
    <ol>
      <li></li>
      <li></li>
    </ol>
  </li>
  <li>
    <ol>
      <li></li>
      <li></li>
      <li></li>
    </ol>
  </li>
</ol>

Tables

Tables are some of the individually most complex structures in HTML, but can be used very effectively for displaying large amounts of data to the user. Tables are fundamentally defined as a series of rows, where each row consists of one or more columns.

<table>

The <table> element wraps the whole table and contains a <thead>, then a <tbody>, and finally a <tfoot> element. Both the <thead> and <tfoot> are optional. It can also have as its first element a <caption> element.

<thead>

The <thead> element contains the table header, which is defined through one or more <tr> elements.

<tbody>

The <tbody> element contains the table body, which is defined through one or more <tr> elements.

<tfoot>

The <tfoot> element contains the table footer, which is defined through one or more <tr> elements.

<caption>

The <caption> is used to define a caption for the table. It is generally only used to provide an explanatory caption where a table is embedded in text content.

<tr>

The <tr> element defines a single row inside the table and contains one or more <th> or <td> elements.

<th>

The <th> element defines a header cell. Header cells can be used anywhere in the table, not just inside the <thead>. For example when used in the <tbody> the semantic interpretation is that it defines a label for that row.

<td>

The <td> element defines a data cell containing arbitrary content.

Here is an example of a table, showing the use of all elements except the <tfoot>:

<table>
  <caption>Log Book</caption>
  <thead>
    <tr>
      <th>Date</th>
      <th>Subject Area</th>
      <th>Details of Work</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>29.06.2018</td>
      <td>Digital Humanities</td>
      <td>PhD Supervision</td>
    </tr>
    <tr>
      <td>31.08.2018</td>
      <td>Digital Humanities</td>
      <td>PhD Supervision</td>
    </tr>
  </tbody>
</table>

Warning

There was a time when tables were used for layouting and you will still find code that does this. Never use tables for layouts. CSS does it all and does it better.

Inline Elements

Inline elements are used inside of block elements to add specific semantics or interaction points to the displayed HTML document.

Generic

<span>

The <span> element plays the same role as the <div> element, but for inline elements. It is used to attach non-semantic roles to content, for example to attach specific styling.

What the Germans call <span class="foreign">Weltschmerz</span>.

Via styling we can then attach a different font or font style to that element to indicate to the reader that there is content in a foreign language. Obviously this is not accessible to technologies such as screen readers. Thus, where this kind of distinction should be available to such technologies, additional attributes must be used to explicitly mark the element up as having a specific role.

Images

<img>

The <img> element is used to embed an image into the HTML document. It never has any content, so it should always be written as <img/>. It has, however, two required attributes: src to specify the URL to load the image from and alt to provide an alternative text description of the image in case it cannot be loaded or for screen readers.

<img src="logo.png" alt="Athena Student Portal"/>

In this example the browser will load the logo image. Users of screen readers will hear the alternative text, which is the name of the site. It is important that the alt attribute always transports the same content as the image, to ensure that the document is accessible to all.

<picture>

The <picture> element allows the definition of multiple image sources for a single <img> element. It contains one or more <source> elements followed by a single <img> element. The browser will process each <source> in order and if the rules defined in the <source> are met, then that source is used to load the image. If no <source> matches, then the image from the <img> src attribute is loaded.

<source>

The <source> defines one potential source for an image. The most common use is using two attributes to define the image to load and the criteria when to use that image. srcset is used to define the URL to load the image from. media is used to define the media query (more on them on the next page) that specifies under which criteria the image from the srcset is to be used.

The following example puts it all together:

<picture>
  <source srcset="logo_large.png" media="(min-width: 1024px)"/>
  <source srcset="logo_medium.png" media="(max-width: 640px)"/>
  <img src="logo.png" alt="Athena Student Portal"/>
</picture>

The browser will start with the first source element and check if the width of the browser window is at least 1024px. In that case, the image called “logo_large.png” is loaded and displayed in the <img> element. If the browser window is less than 1024px wide, the browser will check the next <source> and if the browser window is wider than 600px, use the “logo_medium.png” image. Finally, if the browser window is less than 600px wide, neither of the <source> will match and thus the default image “logo.png” specified in the <img> will be used.

Actions

<a>

Actions that are available for the user are generally represented via the <a> element. Primarily this is used to link together multiple pages via the href attribute, but using JavaScript it is also possible to attach arbitrary actions, which we will use later in the module to build full applications.

Input Tags

With the exception of the <a> element, all other HTML elements that have been covered so far are output-only elements. However, in order to solicit input from the user, HTML also provides a number of input elements.

<form>

The <form> element acts as a container for input elements. Via the use of the action attribute it also specifies where the data in the input elements should be sent.

<button>

The <button> is used to create a button that the user can click on. If you only specify one <button> in the <form> then that <button> submits the form. When you have multiple <button> only the first one submits the <form>. For all others you need to attach explicit functionality via JavaScript.

<label>

The <label> is used to label the input element. Ideally the input element is placed inside the <label>, thus explicitly creating the link. Clicking on the text of the <label> element also executes the default action for the input element (either focussing it or, in the case of radio and checkboxes, toggling it).

For all input elements, the name attribute specifies the name of the field. When the data is submitted by the browser, all input in the form is sent as “name=value” pairs, where the name is the value in the name attribute and the value is the value the user specified.

Full documentation of all attributes, including those used for validation can be found here: https://developer.mozilla.org/en/docs/Web/HTML/Element/input.

Single Line

<input>

The <input> element generates a single line input element. What type of input it allows depends on the value of the type attribute. By default, and if the browser does not understand a given type attribute value, it generates a single line text input element. Commonly used specific input types are “number”, “date”, “search”, “email”, “file”, and “password”.

See full documentation here: https://developer.mozilla.org/en/docs/Web/HTML/Element/input.

Multi Line

<textarea>

The <textarea> element is used to create a multi-line text input control. You will generally need to use CSS to specify an appropriate width and height for the element.

Selection

For selection from a given set of choices, HTML supports both a single selection from a list of choices and multiple selection.

<input type="radio"/>

Creates a radio-box single selection element. Where mutliple radio controls have the same name, only one can ever be selected.

<input type="checkbox/>"

Creates a checkbox multi-selection element. Where multiple checkboxes have the same name, any number of them can be selected.

<select>

By default the <select> element creates a single selection drop-down box. By providing the multiple attribute this can be switched to display a list from which the user can select multiple. However, the default list does not provide any indication to the user that multiple selection is possible, thus it is important to always provide some guidance for the user in that szenario.

The options that are available to the user are specified via <option> elements.

<option>

Each <option> element defines one possible option to select in a <select> element. The content of the <option> is what the user sees and also what is submitted by the browser. By specifying the value attribute on the <option>, when the user selects an option, they see the content of the <option>, but the content of the value attribute is what is sent to the server. This makes it possible to, for example, send data ids to the server, while displaying readable labels to the user.

ARIA Attributes

Accessibility, quite apart from making your HTML better and making it available to a wider range of users, is also in many places a legal requirement. A good starting point are the best practices you can find here: https://www.w3.org/TR/wai-aria-practices-1.1/. In this tutorial we will only the very basics. ARIA attributes can be specified on most elements, but you should check the MDN (Mozilla Developer Network) for which ARIA roles are allowed on specific HTML elements.

role

The role attribute enables you to specify what semantic/activity role an element plays. For example, if you allowed the user to click on a <span> element to make something happen and have indicated this via the visual display of the element, that is not something that a screen reader can pick up on. However, by also adding role="button" to that <span> element, the screen reader can inform the user that an action is available here. A wide range of roles is available, you should check the documentation linked above for the full list.

tabindex

Accessibility frequently means having to navigate via the keyboard. The tabindex attribute allows you to specify which elements can be navigated to via the keyboard and in what order. In general you should only use the values “0” and “-1”. A tabindex of “0” means that the browser should use the order of the elements in the HTML document to define the tab order. A tabindex of “-1” means that the element can be focused for the keyboard, but that it is not accessible via the “tab” key. You would then add JavaScript to move the focus to that element. A common use-case for this is the menu. You would give the first menu item a tabindex of “0”, so that the user can tab to it, then give all other menu items an tabindex of “-1” so that the user does not have to tab through all of them to get past the menu, and then implement menu navigation via JavaScript.

aria-label

The aria-label allows you to specify a label that is only used by screen readers.

Important

Whatever you write in the aria-label from the screen reader’s point-of-view completely replaces the content of the element.

Example

We will now set up the example for this tutorial. Create a new directory week01. Into this create a new file package.json with the following content:

{
  "private": true,
  "dependencies": {
    "cypress": "^9.3.1",
    "http-server": "^14.1.2"
  }
}

Next, on the command-line run the following to install all dependencies:

$ yarn

Amongst other things this installs a small web-server, which we can now start via

$ node_modules/.bin/http-server

Login File

Next, we will create our first HTML file. Create a file login.html and add the following content:

<!DOCTYPE html>
<html xml:lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Athena - Login</title>
    <link rel="stylesheet" href="style.css" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="author" value="Mark Hall" />
  </head>
  <body>
    <header class="grid-x">
      <div class="cell small-12 large-shrink app-title">
        Athena - Study Portal
      </div>
      <nav class="cell small-12 large-auto" aria-label="Main"></nav>
      <nav class="cell shrink small-hidden" aria-label="User">
        <ul class="horizontal" role="menu" aria-label="User">
          <li><a href="login.html" role="menuitem" tabindex="-1">Login</a></li>
        </ul>
      </nav>
    </header>
    <main class="grid-container-x small callout">
      <h1>Login</h1>
      <form action="index.html">
        <div>
          <label
            >E-Mail Address
            <input
              type="email"
              name="email"
              placeholder="Your e-mail address"
              tabindex="1"
              required="required"
            />
          </label>
        </div>
        <div>
          <label
            >Password
            <input
              type="password"
              name="password"
              placeholder="Your password"
              tabindex="2"
              required="required"
            />
          </label>
        </div>
        <div class="text-right">
          <button tabindex="3">Login</button>
        </div>
      </form>
    </main>
    <footer>
      &copy; 2018 - Mark Hall (<a
        href="mailto:mark.hall@informatik.uni-halle.de"
        tabindex="0"
        >mark.hall@informatik.uni-halle.de</a
      >)
    </footer>
    <script src="scripts.js"></script>
  </body>
</html>

This file demonstrates the first important thing about writing good HTML code and that is indentation. You can see that where elements are contained within other elements, they are always indented with two spaces. This makes it easy to see the full structure and nesting of the HTML file and also makes it much easier to find and fix bugs. When you make changes, you must always maintain the indentation as well, to ensure that your code remains maintainable.

With the web-server that we started above running, you can now navigate to http://localhost:8080/login.html and will see your rendered file.

One or two important aspects to pick out from the code:

<label>E-Mail Address
  <input type="email" name="email" placeholder="Your e-mail address" tabindex="1" required="required"/>
</label>

Here we see the definition of the email input element for the login form. You can see that the type is set to “email” and that the required attribute is set to “required”. This tells the browser that in this input field only e-mail addresses are allowed and that input is required. You can test this out by just clicking on the “Login” button and you will see that you get an error message. Similarly, if you type something into the email input field that is not an e-mail address and then click on the “Login” button, you will also get an error. Validation in the browser is not sufficient and you must always validate on the server as well, but for usability purposes, validation in the client is necessary as well.

The other thing here is that it uses an explicit tabindex set to “1”. This is because on the login page, we can make a good assumption that the user will want to log in, thus by letting them get straight to the first input field, we can simplify their interaction.

At this point, because we have neither the necessary CSS nor JavaScript, the page will still be very plain. We will add to that in the next two steps.

Content File

Now, let us create a second file index.html and add the following content:

<!DOCTYPE html>
<html xml:lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Athena - My Modules</title>
    <link rel="stylesheet" href="style.css" />
    <link
      rel="stylesheet"
      href="https://cdn.materialdesignicons.com/2.7.94/css/materialdesignicons.min.css"
    />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="author" value="Mark Hall" />
  </head>
  <body>
    <header class="grid-x">
      <div class="cell small-12 large-shrink app-title">
        Athena - Study Portal
      </div>
      <nav class="cell small-12 large-auto" aria-label="Main">
        <ul class="horizontal" role="menu" aria-label="Main">
          <li>
            <a href="" role="menuitem" tabindex="0" class="active"
              >My Modules</a
            >
          </li>
          <li><a href="" role="menuitem" tabindex="-1">My Exams</a></li>
        </ul>
      </nav>
      <nav class="cell shrink small-hidden" aria-label="User">
        <ul class="horizontal" role="menu" aria-label="User">
          <li>
            <a href="profile.html" role="menuitem" tabindex="0">Profile</a>
          </li>
          <li><a href="login.html" role="menuitem" tabindex="-1">Logout</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <div class="grid-x grid-padding-x">
        <h1 class="cell">My Modules</h1>
      </div>
      <div class="grid-x grid-padding-x">
        <nav class="cell shrink" aria-label="Modules">
          <ul role="menu" aria-label="Modules">
            <li>
              <a href="" tabindex="0" role="menuitem" class="active"
                >Current Semester</a
              >
            </li>
            <li><a href="" tabindex="-1" role="menuitem">Last Semester</a></li>
            <li role="separator"></li>
            <li>
              <a href="" tabindex="-1" role="menuitem">Enroll in Module</a>
            </li>
          </ul>
        </nav>
        <section class="cell auto">
          <table>
            <thead>
              <tr>
                <th>Code</th>
                <th>Name</th>
                <th>Sections</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td><a href="">INF.06528.01</a></td>
                <td><a href="">Client-seitige Web-Anwendungen</a></td>
                <td>
                  <nav aria-label="Sections of Client-seitige Web-Anwendungen">
                    <ul role="menu" class="horizontal" aria-label="Sections">
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Dates"
                          title="Dates"
                          class="mdi mdi-calendar-clock"
                          tabindex="0"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Documents"
                          title="Documents"
                          class="mdi mdi-file-document-box-multiple-outline"
                          tabindex="-1"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Exercises"
                          title="Exercises"
                          class="mdi mdi-test-tube"
                          tabindex="-1"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Teilnehmerinnen"
                          title="Teilnehmer_innen"
                          class="mdi mdi-account-multiple"
                          tabindex="-1"
                        ></a>
                      </li>
                    </ul>
                  </nav>
                </td>
                <td>
                  <nav aria-label="Actions for Client-seitige Web-Anwendungen">
                    <ul role="menu" class="horizontal" aria-label="Actions">
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Leave"
                          title="Leave"
                          class="mdi mdi-delete warning"
                          tabindex="0"
                        ></a>
                      </li>
                    </ul>
                  </nav>
                </td>
              </tr>
              <tr>
                <td><a href="">INF.05370.01</a></td>
                <td>
                  <a href=""
                    >Informatik in den Geistes- und Kulturwissenschaften</a
                  >
                </td>
                <td>
                  <nav
                    aria-label="Sections of Informatik in den Geistes- und Kulturwissenschaften"
                  >
                    <ul role="menu" class="horizontal" aria-label="Sections">
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Dates"
                          title="Dates"
                          class="mdi mdi-calendar-clock"
                          tabindex="0"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Documents"
                          title="Documents"
                          class="mdi mdi-file-document-box-multiple-outline"
                          tabindex="-1"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Exercises"
                          title="Exercises"
                          class="mdi mdi-test-tube"
                          tabindex="-1"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Teilnehmerinnen"
                          title="Teilnehmer_innen"
                          class="mdi mdi-account-multiple"
                          tabindex="-1"
                        ></a>
                      </li>
                    </ul>
                  </nav>
                </td>
                <td>
                  <nav
                    aria-label="Actions for Informatik in den Geistes- und Kulturwissenschaften"
                  >
                    <ul role="menu" class="horizontal" aria-label="Actions">
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Leave"
                          title="Leave"
                          class="mdi mdi-delete warning"
                          tabindex="0"
                        ></a>
                      </li>
                    </ul>
                  </nav>
                </td>
              </tr>
              <tr>
                <td><a href="">INF.06450.01</a></td>
                <td><a href="">eHumanities Grundlagen</a></td>
                <td>
                  <nav aria-label="Sections of eHumanities Grundlagen">
                    <ul role="menu" class="horizontal" aria-label="Sections">
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Dates"
                          title="Dates"
                          class="mdi mdi-calendar-clock"
                          tabindex="0"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Documents"
                          title="Documents"
                          class="mdi mdi-file-document-box-multiple-outline"
                          tabindex="-1"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Exercises"
                          title="Exercises"
                          class="mdi mdi-test-tube"
                          tabindex="-1"
                        ></a>
                      </li>
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Teilnehmerinnen"
                          title="Teilnehmer_innen"
                          class="mdi mdi-account-multiple"
                          tabindex="-1"
                        ></a>
                      </li>
                    </ul>
                  </nav>
                </td>
                <td>
                  <nav aria-label="Actions for eHumanities Grundlagen">
                    <ul role="menu" class="horizontal" aria-label="Actions">
                      <li>
                        <a
                          href=""
                          role="menuitem"
                          aria-label="Leave"
                          title="Leave"
                          class="mdi mdi-delete warning"
                          tabindex="0"
                        ></a>
                      </li>
                    </ul>
                  </nav>
                </td>
              </tr>
            </tbody>
          </table>
        </section>
      </div>
    </main>
    <footer>
      &copy; 2018 - Mark Hall (<a
        href="mailto:mark.hall@informatik.uni-halle.de"
        tabindex="0"
        >mark.hall@informatik.uni-halle.de</a
      >)
    </footer>
    <script src="scripts.js"></script>
  </body>
</html>

We will dig into this example in more detail when we add CSS and JavaScript, but for the moment I just want to highlight the use of the ARIA tags in the menus:

<nav class="cell small-12 large-auto" aria-label="Main">
  <ul class="horizontal" role="menu" aria-label="Main">
    <li>
      <a href="" role="menuitem" tabindex="0" class="active"
        >My Modules</a
      >
    </li>
    <li><a href="" role="menuitem" tabindex="-1">My Exams</a></li>
  </ul>
</nav>
<nav class="cell shrink small-hidden" aria-label="User">
  <ul class="horizontal" role="menu" aria-label="User">
    <li>
      <a href="profile.html" role="menuitem" tabindex="0">Profile</a>
    </li>
    <li><a href="login.html" role="menuitem" tabindex="-1">Logout</a></li>
  </ul>
</nav>

First, every menu is wrapped in a <nav> element to indicate that it contains navigation elements.

Second, the actual menu items are represented as an unordered list. The <ul> has the role attribute set to “menu” to indicate that this is a list that acts as a menu. The individual links then have the role “menuitem” to indicate that they are items in the menu. What is important here is that the role is set on the actual element that allows for the interaction, the <a>, and not the <li> that provides the structuring. Roles that imply interaction, such as “menuitem”, must always be specified on the element that handles the actual interaction, not on any wrapping element that is there just for syntactic or display reasons.

Finally, the first menu item has a tabindex of “0”, while the second (and any other in the other menus) has a tabindex of “-1”. This makes each menu accessible via the “tab” key, but at the same time does not force the user to tab through each of the menu items. We will later use JavaScript to implement keyboard navigation within each menu.

With the basics of HTML covered, we now move on to adding a bit of style to the HTML with CSS.