Learn all about the <table> tag with HTML

Learn how to use the HTML <table> tag to create structured data tables. Syntax, practical examples, accessibility best practices, and CSS styling.
8 min read
Believemy logo

The <table> tag is the fundamental element for creating data tables in HTML. Whether you want to display statistics, compare products, or present structured information, HTML tables remain an essential tool in modern web development.

If you're just starting with HTML and want to master table creation along with other essential elements, our HTML course will guide you step by step through your learning journey.

Good to know

HTML tables are designed for displaying tabular data, not for page layout! Use CSS Grid or Flexbox for your page layouts 😊

 

Definition and syntax of the table tag

What is the table tag?

The <table> tag defines a table in HTML. It serves as the main container for organizing data into rows and columns. A well-structured table improves the readability of your information and makes it easier for users and search engines to understand.

A complete HTML table consists of several elements working together:

  • <table>: the main table container
  • <thead>: the table header (optional but recommended)
  • <tbody>: the table body containing the data
  • <tfoot>: the table footer (optional)
  • <tr>: a table row
  • <th>: a header cell (table header)
  • <td>: a data cell (table data)

 

Basic syntax

Here is the minimal structure of an HTML table:

HTML
<table>
  <tr>
    <th>Header 1</th>
    <th>Header 2</th>
  </tr>
  <tr>
    <td>Data 1</td>
    <td>Data 2</td>
  </tr>
</table>

This structure creates a simple table with one header row and one data row.

 

For a semantically correct and accessible table, we recommend using grouping elements:

HTML
<table>
  <caption>Believemy Course List</caption>
  <thead>
    <tr>
      <th scope="col">Course</th>
      <th scope="col">Duration</th>
      <th scope="col">Level</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>HTML & CSS</td>
      <td>20 hours</td>
      <td>Beginner</td>
    </tr>
    <tr>
      <td>JavaScript</td>
      <td>35 hours</td>
      <td>Intermediate</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="2">Total</td>
      <td>2 courses</td>
    </tr>
  </tfoot>
</table>

The <caption> element provides a descriptive title for the table, which is essential for accessibility.

 

Attributes of the table tag

Global attributes

The <table> tag accepts all global HTML attributes, including:

AttributeDescriptionExample
idUnique identifier for the tableid="courses-table"
classCSS classes for stylingclass="table-responsive"
styleInline CSS stylesstyle="width: 100%;"
titleTooltip on hovertitle="2024 Data"

 

Deprecated attributes to avoid

Some attributes were used in older versions of HTML but are now deprecated:

Warning

The attributes border, cellpadding, cellspacing, width, bgcolor, and align are deprecated. Use CSS to style your tables!

Here's how to replace these old attributes with modern CSS:

CSS
/* Replaces border="1" */
table {
  border-collapse: collapse;
}

table, th, td {
  border: 1px solid #333;
}

/* Replaces cellpadding="10" */
th, td {
  padding: 10px;
}

/* Replaces cellspacing="0" */
table {
  border-spacing: 0;
}

/* Replaces width="100%" */
table {
  width: 100%;
}

/* Replaces bgcolor */
table {
  background-color: #f5f5f5;
}

 

Practical examples of HTML tables

Simple data table

Let's start with a concrete example: a table listing learners and their scores on the Believemy platform:

HTML
<table>
  <caption>Learner Progress - Week 1</caption>
  <thead>
    <tr>
      <th scope="col">Learner</th>
      <th scope="col">Course</th>
      <th scope="col">Progress</th>
      <th scope="col">Score</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Marie Dupont</td>
      <td>HTML & CSS</td>
      <td>75%</td>
      <td>92/100</td>
    </tr>
    <tr>
      <td>Pierre Martin</td>
      <td>JavaScript</td>
      <td>45%</td>
      <td>88/100</td>
    </tr>
    <tr>
      <td>Sophie Bernard</td>
      <td>React</td>
      <td>90%</td>
      <td>95/100</td>
    </tr>
  </tbody>
</table>

Note the use of scope="col" on header cells, which tells screen readers that these headers apply to columns.

 

