HTML Tables — A Beginner's Guide (2024)

Explore the basics of HTML Tables—perfect for web developers and content creators, this guide demystifies the art of creating clean, accessible tables, offering essential tips and SEO insights.

Josh Hartman
Josh Hartman
Last updated: May 15, 2024
Table of Contents

HTML tables allow you to display data in rows and columns on a webpage. New web technologies such as CSS grid and flexbox provide additional layout options. However, tables remain valuable for displaying tabular data and spreadsheet-like information. 

In this beginner's guide, we'll walk through everything you need to know to start building these tables from scratch.

Tip: If you're interested in learning about HTML tables but would like to save yourself some time building them, you can use our best-in-class HTML Table Generator.

Who Can Benefit from This Beginner's Guide?

I crafted this guide for a diverse audience, including:

  • Web Developers Starting Out with HTML: Whether you're just starting with HTML or already know your way around, this guide helps you build a strong foundation for working with HTML tables.
  • Marketers and Content Creators: Building long-form content that involves presenting data sets? HTML tables can be your ally, and this guide will equip you with the knowledge to use them effectively.
  • Anyone Needing to Display Relational Datasets: No matter your experience, if you want to display data on a webpage while keeping the connections clear, this guide is for you.

We'll cover all the basics, best practices, and details you need to start building HTML tables. You do not need any prior HTML experience to follow along. Let's dive in!

Introduction to HTML Tables

The <table> tag defines HTML tables. The <tr> tag defines each row inside a table. Within each row, you define data using either the <td> or <th> tag, depending on its location and context.

<table> <thead> <tr> <th>Team</th> <th>Sport</th> <th>City</th> </tr> </thead> <tbody> <tr> <td>Manchester United</td> <td>Soccer</td> <td>Manchester</td> </tr> <tr> <td>New York Yankees</td> <td>Baseball</td> <td>New York City</td> </tr> <tr> <td>Los Angeles Lakers</td> <td>Basketball</td> <td>Los Angeles</td> </tr> </tbody> </table>
Team Sport City
Manchester United Soccer Manchester
New York Yankees Baseball New York City
Los Angeles Lakers Basketball Los Angeles

In this example, we created a simple 3x4 table with 3 columns and 4 rows. Pretty easy, right?

Note: In this article, the tables have the same styles as our own tables (grey header, striped rows, etc.). We will discuss different styles in some parts. Generally, your tables will adopt the styles of your website. However, you can modify them using CSS.

When to Use Tables

Tables are important for web developers and content creators, providing many benefits that make them necessary in different situations. Here are some key reasons to consider using them in your projects:

Display Tabular Data with Ease

Tables organize data in rows and columns, making it easier to present and arrange information in a structured manner. This makes them ideal for showcasing data sets that follow a relational structure.

Effortless Horizontal and Vertical Alignment

Tables are good at aligning text both horizontally and vertically. This flexibility in alignment ensures a clean and visually appealing presentation of your content.

Semantic Structure for Enhanced Readability

By utilizing HTML tables, you impart semantic meaning to your data. This improves code readability and helps search engines understand content structure, leading to better SEO.

Optimized for SEO and Data Relationships

Tables play a crucial role in improving Search Engine Optimization (SEO) by clearly displaying relational data. HTML tables organize data like financial reports, sports results, and train schedules for easy presentation and understanding. They help show the connections between different pieces of information.

When NOT to Use Tables

While tables are useful for organizing tabular data, there are situations where they may not be the best choice. Here are some instances where it's not a good idea to use them:

Layout and Design

You should not use tables for page layout or to create a grid-based structure. Instead, use CSS for layout purposes. CSS is for presentation; using tables for layout can make code harder to maintain and more complicated.

Responsive Layout Design

Tables can be challenging to make responsive for different screen sizes. Modern web design favors responsive layouts that adapt to various devices, such as smartphones and tablets. Using tables for layout can make it difficult to achieve a responsive design.

Accessibility (With Complexity)

Tables can present challenges for accessibility. Screen readers struggle with tables used for layout, making it harder for disabled users to access content. Proper HTML5 structural elements and semantic markup are essential for creating accessible content.

Non-Tabular Data Presentation

If the content you're presenting is not tabular data, using a table is not a good fit. For non-tabular content, use semantic HTML elements that accurately describe the structure and purpose of the content.

Mobile Experience

Tables can be difficult to navigate on small screens. For mobile users, try different ways to show information on smaller screens, like collapsing columns or using responsive design techniques.

HTML Refresher

Before diving into the details of tables, let's recap some key HTML basics.

Tip: If you're already well-versed in HTML, feel free to skip to the next section of your choice.

