Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

On Day 2, you will build two useful pieces of HTML: a real data table and a semantic navigation section. Use <table> when readers need to compare values in rows and columns, and use <nav> to identify a major group of navigation links. HTML supplies the meaning; CSS controls colors, spacing, borders, and whether a navigation list appears horizontally or vertically.

By the end, you will know how to write a small accessible table, decide when a table is the wrong tool, and turn a list of links into a navigation region that browsers and assistive technologies can identify.

Start with a genuine data table

A table is appropriate when each row and column has a meaningful relationship. A learning schedule is a good example: every row describes one module, and every column describes the same property for all modules. The browser can expose those relationships to a screen reader because the markup says which cells are headers and which are data.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<table>
  <caption>Week 1 learning schedule</caption>
  <thead>
    <tr>
      <th scope="col">Module</th>
      <th scope="col">Topic</th>
      <th scope="col">Estimated time</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>HTML document structure</td>
      <td>30 minutes</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Tables and navigation</td>
      <td>45 minutes</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Links and images</td>
      <td>40 minutes</td>
    </tr>
  </tbody>
</table>

Save this as part of an HTML document and open it in a browser. You will see an unstyled grid or a plain sequence of cells, depending on the browser’s default styles. That appearance is not the important part yet. The important part is that the first row is identified as a set of column headers, while the following rows contain ordinary values.

#1 Best Overall
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

What each table element means

<table>: the data container

The outer <table> element tells the browser that its contents form a set of related tabular data. It should not be used merely because boxes need to line up. A product comparison, timetable, set of measurements, or invoice can be tabular; a page’s header, sidebar, and footer are layout regions and belong in normal structural elements styled with CSS.

<caption>: a name for the table

A caption gives the table a visible, programmatically associated name. “Week 1 learning schedule” tells a reader what the grid represents before they inspect individual cells. Put the caption immediately inside <table>. If surrounding text already provides an unmistakable title, you can still use a concise caption to make the table understandable when encountered on its own.

<tr>, <th>, and <td>

<tr> creates a row. A <th> creates a header cell, and a <td> creates a data cell. Use <th> for “Module,” “Topic,” and “Estimated time,” not a <td> that you later make bold with CSS. Bold text changes appearance only; it does not tell assistive technology that the cell labels the values below it. Likewise, putting a label in a visually prominent position does not create a semantic relationship.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

<thead>, <tbody>, and <tfoot>

These elements group rows into a header, body, and optional footer. They make a long table easier to understand and style, and browsers can use the groups when printing or handling a scrolling table. Their presence does not automatically make a table accessible: the header cells still need to be marked correctly and related to their data.

<table>
  <caption>Monthly study hours</caption>
  <thead>
    <tr>
      <th scope="col">Month</th>
      <th scope="col">HTML</th>
      <th scope="col">CSS</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">January</th>
      <td>8 hours</td>
      <td>5 hours</td>
    </tr>
    <tr>
      <th scope="row">February</th>
      <td>10 hours</td>
      <td>7 hours</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th scope="row">Total</th>
      <td>18 hours</td>
      <td>12 hours</td>
    </tr>
  </tfoot>
</table>

In this second example, “January,” “February,” and “Total” label rows, so they are also <th> cells. A header can describe a column or a row; it is not limited to the top line.

Make header relationships explicit

Simple tables: use scope

For a straightforward grid, scope="col" tells the browser that a header applies downward to its column. scope="row" tells it that a header applies across its row. Many simple tables can be understood without the attribute, but adding it documents your intent and removes ambiguity, especially when a table has both row and column headers.

Choosing table markup for the relationship you have
Situation Markup approach Reason
One header row, values below <th scope="col"> Each heading labels a vertical column.
One header column, values across <th scope="row"> Each heading labels a horizontal row.
Several header levels or irregular groups Header id values plus data-cell headers Each data cell can name every header that applies to it.

Complex tables: use id and headers

A simple direction is not enough when a data cell belongs to multiple header levels, such as a financial report grouped by year and quarter. Give every relevant header a unique id, then list those IDs in the data cell’s headers attribute. The value is a space-separated list.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<table>
  <caption>Sales by region and quarter</caption>
  <thead>
    <tr>
      <th id="region" rowspan="2">Region</th>
      <th id="year-2026" colspan="2">2026</th>
    </tr>
    <tr>
      <th id="q1">Q1</th>
      <th id="q2">Q2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th id="north">North</th>
      <td headers="region north year-2026 q1">$12,000</td>
      <td headers="region north year-2026 q2">$14,500</td>
    </tr>
  </tbody>
</table>

Do not add this complexity to a small table that already has an obvious pattern. The goal is a relationship that can be determined from the markup, not the largest possible number of attributes.

Why a table should not become your page layout

Older sites often placed navigation, columns, and footers in table cells. That approach describes visual positions as if they were data relationships. It makes the document harder to adapt to small screens, complicates keyboard and screen-reader navigation, and ties content structure to one visual arrangement. W3C WAI’s tables guidance distinguishes data grids from layout tables for this reason.

Data table or layout grid?
Question Use a table Use HTML structure and CSS
Do rows and columns communicate facts together? Yes: schedules, scores, measurements, invoices. No: the boxes only need to line up.
Would a screen reader benefit from announcing headers? Yes; mark those headers with <th>. No; use meaningful regions such as <header>, <main>, and <footer>.
Should the arrangement change at a mobile width? Let CSS handle responsive table scrolling or presentation. Use CSS Grid, Flexbox, margins, and padding for layout.

CSS is the presentation layer. For a readable first style, add a border, spacing, and aligned text without changing the HTML meaning:

table {
  border-collapse: collapse;
  width: 100%;
}