Table with merged cells

The colspan and rowspan attributes allow you to merge cells horizontally or vertically:

HTML
<table>
  <caption>Weekly Class Schedule</caption>
  <thead>
    <tr>
      <th scope="col">Time</th>
      <th scope="col">Monday</th>
      <th scope="col">Tuesday</th>
      <th scope="col">Wednesday</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">9am - 12pm</th>
      <td rowspan="2">HTML Course</td>
      <td>CSS Course</td>
      <td>Free</td>
    </tr>
    <tr>
      <th scope="row">2pm - 5pm</th>
      <td colspan="2">Practical Project</td>
    </tr>
  </tbody>
</table>

In this example:

  • rowspan="2" makes "HTML Course" span two rows
  • colspan="2" makes "Practical Project" span two columns
  • scope="row" indicates that the time cells are row headers

 

Responsive table with CSS

Tables can be problematic on mobile devices. Here's a technique to make them responsive:

HTML
<div class="table-container">
  <table class="table-responsive">
    <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Phone</th>
        <th>City</th>
        <th>Registration</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td data-label="Name">Jean Believemy</td>
        <td data-label="Email">jean@example.com</td>
        <td data-label="Phone">01 23 45 67 89</td>
        <td data-label="City">Paris</td>
        <td data-label="Registration">01/15/2024</td>
      </tr>
    </tbody>
  </table>
</div>
CSS
/* Horizontally scrollable container */
.table-container {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

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

.table-responsive th,
.table-responsive td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #ddd;
}

/* Alternative: card display on mobile */
@media screen and (max-width: 600px) {
  .table-responsive thead {
    display: none;
  }
  
  .table-responsive tr {
    display: block;
    margin-bottom: 1rem;
    border: 1px solid #ddd;
  }
  
  .table-responsive td {
    display: flex;
    justify-content: space-between;
    padding: 10px;
  }
  
  .table-responsive td::before {
    content: attr(data-label);
    font-weight: bold;
  }
}

This technique uses data-label attributes to display headers on mobile.

 

HTML table accessibility

Why accessibility is essential

Poorly structured tables are particularly difficult to navigate for screen reader users. An accessible table allows all users to understand the relationships between data.

 

Accessibility best practices

Here are the essential rules for creating accessible tables:

  • Always use <caption>: describes the table content
  • Use <th> for headers: never <td> with bold text
  • Add the scope attribute: col for columns, row for rows
  • Use <thead>, <tbody>, <tfoot>: clear semantic structure
  • Avoid nested tables: unnecessary complexity
HTML
<!-- Example of a perfectly accessible table -->
<table aria-describedby="table-desc">
  <caption>
    Believemy Course Pricing
    <span id="table-desc" class="sr-only">
      Comparative pricing table by level and duration
    </span>
  </caption>
  <thead>
    <tr>
      <th scope="col">Course</th>
      <th scope="col">Level</th>
      <th scope="col">Duration</th>
      <th scope="col">Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">HTML Fundamentals</th>
      <td>Beginner</td>
      <td>10 hours</td>
      <td>Free</td>
    </tr>
    <tr>
      <th scope="row">Advanced CSS</th>
      <td>Intermediate</td>
      <td>15 hours</td>
      <td>$49</td>
    </tr>
  </tbody>
</table>

 

ARIA attributes for complex tables

For tables with complex headers, use the id and headers attributes:

HTML
<table>
  <thead>
    <tr>
      <th id="name">Name</th>
      <th id="q1">Q1 2024</th>
      <th id="q2">Q2 2024</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th id="marie" headers="name">Marie</th>
      <td headers="marie q1">150</td>
      <td headers="marie q2">180</td>
    </tr>
  </tbody>
</table>

The headers attribute lists the identifiers of associated header cells.

 

Styling tables with CSS

Here's a solid CSS foundation for styling your tables:

CSS
/* Reset and base */
table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5rem 0;
  font-size: 0.95rem;
}

/* Headers */
thead {
  background-color: #2563eb;
  color: white;
}

th {
  padding: 1rem;
  text-align: left;
  font-weight: 600;
}