HTML stands for HyperText Markup Language. HTML documents contain text content along with HTML tags that apply structure and meaning to content.

Here are some common HTML tags:

  • <html> - The root element that contains the entire HTML document
  • <head> - Contains metadata about the page
  • <body> - Contains the visible page content
  • <h1> to <h6> - Headings, <h1> is the most important
  • <p> - Paragraph text
  • <ul>, <ol>, <li> - Unordered, ordered, and list item tags for lists
  • <img> - Adds an image
  • <a> - Creates a hyperlink
  • <table> - Defines a table (the element you're here for!)

HTML tags provide semantic structure and meaning to content. Most tags have an opening and closing tag with the content in between:

<tagname>Content goes here...</tagname>

Some tags are self-closing with just one tag:

<img src="image.jpg" />

Now that we've reviewed some HTML basics, let's look at the anatomy of an HTML table.

Anatomy of an HTML Table

As mentioned earlier, you define an HTML table with the <table> tag. The <tr> tag defines each row inside the table. The <td> tag defines data in table cells inside each row.

Some additional HTML table elements include:

  • <th> - Defines a table header cell
  • <thead> - Groups header content in a table
  • <tbody> - Groups table body content
  • <tfoot> - Groups footer content in a table
  • <caption> - Provides a caption or title for a table

These elements help add additional semantic meaning to tables.

Now let's walk through building a simple HTML table step-by-step.

Building a Simple HTML Table

Follow along as we build a simple HTML table to display a list of products and prices:

Tip: For this process, you can use our handy HTML Table Generator. However, we’ll also show you the manual way of doing it.

Step 1: Add a <table> element along with the <caption> element to add a title

We're going to start off with the most basic table element — the <table> tag. From here, we're going to add a <caption> that describes our table. In this case, we'll call it "Product Pricing."

<table> <caption>Product Pricing</caption> </table>
Product Pricing

As you can see, no other table elements have been added aside from the caption. Let's change that!

Step 2: Add a <thead> element and nested <tr> and <th> elements to define the table header row

Time to get semantical (is that even a word?). Let's add our <thead> tag to define our table header along with a single <tr> tag (since it's still a row in the table). Inside of that <tr> tag, we'll add 2 <th> tags to semantically establish them as header cells.

<table> <caption>Product Pricing</caption> <thead> <tr> <th>Product</th> <th>Price</th> </tr> </thead> </table>
Product Pricing
Product Price

Looking good! Let's keep moving.

Step 3: Add a <tbody> element and use <tr> and <td> to add table rows and data cells

Much like what we did for the header of the table, we can now establish the body of the table using the <tbody> tag. We can use <tr> and <td> tags to show product details like name and price in this section.

<table> <caption>Product Pricing</caption> <thead> <tr> <th>Product</th> <th>Price</th> </tr> </thead> <tbody> <tr> <td></td> <td></td> </tr> <tr> <td></td> <td></td> </tr> <tr> <td></td> <td></td> </tr> </tbody> </table>
Product Pricing
Product Pricing

Our table now has semantic structure. We're almost done!

Step 4: Fill in the content for each cell

Now, we can add our content into each table cell. Your content will almost always come in the form of text (with few exceptions, especially for modern tables).

<table> <caption>Product Pricing</caption> <thead> <tr> <th>Product</th> <th>Price</th> </tr> </thead> <tbody> <tr> <td>Product A</td> <td>$19.99</td> </tr> <tr> <td>Product B</td> <td>$24.99</td> </tr> <tr> <td>Product C</td> <td>$14.99</td> </tr> </tbody> </table>
Product Pricing
Product Price
Product A $19.99
Product B $24.99
Product C $14.99

Step 5: Add any additional styling or attributes

We now have a near complete table. However, we'd now like to link each product to it's given product page. Let's add some <a> tags in order to establish links.

<table> <caption>Product Pricing</caption> <thead> <tr> <th>Product</th> <th>Price</th> </tr> </thead> <tbody> <tr> <td><a href="#product-a">Product A</a></td> <td>$19.99</td> </tr> <tr> <td><a href="#product-b">Product B</a></td> <td>$24.99</td> </tr> <tr> <td><a href="#product-c">Product C</a></td> <td>$14.99</td> </tr> </tbody> </table>
Product Pricing
Product Price
Product A $19.99
Product B $24.99
Product C $14.99

And that's the basics of building out an HTML table! The <table>, <tr>, <td>, and <th> elements provide the overall table structure. Tags like <thead>, <tbody>, and <caption> add semantic meaning.

Next let's look at some key table attributes to control styling and layout.

HTML Table Attributes

