HTML

HTML Tag: Syntax, Usage, and Examples

The tr tag defines a table row in HTML. You use it inside a table to group cells into a single horizontal row.

How to Use the Tag

A row lives inside a table section, like thead, tbody, or tfoot. Inside the row, you place header cells (th) or data cells (td).

Here’s the basic structure:

<table>
<tr>
<th>Header cell</th>
<th>Header cell</th>
</tr>
<tr>
<td>Data cell</td>
<td>Data cell</td>
</tr>
</table>

Most tables also include thead and tbody for clearer structure:

<table>
<thead>
<tr>
<thscope="col">Course</th>
<thscope="col">Level</th>
<thscope="col">Time</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTML Basics</td>
<td>Beginner</td>
<td>2 hours</td>
</tr>
<tr>
<td>JavaScript Loops</td>
<td>Intermediate</td>
<td>3 hours</td>
</tr>
</tbody>
</table>

A few practical rules:

  • Put tr inside table, and typically inside thead, tbody, or tfoot.
  • Put td and th inside tr.
  • Use th for headings, and td for regular values.
  • Keep the number of cells consistent across rows so the table stays readable.

What a row actually represents

A row is a record. Think “one person,” “one order,” “one lesson,” or “one day.” Each cell in the row provides one piece of that record, like name, status, and date.

Row groups: thead, tbody, and tfoot

Row groups help browsers and assistive tech understand your table, and they make styling simpler.

  • thead holds the header rows.
  • tbody holds the main data rows.
  • tfoot holds summary rows, like totals.

Browsers can render tfoot before tbody in the HTML and still display it at the bottom. Many developers still place tfoot after tbody for readability, but both patterns exist.

Attributes you might see on tr

The tr tag itself does not have many special attributes you need day to day. Historically, you might see align or bgcolor, but those are obsolete in HTML5. Use CSS instead.

You can always use global attributes like id, class, data-*, and aria-*.

<trclass="row--highlight"data-user-id="1842">
<td>Amira</td>
<td>Active</td>
</tr>

When to Use the Tag

Use the tr tag whenever you need a row-based layout where each row lines up under consistent columns. Tables work best for data, not for page layout.

Here are some common use cases.

1) Display structured data people compare

Tables shine when readers scan and compare values across columns.

Examples:

  • Pricing breakdown (plan, storage, support level)
  • Course schedule (day, topic, duration)
  • Feature list (feature, included, notes)

If someone might point at the screen and say “compare these two rows,” a table is a strong candidate.

2) Show lists that feel like records

A record is a set of fields that belong together. One row per record keeps things tidy.

Examples:

  • A list of support tickets (ID, subject, status)
  • A list of invoices (number, date, amount)
  • A list of learners (name, progress, last activity)

3) Create accessible tables with real semantics

Screen readers understand tables when you use them properly. A row with correct headers gives assistive tech enough context to announce values with meaning, like “Status, Active.”

A grid of div elements can look similar, but it does not carry the same built-in semantics.

4) Build tables that need styling by row

Rows are convenient targets for CSS and JavaScript.

  • Zebra striping with tr:nth-child(even)
  • Hover effects on a row
  • Clicking a row to open details
  • Highlighting rows that meet a condition, like “overdue”

Examples of the Tag

Below are several examples showing realistic patterns, plus small details that help with readability and accessibility.

1) A simple course table

<table>
<thead>
<tr>
<thscope="col">Lesson</th>
<thscope="col">Topic</th>
<thscope="col">Difficulty</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Links and images</td>
<td>Easy</td>
</tr>
<tr>
<td>2</td>
<td>Forms</td>
<td>Medium</td>
</tr>
<tr>
<td>3</td>
<td>Tables</td>
<td>Medium</td>
</tr>
</tbody>
</table>

Notes:

  • scope="col" on header cells clarifies that each th is a column header.
  • Each tr in tbody represents one lesson.

2) Zebra striping and row hover with CSS

Row-level styling is one of the nicest perks of tables.

<style>
table {
border-collapse: collapse;
width:100%;
  }

th,td {
border:1px solid#ccc;
padding:10px;
text-align: left;
  }

tbodytr:nth-child(even) {
background:#f7f7f7;
  }

tbodytr:hover {
background:#eee;
  }
</style>

<table>
<thead>
<tr>
<thscope="col">Name</th>
<thscope="col">Role</th>
<thscope="col">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jordan</td>
<td>Student</td>
<td>Active</td>
</tr>
<tr>
<td>Minh</td>
<td>Mentor</td>
<td>On break</td>
</tr>
<tr>
<td>Sofía</td>
<td>Teacher</td>
<td>Active</td>
</tr>
</tbody>
</table>

