HTML Table Basics
If you have ever used a spreadsheet, you already understand what a table is: a grid of cells in rows and columns. An HTML table is the web version. It is how you show a timetable, a price list, a set of scores, or any data where the position of a value tells you something.
The good news is that you only need four elements to build almost any table. The slightly tricky part is that HTML describes tables in an unusual way: you write rows, not columns. Once that clicks, everything else falls into place. Let's build your first table step by step.
What You Will Learnβ
- The four core elements:
<table>,<tr>,<th>, and<td> - How to build a table step by step, one row at a time
- How columns appear without being declared
- What browsers show by default, and how to add borders with CSS
- Which old table attributes to avoid
- The most common beginner mistakes, and how to fix them
The Four Core Elementsβ
| Element | Name | What it does |
|---|---|---|
<table> | Table | Wraps the whole table |
<tr> | Table Row | Creates one horizontal row |
<th> | Table Header | A heading cell. Bold and centered by default |
<td> | Table Data | A normal data cell |
The nesting is always the same:
table
ββ tr (a row)
ββ th or td (a cell)
ββ th or td
ββ th or td
A <table> contains rows. A row contains cells. Cells contain your content. Nothing else sits directly inside a row.
Build a Table, Step by Stepβ
Let's make a small table of three courses with their length and level. We will go one piece at a time.
Step 1: Start with the Tableβ
<table>
</table>
An empty table shows nothing. It is just a container.
Step 2: Add the Header Rowβ
The first row usually holds headings: the labels for each column. Use <tr> for the row and <th> for each heading.
<table>
<tr>
<th>Course</th>
<th>Weeks</th>
<th>Level</th>
</tr>
</table>
Three <th> cells mean three columns.
Step 3: Add the Data Rowsβ
Each following row has one <tr>, with one <td> for each column.
- HTML Code
- Browser Output
<table>
<tr>
<th>Course</th>
<th>Weeks</th>
<th>Level</th>
</tr>
<tr>
<td>Intro to HTML</td>
<td>4</td>
<td>Beginner</td>
</tr>
<tr>
<td>CSS Layouts</td>
<td>6</td>
<td>Intermediate</td>
</tr>
<tr>
<td>JavaScript Basics</td>
<td>8</td>
<td>Beginner</td>
</tr>
</table>
| Course | Weeks | Level |
|---|---|---|
| Intro to HTML | 4 | Beginner |
| CSS Layouts | 6 | Intermediate |
| JavaScript Basics | 8 | Beginner |
The demo uses CSS for borders and a header background (you will see how in a moment). Your browser would show the same data without them.
Columns Appear on Their Ownβ
Notice that you never wrote the word "column." The browser lines up the cells for you:
- The first cell of every row forms column 1.
- The second cell of every row forms column 2.
- And so on.
col 1 col 2 col 3
ββββββββββββββββββββ¬βββββββββ¬βββββββββββββββ
β Course β Weeks β Level β β row 1
β Intro to HTML β 4 β Beginner β β row 2
β CSS Layouts β 6 β Intermediate β β row 3
β JavaScript Basicsβ 8 β Beginner β β row 4
ββββββββββββββββββββ΄βββββββββ΄βββββββββββββββ
This means every row should have the same number of cells. Column widths adjust automatically to fit the longest content in each column.
What Does a Table Look Like by Default?β
Out of the box, a table is plain:
- No borders and no background. Only aligned text.
- Cells are as wide as their content needs, with tiny spacing.
<th>cells are bold and centered.<td>cells are left-aligned (in left-to-right languages).- The table is only as wide as its content.
That is on purpose. HTML describes the structure, and CSS handles the look.
Adding Borders with CSSβ
The simplest useful style is a border on the table and its cells. Use border-collapse: collapse so that neighboring borders merge into one clean line.
- HTML + CSS
- Without vs With
table {
border-collapse: collapse;
}
th,
td {
border: 1px solid #94a3b8;
padding: 6px 12px;
text-align: left;
}
th {
background: #e2e8f0;
}
Without CSS:
| Course | Weeks |
|---|---|
| Intro to HTML | 4 |
With CSS:
| Course | Weeks |
|---|---|
| Intro to HTML | 4 |
You will learn borders, stripes, spacing, and alignment in detail in Styling Tables. For now, remember one idea: HTML builds the table, CSS makes it pretty.
Whitespace Does Not Matterβ
HTML ignores extra spaces and line breaks between tags. These two tables are identical:
<!-- Spread out, easy to read -->
<table>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
<tr>
<td>Aisha</td>
<td>24</td>
</tr>
</table>
<!-- Squeezed onto few lines -->
<table><tr><th>Name</th><th>Age</th></tr><tr><td>Aisha</td><td>24</td></tr></table>
Use the spread-out version. Indenting each level makes the nesting obvious, and mistakes easier to spot.
What Can Go Inside a Cell?β
A <td> or <th> can hold nearly anything: text, numbers, links, images, lists, even another table.
- HTML Code
- Browser Output
<table>
<tr>
<th>Resource</th>
<th>Details</th>
</tr>
<tr>
<td><a href="#">HTML guide</a></td>
<td><strong>Free</strong>, 4 chapters</td>
</tr>
<tr>
<td>Starter files</td>
<td>
<ul>
<li>index.html</li>
<li>style.css</li>
</ul>
</td>
</tr>
</table>
| Resource | Details |
|---|---|
| HTML guide | Free, 4 chapters |
| Starter files |
|
You will explore cells more in Table Rows and Cells.
Empty Cellsβ
Sometimes there is no value. Keep the cell, and leave it empty or put a clear placeholder in it. Never delete the cell, or the row will be shorter than the others.
<tr>
<td>CSS Layouts</td>
<td>6</td>
<td></td> <!-- empty, but still there -->
</tr>
A short dash or "N/A" tells readers that the blank is intentional, which is kinder to people using screen readers.
An Important Detail: <tbody>β
You may have noticed that the demos wrap their rows in <tbody>. Browsers add a <tbody> automatically around loose rows, even if you did not write one. Writing it yourself is cleaner, and the next lessons explain why. For now, both versions are valid:
<!-- Allowed -->
<table>
<tr>...</tr>
</table>
<!-- Better habit -->
<table>
<tbody>
<tr>...</tr>
</tbody>
</table>
You will learn <thead>, <tbody>, and <tfoot> in Thead, Tbody, Tfoot.
Old Attributes You Should Not Useβ
Older tutorials style tables with HTML attributes. They are obsolete. Use CSS instead.
| Old attribute | What it did | Use this instead |
|---|---|---|
border="1" | Added borders | CSS border |
cellpadding | Padding inside cells | CSS padding on th, td |
cellspacing | Space between cells | CSS border-spacing or border-collapse |
width and height | Size of table and cells | CSS width and height |
align | Alignment | CSS text-align, margin |
bgcolor | Background color | CSS background |
A Real Example: A Simple Scheduleβ
- HTML Code
- Browser Output
<table>
<tr>
<th>Time</th>
<th>Session</th>
<th>Room</th>
</tr>
<tr>
<td>09:00</td>
<td>Welcome and setup</td>
<td>A</td>
</tr>
<tr>
<td>10:30</td>
<td>Build your first page</td>
<td>B</td>
</tr>
<tr>
<td>12:00</td>
<td>Lunch</td>
<td>Hall</td>
</tr>
</table>
| Time | Session | Room |
|---|---|---|
| 09:00 | Welcome and setup | A |
| 10:30 | Build your first page | B |
| 12:00 | Lunch | Hall |
Times use the 24-hour format, which is clear to readers in most countries.
Spot the Mistake: Uneven Rowsβ
The most common beginner error is a row with the wrong number of cells.
- Broken
- Fixed
<table>
<tr>
<th>Course</th>
<th>Weeks</th>
<th>Level</th>
</tr>
<tr>
<td>Intro to HTML</td>
<td>4</td>
<!-- forgot the third cell -->
</tr>
</table>
| Course | Weeks | Level |
|---|---|---|
| Intro to HTML | 4 |
The last row ends early. The table looks lopsided, and a screen reader cannot tell what the missing "Level" should be.
<table>
<tr>
<th>Course</th>
<th>Weeks</th>
<th>Level</th>
</tr>
<tr>
<td>Intro to HTML</td>
<td>4</td>
<td>Beginner</td>
</tr>
</table>
Before moving on, count the cells in each row. If the header row has 3 cells, every other row needs 3 too (unless you purposely merge cells, which you will learn in Colspan and Rowspan).
Common Mistakes to Avoidβ
- Rows with different cell counts. Keep them equal.
- Putting
<td>directly inside<table>. Cells must live inside a<tr>. - Forgetting closing tags. A missing
</tr>or</td>can scramble the whole table. - Using
<td>with bold text for headers. Use<th>, which carries real meaning. - Using a table for layout. Tables are for data.
- Using obsolete attributes such as
border,cellpadding, andbgcolor. - Typing numbers with units in every cell. Put "kg" or "$" in the header once.
- Leaving out the header row. Without it, readers do not know what each column means.
Practice Timeβ
Try these in your editor:
- Build a 3-column, 3-row table of your favorite books (title, author, year).
- Add a header row using
<th>cells. - Add borders with CSS:
border-collapse: collapseplusborderonth, td. - Add
paddingso the text is not cramped. - Add a row with an empty cell, and fill it with "N/A."
- Put a link inside one cell and a bulleted list inside another.
- Break the table on purpose by removing one cell, and look at what happens. Then fix it.
- Build a weekly timetable with the days as columns.
- Wrap your rows in
<tbody>. - Bonus: use your browser's developer tools to inspect the table, and find the
<tbody>the browser added.
Quick Recapβ
Click a question to check your answer.
1. Which four elements make up a basic table?
<table> is the container, <tr> is a row, <th> is a header cell, and <td> is a data cell.
2. Do you create columns in HTML?
No. You write rows and cells. The cells stacked in the same position across rows form the columns.
3. What is the difference between <th> and <td>?
<th> labels a column or row and is bold and centered by default. <td> holds ordinary data.
4. How do you add borders to a table?
With CSS, for example border: 1px solid on th and td, plus border-collapse: collapse on the table. The HTML border attribute is obsolete.
5. Why must every row have the same number of cells?
The columns are formed by the cells in each position. A missing cell makes the table lopsided, and screen readers cannot match the cells to their headings.
Key Takeawaysβ
- A table is built from
<table>,<tr>,<th>, and<td>. You write rows, and columns appear by themselves. - Use
<th>for headings and<td>for data. Keep an equal number of cells in every row. - Tables have no borders by default. Add them, along with spacing and color, with CSS.
- Cells can hold text, links, lists, and more. Leave empty cells in place, with a placeholder.
- Avoid obsolete attributes like
borderandcellpadding. Tables are for data, never for layout.
You now have the skeleton of a table. Next, take a closer look at what rows and cells can do in Table Rows and Cells, or return to the Tables overview.