caption {
  font-weight: 700;
  margin-bottom: 0.5rem;
  text-align: left;
}

th, td {
  border: 1px solid #b8c0cc;
  padding: 0.6rem;
  text-align: left;
}

th {
  background: #eef2f7;
}

If a wide data table must remain readable on a phone, place it in a wrapper with horizontal overflow rather than squeezing every word into an unusable column:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
.table-scroll {
  overflow-x: auto;
}

Keep the table itself intact inside that wrapper. Do not remove headers just to make the grid fit.

Add a navigation section with <nav>

The <nav> element identifies a section whose purpose is to provide major navigation links within the current page or to other documents. It does not need to wrap every link. A link in a paragraph, a product description, or a citation can remain where it naturally belongs.

<nav aria-label="Tutorial sections">
  <ul>
    <li><a href="#tables">HTML tables</a></li>
    <li><a href="#headers">Header relationships</a></li>
    <li><a href="#navigation">Navigation with nav</a></li>
    <li><a href="#practice">Practice checklist</a></li>
  </ul>
</nav>

Give the surrounding sections matching IDs so the fragment links work. If you have more than one navigation region, label them according to purpose:

<nav aria-label="Primary">
  <a href="index.html">Home</a>
  <a href="lessons.html">Lessons</a>
  <a href="contact.html">Contact</a>
</nav>

<nav aria-label="Account">
  <a href="profile.html">Profile</a>
  <a href="sign-out.html">Sign out</a>
</nav>

MDN notes that a document may contain multiple <nav> sections. Labels help users of assistive technology distinguish “Primary” from “Account,” “On this page,” or another purpose. Use a real list when the links form a list; the list gives you a predictable structure to style and a sensible fallback when CSS is unavailable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Turn the link list into a navigation bar with CSS

HTML does not decide whether navigation is a bar, sidebar, drawer, or vertical list. Apply that visual decision in CSS:

nav ul {
  display: flex;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

nav a {
  color: #174a7e;
  text-decoration: none;
}

nav a:hover,
nav a:focus-visible {
  text-decoration: underline;
}

@media (max-width: 42rem) {
  nav ul {
    align-items: flex-start;
    flex-direction: column;
  }
}

The links remain the same when the viewport narrows; only their arrangement changes. Keep visible focus styling so keyboard users can see which link is active. If you later create a menu button that shows or hides links, make the button keyboard accessible and keep its expanded state synchronized with the menu; that interaction is an additional behavior, not something <nav> provides automatically.

Build one complete Day 2 page

Combine the two ideas in a small page. The navigation links point to headings, and the table provides genuinely related data.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Day 2: Tables and Navigation</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <header>
    <h1>My Web Development Journey</h1>
    <nav aria-label="Primary">
      <ul>
        <li><a href="#tables">Tables</a></li>
        <li><a href="#navigation">Navigation</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <section id="tables">
      <h2>Study schedule</h2>
      <table>
        <caption>Day 2 tasks</caption>
        <thead>
          <tr>
            <th scope="col">Task</th>
            <th scope="col">Status</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Create a data table</td>
            <td>Complete</td>
          </tr>
          <tr>
            <td>Add a navigation region</td>
            <td>Next</td>
          </tr>
        </tbody>
      </table>
    </section>

    <section id="navigation">
      <h2>Navigation practice</h2>
      <p>Use the links above to move between sections of this page.</p>
    </section>
  </main>
</body>
</html>

This page uses <header> and <main> for page regions, <section> for related content, <nav> for the major links, and a table only for the task-and-status relationship.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check your work before moving to Day 3

  1. Describe the data. In one sentence, explain what each row and column represents. If you cannot, the content may not be tabular.
  2. Inspect the first row. Headers should be <th> elements, not ordinary cells made bold with CSS.
  3. Mark direction. Add scope="col" or scope="row" when a header’s direction is not immediately obvious.
  4. Name the grid. Add a concise <caption> that still makes sense when read apart from nearby prose.
  5. Test navigation. Activate every link with the keyboard and confirm that each fragment target exists and is visible.
  6. Test small screens. Resize the browser. The navigation may stack, and a wide table may scroll horizontally, but neither should become clipped or unreadable.
  7. Check the source. Ensure each ID is unique, each headers value matches a real header ID when used, and all elements are properly closed.

Common mistakes and fixes

Using a table to align a form or page columns

Replace the layout table with normal sections and CSS Grid or Flexbox. Reserve table markup for relationships a reader would naturally describe as rows and columns.

Making headers look right but leaving them as <td>

Change the cells to <th> and, when useful, add scope. Visual formatting cannot substitute for semantic markup.

Adding row groups and assuming accessibility is finished

<thead>, <tbody>, and <tfoot> organize the source and help styling, but they do not establish every header relationship by themselves. Review the actual headers and their scope.

Putting every link inside <nav>

Use <nav> for a major navigation block. Keep contextual links in their paragraphs or lists so the navigation landmark remains useful and easy to scan.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Expecting HTML to create a horizontal bar

The element supplies meaning, not a visual design. Use CSS for direction, spacing, colors, responsive behavior, and focus states.

A short practice challenge

Create a table of five modules from your own learning plan. Give it a caption, one header row, and a body. If a module name labels an entire row, make that cell a row header; otherwise keep it as data. Then add a labeled <nav> with links to the table and two other sections. Style the navigation with Flexbox, add a mobile media query that stacks the links, and test the page using only the keyboard.

When the page works, view its source and ask two questions: “Can a browser determine which headers describe each value?” and “Can a user identify this link group as a navigation region?” If the answer to both is yes, you have used the semantics that HTML provides and left visual presentation where it belongs—in CSS.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.