/* Cells */
td {
  padding: 0.875rem 1rem;
  border-bottom: 1px solid #e5e7eb;
}

/* Alternating colors */
tbody tr:nth-child(even) {
  background-color: #f9fafb;
}

/* Hover effect */
tbody tr:hover {
  background-color: #eff6ff;
}

/* Table footer */
tfoot {
  background-color: #f3f4f6;
  font-weight: 600;
}

 

Table with rounded borders

To achieve rounded borders on a table, we need to use a specific technique:

CSS
table {
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  overflow: hidden;
}

th:first-child {
  border-top-left-radius: 8px;
}

th:last-child {
  border-top-right-radius: 8px;
}

tbody tr:last-child td:first-child {
  border-bottom-left-radius: 8px;
}

tbody tr:last-child td:last-child {
  border-bottom-right-radius: 8px;
}
Good to know

Use border-collapse: separate to allow rounded borders, then border-spacing: 0 to remove spacing between cells.

 

Common mistakes to avoid

Using tables for page layout

This is the most common and problematic mistake:

HTML
<!-- ❌ BAD: table used for layout -->
<table>
  <tr>
    <td><nav>Menu...</nav></td>
    <td><main>Content...</main></td>
    <td><aside>Sidebar...</aside></td>
  </tr>
</table>

<!-- ✅ GOOD: use CSS Grid or Flexbox -->
<div class="layout">
  <nav>Menu...</nav>
  <main>Content...</main>
  <aside>Sidebar...</aside>
</div>

 

Forgetting semantic headers

HTML
<!-- ❌ BAD: headers with <td> and bold -->
<table>
  <tr>
    <td><strong>Name</strong></td>
    <td><strong>Age</strong></td>
  </tr>
</table>

<!-- ✅ GOOD: use <th> -->
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Age</th>
    </tr>
  </thead>
</table>

 

Tables too wide without responsive handling

HTML
<!-- ❌ BAD: table with many columns without wrapper -->
<table>...15 columns...</table>

<!-- ✅ GOOD: container with horizontal scroll -->
<div style="overflow-x: auto;">
  <table>...15 columns...</table>
</div>

 

Tables and SEO

How Google interprets tables

Search engines can extract and display data from your tables directly in search results. To optimize your tables for SEO:

  • Use descriptive headers: Google uses <th> to understand structure
  • Add a relevant <caption>: helps understand context
  • Structure data correctly: <thead>, <tbody>, <tfoot>
  • Avoid images of text: text in tables is indexable

 

Browser compatibility

The <table> tag and its associated elements enjoy excellent compatibility:

BrowserMinimum VersionSupport
Chrome1.0✅ Full
Firefox1.0✅ Full
Safari1.0✅ Full
Edge12✅ Full
Opera7.0✅ Full
Internet Explorer4.0✅ Full

HTML tables have been supported by all browsers since their earliest versions.

 

Frequently asked questions about the table tag

Question

What is the difference between <th> and <td>?

The <th> tag (table header) represents a header cell that describes the content of its column or row. It is automatically bold and centered by default. The <td> tag (table data) contains standard table data. Always use <th> for headers to improve accessibility and semantics of your table.

 

Question

How do I merge cells in an HTML table?

Use the colspan attribute to merge cells horizontally (across multiple columns) and rowspan to merge vertically (across multiple rows). For example, <td colspan="3"> creates a cell that spans 3 columns, while <td rowspan="2"> creates a cell that spans 2 rows.

 

Question

Can I use tables for website layout?

No, this practice is strongly discouraged and has been considered obsolete for many years. Tables are designed only for displaying tabular data. For layout, use modern CSS technologies like Flexbox or CSS Grid, which offer more flexibility and are much better for accessibility and SEO.

 

Question

How can I learn HTML and CSS?

To master HTML, CSS, and professional table creation, we recommend following our HTML course. This course will guide you step by step through learning the fundamentals to advanced techniques, with practical exercises and concrete projects.

Related terms

Discover our hTML and CSS glossary

Browse the terms and definitions most commonly used in HTML and CSS development.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.