Rowspan Attribute

The rowspan attribute is used to make a cell span multiple rows in a table. This can be particularly useful when dealing with data that should be grouped across several rows.

<table> <tr> <td rowspan="2">Row 1, Cell 1</td> <td>Row 1, Cell 2</td> <td>Row 1, Cell 3</td> </tr> <tr> <!-- This cell spans two rows --> <td>Row 2, Cell 2</td> <td>Row 2, Cell 3</td> </tr> <tr> <td>Row 3, Cell 1</td> <td>Row 3, Cell 2</td> <td>Row 3, Cell 3</td> </tr> </table>
Row 1, Cell 1 Row 1, Cell 2 Row 1, Cell 3
Row 2, Cell 2 Row 2, Cell 3
Row 3, Cell 1 Row 3, Cell 2 Row 3, Cell 3

In this example, the first cell in the first row has a rowspan of 2, causing it to span the first and second rows. This creates a visual grouping effect for the data.

Colspan Attribute

Similarly, the colspan attribute allows a cell to span multiple columns, enabling the consolidation of data horizontally.

<table> <tr> <td>Row 1, Cell 1</td> <td colspan="2">Row 1, Cell 2 and 3</td> </tr> <tr> <td>Row 2, Cell 1</td> <td>Row 2, Cell 2</td> <td>Row 2, Cell 3</td> </tr> </table>
Row 1, Cell 1 Row 1, Cell 2 and 3
Row 2, Cell 1 Row 2, Cell 2 Row 2, Cell 3

In this case, the second cell in the first row has a colspan of 2, causing it to span the second and third columns. This creates a wider cell that accommodates the data intended for both columns.

Combining Rowspan and Colspan

You can combine rowspan and colspan attributes to create complex table layouts.

<table> <tr> <td rowspan="2">Row 1, Cell 1</td> <td colspan="2">Row 1, Cell 2 and 3</td> </tr> <tr> <!-- This cell spans two rows and two columns --> <td rowspan="2" colspan="2">Row 2, Cell 2 and 3</td> </tr> <tr> <td>Row 3, Cell 1</td> <td>Row 3, Cell 2</td> </tr> </table>
Row 1, Cell 1 Row 1, Cell 2 and 3
Row 2, Cell 2 and 3
Row 3, Cell 1 Row 3, Cell 2

In this example, the second cell in the first row spans two columns (colspan="2") and two rows (rowspan="2"), creating a larger cell that spans multiple rows and columns simultaneously.

Understanding and effectively using rowspan and colspan attributes can significantly enhance the presentation of data in HTML tables, allowing for more flexible and visually appealing layouts.

However, it's important to keep accessibility in mind—the more complex the table layout, the more challenging your data can be to interpret, both by humans and screen readers.

Depreciated Attributes

Border Attribute

The border attribute adds a visible border to the table and cells. This attribute is deprecated in HTML5, meaning CSS borders should be used instead:

/* CSS for adding a visible border to the table and cells */ table { border-collapse: collapse; border: 1px solid black; /* You can adjust the width and color */ } td, th { border: 1px solid black; /* You can adjust the width and color */ padding: 8px; /* Adjust the padding as needed */ }

In this example, border-collapse: collapse; is used to collapse the borders into a single border, and border: 1px solid black; is applied to both the table and table cells (<td> and <th>).

Cellpadding and Cellspacing

cellpadding controls padding inside each cell, while cellspacing controls spacing between cells. Both are deprecated in HTML5 in favor of CSS:

/* CSS for controlling padding inside each cell */ td, th { padding: 10px; /* Adjust the padding as needed */ } /* CSS for controlling spacing between cells */ table { border-collapse: separate; border-spacing: 10px; /* Adjust the spacing as needed */ }

In this example, padding: 10px; is applied to both <td> and <th> elements to control the padding inside each cell. border-collapse: separate; and border-spacing: 10px; are used to control the spacing between cells.

Now that we've covered table structure and attributes, let's look at styling tables with CSS in greater detail.

Styling HTML Tables with CSS

While HTML provides the overall table structure, CSS is used to style and layout tables.

Some common styling includes:


Setting the layout of an HTML table involves controlling its width and centering it horizontally. This can be achieved through CSS styles. For example:

/* CSS for setting the width and centering the table */ table { width: 80%; /* Adjust the width as needed */ margin: 0 auto; /* Center the table horizontally */ }

Here, the width property is used to define the overall width of the table, and margin: 0 auto; centers the table by setting equal margins on the left and right.


Adding borders to the table and cells enhances the visual structure. You can control the border color, style, and width using CSS properties:

/* CSS for adding borders to the table and cells */ table, th, td { border: 1px solid black; /* Adjust the width and color as needed */ } /* Additional styling for table header cells (th) */ th { background-color: #f2f2f2; /* Background color for headers */ font-weight: bold; /* Bold text for headers */ }

In this example, the border property is used to set a solid black border around the table and its cells. Additional styling is applied to header cells (<th>) for improved visual distinction.

Zebra Stripes

Adding zebra stripes involves applying alternating background colors to rows, which enhances readability. Here's an example:

/* CSS for adding zebra stripes to the table */ tr:nth-child(even) { background-color: #f9f9f9; /* Background color for even rows */ }

This CSS selector targets even rows (tr:nth-child(even)) and applies a background color, creating a visually appealing zebra stripe effect.

Text Alignment

Aligning text within cells improves the overall presentation. You can control horizontal text alignment using the text-align property:

/* CSS for aligning text horizontally in cells */ td, th { text-align: center; /* Adjust as needed (center, left, right) */ }

This example centers text horizontally within both regular cells (<td>) and header cells (<th>), but you can customize it based on your layout preferences.


Adding padding inside cells helps create spacing between the content and cell borders. Here's an example:

/* CSS for adding padding inside cells */ td, th { padding: 10px; /* Adjust the padding as needed */ }

In this case, the padding property is used to add 10 pixels of padding to both regular cells (<td>) and header cells (<th>), enhancing the visual appeal and readability of the table.

There are tons of styling options for formatting tables with CSS. These are just a few!

Accessible HTML Tables

When building tables, it's important to keep accessibility in mind:

Utilizing the <caption> Element

When creating HTML tables, it's good practice to use the <caption> element to provide a brief and concise description of the table's purpose and content. The <caption> element serves as a title or heading for the table, making it more accessible and providing context to users or assistive technologies.

Associating Headers with Data Cells Using <th>

To enhance the accessibility and understanding of your table, use the <th> element to designate header cells. Header cells should be used for the labels of rows and columns. By associating headers with corresponding data cells, you create a clear and meaningful relationship within the table. This association is particularly valuable for users relying on screen readers, as it helps them interpret the structure of the table more effectively.

Implementing Semantic Elements like <thead>, <tbody>, and <tfoot>

Break up your table into logical sections using semantic elements such as <thead>, <tbody>, and <tfoot>. These elements help to organize the content and improve the structure of the table. The <thead> element contains header information, <tbody> includes the main content, and <tfoot> holds the footer or summary information. This segmentation not only enhances readability but also contributes to a more accessible and well-structured table.

Keeping Markup Clean and Well-Structured

Maintain clean and well-structured HTML markup when creating tables. Avoid unnecessary nesting of tables and complex cell spanning, as these practices can make the table more challenging to navigate for both users and assistive technologies. Clean and well-organized markup ensures that the table is easily understandable, promoting better accessibility and a more seamless user experience.

Paying attention to accessibility ensures your HTML tables are usable and understandable to all readers.

Advanced HTML Tables (With Examples)

We've covered the basics, but there are a few more advanced table features to be aware of:

Merged Cells

While we touched on colspan and rowspan attributes earlier, their advanced usage involves merging cells across rows and columns. These attributes allow a single cell to span multiple columns or rows, creating a more complex layout:

<!-- Example of merged cells using colspan and rowspan --> <table> <tr> <td rowspan="2">Merged Cell</td> <td colspan="2">Spanned Cells</td> </tr> <tr> <td>Row 2, Cell 1</td> <td>Row 2, Cell 2</td> </tr> </table>

Here, the first cell spans two rows (rowspan="2") and the second cell spans two columns (colspan="2"), resulting in a table with merged and spanned cells.

Nested Tables

Though it's not usually recommended because it makes the code more complicated, nested tables involve putting one table inside another. It can help with making detailed layouts, but it's best to use it carefully so that the code (and your table) stays easy to read. Honestly, this isn't something people use a lot, and it's usually better not to.

<!-- Example of a nested table --> <table> <tr> <td>Main Table Cell</td> <td> <!-- Nested Table --> <table> <tr> <td>Nested Table Cell 1</td> <td>Nested Table Cell 2</td> </tr> </table> </td> </tr> </table>

Nested tables can be useful but use them sparingly as they create more complex markup.

Responsive Tables

Responsive design is crucial for tables, ensuring they adapt to various screen sizes. Advanced techniques involve using CSS and HTML to address responsive challenges:

Horizontal Scrolling

/* CSS for horizontal scrolling on smaller screens */ .table_component { overflow: auto; }

Wrap your table within a container and apply the overflow: auto; property to enable horizontal scrolling on smaller screens. This prevents the table from expanding beyond the viewport width.

Hiding Less Important Columns

<table> <tr> <td>Row 1, Cell 1</td> <td class="less-important-column">Row 1, Cell 2 (Less Important)</td> <td>Row 1, Cell 3</td> <td>Row 1, Cell 4</td> </tr> <tr> <td>Row 2, Cell 1</td> <td class="less-important-column">Row 2, Cell 2 (Less Important)</td> <td>Row 2, Cell 3</td> <td>Row 2, Cell 4</td> </tr> <tr> <td>Row 3, Cell 1</td> <td class="less-important-column">Row 3, Cell 2 (Less Important)</td> <td>Row 3, Cell 3</td> <td>Row 3, Cell 4</td> </tr> </table>
/* CSS for hiding columns on small screens */ @media screen and (max-width: 600px) { .less-important-column { display: none; } }

Use media queries to hide less important columns on smaller screens, improving readability and focusing on essential content.

Adjusting Font Sizes and Padding

/* CSS for decreasing font sizes and padding on smaller screens */ @media screen and (max-width: 600px) { table { font-size: 14px; } td, th { padding: 5px; } }

Modify font sizes and padding for tables and cells on smaller screens to maintain a balanced design.

Incorporating these advanced features enhances the versatility of HTML tables, allowing for more sophisticated layouts and ensuring a seamless user experience across various devices and screen sizes.

Best Practices

While tables are a powerful tool, their misuse can lead to accessibility issues, poor performance, and difficulties in maintaining code. In this section, we will explore best practices to ensure that your HTML tables are well-structured, semantically meaningful, and accessible. By following these guidelines, you can enhance the user experience, improve search engine optimization, and create more maintainable and future-proof tables.

Use HTML to Define the Table Structure and Relationships

The HTML elements like:

should be used to set up the overall table structure and relationships between data. Let HTML handle the semantics. Don't try to achieve visual layouts with complex HTML markup. Keeping the HTML clean and straightforward makes it easier to maintain and style.

Use Semantic HTML Elements to Add Meaning

Make use of HTML5 semantic elements like:

to add meaning to the table structure. Use <th> to indicate table header cells explicitly. Semantic elements lead to better accessibility and SEO.

Style the Table with CSS

Once the HTML defines the overall structure, use CSS for all styling and layout needs. Things like borders, background colors, height/width, alignment, padding, font styles, etc. should all be handled in CSS. This separation of concerns leads to cleaner and more maintainable code.

Keep Markup Lean and Well-Formatted

Here are some quick and easy tips:

  • The HTML markup itself should be lean, clean and well formatted.
  • Use proper indentation of nested elements.
  • Avoid unnecessary nesting or complexity.
  • Keep code lines to reasonable lengths.
  • Well organized and commented code is much easier to revisit later on.

Make Tables Accessible

Keep accessibility in mind when structuring tables. Here are some ways to do it:

  • Associate headers with data cells using <th>.
  • Provide captions and summaries.
  • Use semantic elements.
  • Linearize logically.
  • Ensure color contrast.

All these practices help make tables usable by those with disabilities.

Validate HTML

Use the W3C HTML Validator to check for any errors or warnings in table markup. Fixing validation issues can uncover problems like improper nesting, malformed attributes, and badly formatted code. Proper validation helps ensure proper rendering across different browsers.

Note: If you use our HTML Table Generator, the code will be semantically correct out-of-the-box.

Following coding best practices will improve your table markup and user experience. Even if you're not a developer, understanding the basics will go a long way.


You should now have a good understanding of how to create HTML tables!

We covered:

  • Basic table structure using <table>, <tr>, <td>, and <th>.
  • Add semantic meaning using <caption>, <thead>, <tbody> and <tfoot>.
  • Adding borders, spacing, styling, and layout with HTML attributes and CSS
  • Best practices for accessible semantic markup
  • Additional table features like spanning, nesting, and responsiveness

HTML tables provide a handy way to display relational datasets on webpages. Start putting your new skills into practice by building out HTML tables for your own projects!

Helpful Resources

Here are some recommended resources for learning more about HTML tables:

And for a complete guide to web development, take a look at The Odin Project.

Build & Style HTML Tables — No Coding Skills Required.

Josh Hartman

Josh Hartman

I'm Josh, the founder of HTML Tables and eklipse Development, a Webflow Professional Partner. I've always loved seamless web experiences and take pride in merging code with creative design. Aside from this website, I'm currently building How Much Concrete, a state-of-the-art concrete calculator. Beyond the digital realm, I love the outdoors & fitness. Find me on a trail or in the gym!