Each tr is a clean styling target. No extra wrapper elements needed.

3) A summary row in tfoot

Footer rows work well for totals, averages, or quick summaries.

<table>
<thead>
<tr>
<thscope="col">Item</th>
<thscope="col">Qty</th>
<thscope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Notebook</td>
<td>2</td>
<td>6.00</td>
</tr>
<tr>
<td>Pen</td>
<td>5</td>
<td>1.50</td>
</tr>
</tbody>
<tfoot>
<tr>
<thscope="row">Total</th>
<td>7</td>
<td>7.50</td>
</tr>
</tfoot>
</table>

Why scope="row" on the “Total” cell? That cell is acting like a row header. It labels the rest of the row.

4) Click a row to show details (small JavaScript example)

Sometimes you want “click row to open.” Tables can do that cleanly with data-* attributes.

<tableid="orders">
<thead>
<tr>
<thscope="col">Order</th>
<thscope="col">Customer</th>
<thscope="col">Status</th>
</tr>
</thead>
<tbody>
<trdata-order-id="A102">
<td>A102</td>
<td>Priya</td>
<td>Shipped</td>
</tr>
<trdata-order-id="A103">
<td>A103</td>
<td>Omar</td>
<td>Processing</td>
</tr>
</tbody>
</table>

<pid="output"aria-live="polite"></p>

<script>
const tableBody =document.querySelector("#orders tbody");
const output =document.getElementById("output");

  tableBody.addEventListener("click",(event) => {
const row = event.target.closest("tr");
if (!row)return;

    output.textContent =`Selected order: ${row.dataset.orderId}`;
  });
</script>

This pattern avoids adding click handlers to every row. One listener on tbody is enough.

Learn More About the Tag

tr vs td vs th

These three tags get mixed up a lot, so here’s the simplest mental model:

  • tr creates the row.
  • td creates a data cell inside the row.
  • th creates a header cell inside the row.

A row without cells is like a sentence without words. Browsers may still render it, but it does not carry useful content.

Table headers and accessibility

Tables become much more accessible when headers are clear.

Good habits:

  • Use th for header cells.
  • Use scope="col" for column headers.
  • Use scope="row" when a cell labels the rest of its row.
  • Add a <caption> for context when the table needs a title.
<table>
<caption>Weekly study plan</caption>
<thead>
<tr>
<thscope="col">Day</th>
<thscope="col">Topic</th>
<thscope="col">Time</th>
</tr>
</thead>
<tbody>
<tr>
<thscope="row">Mon</th>
<td>HTML forms</td>
<td>45 min</td>
</tr>
</tbody>
</table>

The caption gives the table meaning in one line. Screen readers often announce it before reading rows.

Consistent column count matters

A messy table often comes from inconsistent cell counts, like a row with two cells inside a table that usually has three. Sometimes that is fine if you use colspan, but accidental mismatches cause confusing layouts.

Here is a correct way to span columns:

<tr>
<tdcolspan="3">No results found.</td>
</tr>

Without colspan, the “No results found” message would sit in just the first column, which can look odd.

Rowspan and colspan, quick overview

  • colspan lets a cell stretch across multiple columns.
  • rowspan lets a cell stretch across multiple rows.

Example of a grouped schedule:

<table>
<thead>
<tr>
<thscope="col">Track</th>
<thscope="col">Session</th>
<thscope="col">Speaker</th>
</tr>
</thead>
<tbody>
<tr>
<thscope="row"rowspan="2">Frontend</th>
<td>Accessibility basics</td>
<td>Lina</td>
</tr>
<tr>
<td>CSS layout</td>
<td>Sam</td>
</tr>
</tbody>
</table>

The “Frontend” header spans two rows, so it labels both sessions.

Common mistakes

Putting tr outside a table

A row must live inside a table structure. Browsers might try to fix the markup, but it can lead to unexpected results.

Using tables for page layout

Tables are for data. Use CSS layout tools like Flexbox or Grid for page structure.

Forgetting headers

A table with no headers can be hard to understand, especially for assistive tech users. Add th cells and a caption when the table benefits from context.

Styling rows without overcomplicating things

Row styling is usually best done with:

  • tbody tr:nth-child(even) for zebra stripes
  • tbody tr:hover for hover feedback
  • A class like .is-selected for state
<trclass="is-selected">
<td>Selected row</td>
<td>More data</td>
</tr>

Then style it in CSS.