HTML Tables - Basics

Chapter 30 18 mins

Learning outcomes:

  1. Creating tables using <table>
  2. Table rows (<tr>)
  3. Table cells — heading cells (<th>) and data cells (<td>)
  4. Simple table examples
  5. Table captions (<caption>)

Introduction

In this chapter, we shall explore the basics of how to create tables in HTML.

We'll go over the five core elements — <table>, <tr>, <th>, <td>, and <caption> — and see how these elements integrate together to produce very basic table layouts. We'll also consider some basic CSS properties to style these tables, and much more on this road.

Let's get started.

Creating a table using <table>

The cornerstone of tables in HTML is the <table> element. It's the entry point into creating any kind of a table in HTML. You need a table, you need <table>. As simple as that.

Let's start building a table to denote some programming languages along with the year in which they were released to the public.

Something as follows:

Programming languageRelease year
JavaScript1995
Java1995
C++1985

Obviously, the first thing we need is <table>, so let's go on and create that:

<table></table>

However, <table> won't do anything magical on its own. It needs to be paired with other elements inside it to bring a table to life in the browser.

While those elements will differ depending on the way we want to structure our tables, generally speaking, here's what we require at the minimum:

  • <tr> to denote rows of the table.
  • <th> to denote headings of the table.
  • <td> to denote actual data of the table in individual cells.

Let's go into the details of each of these.

Table rows via <tr>

A table is comprised of a multitude of entries, commonly referred to as rows.

For example, in the table shown above, we have four rows — one is a row denoting all the headings of the table while the rest of the rows each simply denotes a data entry (and we have a total of 3 of them).

To create a row in an HTML table, we use the <tr> element.

As you can probably guess, <tr> stands for 'table row'. It serves to create a new row inside a <table> element. A <table> element can directly contain <tr>.

A table can also directly contain other elements such as <thead>, <tbody> and <tfoot>, but we shall explore these elements later in this unit.

Not surprisingly, a <table> can contain as many <tr>s as we want in it.

Let's now use <tr> to continue our <table> code that we wrote above. Since the table that we're trying to replicate has four rows, we'll need four <tr>s:

<table>
   <tr></tr>
   <tr></tr>
   <tr></tr>
   <tr></tr>
</table>

Great. Now we need individual cells in each of these rows.

Heading cells (<th>) and data cells (<td>)

A cell is basically just a unit of information inside a table. Cells simply refer to the individual sections that we get by the intersection of the horizontal and vertical lines inside a table.

Now, cells can either define headings or they could define actual data of the underlying table.

In HTML, the former is denoted using <th> and the latter is denoted using <td>.

  • The <th> element, which stands for 'table heading', serves to create a heading cell inside a given table row (which is denoted using <tr>, as we learnt a while ago).
  • Similarly, <td>, which stands for 'table data', serves to create a data cell inside a given table row.

By default, all the cells inside a table row, i.e. <th> and <td>, are displayed adjacent to one another in the HTML output.

Anyways, continuing our table code above, let's now define the table's header, using <th>:

<table>
   <tr>
<th>Programming language</th>
<th>Release year</th> </tr> <tr></tr> <tr></tr> <tr></tr> </table>

There are two headings to denote and, likewise, we have two <th>s.

Next, let's define each of the individual data entries in the table, using <td> in the remaining <tr> elements:

<table>
   <tr>
      <th>Programming language</th>
      <th>Release year</th>
   </tr>
   <tr>
<td>JavaScript</td>
<td>1995</td> </tr> <tr>
<td>Java</td>
<td>1995</td> </tr> <tr>
<td>C++</td>
<td>1985</td> </tr> </table>

And that's our table.

Here's the output produced:

Programming languageRelease year
JavaScript1995
Java1995
C++1985

Doesn't look really nice but content-wise it's exactly the same table that we saw before.

As you'd agree, it's not really any difficult to create a table in HTML.

No matter how complex a table's structure is, we only need to employ these three elements to create a table in HTML: <tr> for individual rows, <th> for headings (inside <tr>), and <td> for actual data (again inside <tr>).

In the following section, we create four similar kinds of such simple tables to brush up on our skills of creating tables in HTML.

Adding borders to a table

The table we created above can be termed as being borderless, without any borders surrounding it or any cell inside of it. Typically, however, tables in HTML do have borders.

So how to add borders to HTML tables?

Well, there are quite a few ways:

  • Using the border HTML attribute of a <table>.
  • Applying CSS styles on a table and/or its constituent elements.

Let's start off with the first one in the list.

The border attribute

The <table> element can be provided a border attribute in order to apply borders around it and each of its individual cells.

The value can either be 0 to mean no borders, or any integer greater than 0 to mean border of that thickness.

For example, a border="1" attribute means a border of 1 pixel thickness. Similarly, border="2" means a border of 2 pixel thickness. And so on and so forth.

Following we apply a border to the table we created just a while ago:

<table border="1">
   <tr>
      <th>Programming language</th>
      <th>Release year</th>
   </tr>
   <tr>
      <td>JavaScript</td>
      <td>1995</td>
   </tr>
   <tr>
      <td>Java</td>
      <td>1995</td>
   </tr>
   <tr>
      <td>C++</td>
      <td>1985</td>
   </tr>
</table>

Here's the output produced:

Programming languageRelease year
JavaScript1995
Java1995
C++1985

Carefully notice how there is a border around the table and around each individual cell.

This is one of the two ways table bordering is done in browsers. It's known as separated bordering, as the borders are separated from one another by a given amount of space.

This space can be controlled using CSS, specifically using the border-spacing property.

We can switch this behavior off and transition to continuous bordering via the border-collapse CSS property on a <table>.

This is shown as follows:

<table border="1" style="border-collapse: collapse">
   <tr>
      <th>Programming language</th>
      <th>Release year</th>
   </tr>
   <tr>
      <td>JavaScript</td>
      <td>1995</td>
   </tr>
   <tr>
      <td>Java</td>
      <td>1995</td>
   </tr>
   <tr>
      <td>C++</td>
      <td>1985</td>
   </tr>
</table>
Programming languageRelease year
JavaScript1995
Java1995
C++1985

See how the borders have literally been collapsed together, putting aside all the spacing between them previously.

The CSS border property

Apart from using the border HTML attribute, we can also use the CSS border property to apply borders to a table, but this time in many different ways.

Here's the general form of the value assigned to border: width type color.

  • width specifies the width of the border.
  • type specifies the type of the border, i.e. dashed, dotted, or solid.
  • color specifies the color of the border. By default, it's black.

Let's consider some examples.

Suppose we want to only apply borders around a table. In this case, we can set the border property on the <table> element specifically.

This is illustrated below:

<table style="border: 1px solid black">
   <tr>
      <th>Programming language</th>
      <th>Release year</th>
   </tr>
   <tr>
      <td>JavaScript</td>
      <td>1995</td>
   </tr>
   <tr>
      <td>Java</td>
      <td>1995</td>
   </tr>
   <tr>
      <td>C++</td>
      <td>1985</td>
   </tr>
</table>

The value 1px solid black assigned to the border property means a 1 pixel thick, solid border, colored black.

Programming languageRelease year
JavaScript1995
Java1995
C++1985
Remember to remove the border HTML attribute from the <table> element before applying these CSS border styles.

Now suppose that we want to apply borders around every single row. Since, individually doing so (by applying the border style in every <tr> element) would be quite tedious, we'll leverage the <style> element for this, along with the tr CSS selector.

The border we'll apply would be the same 1px, solid, black-colored border we applied above.

Consider the following HTML:

<style> tr { border: 1px solid black; } </style>
<table> <tr> <th>Programming language</th> <th>Release year</th> </tr> <tr> <td>JavaScript</td> <td>1995</td> </tr> <tr> <td>Java</td> <td>1995</td> </tr> <tr> <td>C++</td> <td>1985</td> </tr> </table>
Programming languageRelease year
JavaScript1995
Java1995
C++1985

Surprisingly enough, this doesn't have any effect.

"Why" you ask?

Well, that's because of the way browsers render HTML tables in the separated bordering approach, which is the default. As we learnt above, we can change this approach using the border-collapse property.

Let's do that and then see the result:

<style>
   table { border-collapse: collapse; }
   tr { border: 1px solid black; }
</style>
Programming languageRelease year
JavaScript1995
Java1995
C++1985

Perfect! Thanks to the transition from the default, separated bordering behavior of the given table to continuous bordering, the given border rules get applied for real.

Table captions via <caption>

Since the early days of HTML, the <caption> element has remained an integral part of tables. So what exactly is <caption>?

The <caption> element is used to define a table caption in HTML. A table caption in this regard is a piece of text to describe what information the table contains.

For example, going with the table presented at the start of this chapter, it showcases a couple of programming languages along with their release year; hence, we could caption the table something as follows: 'Some programming languages, with their release year.'

Of course, there's no hard and fast rule to abide by in defining table captions — we can give any captions as we want to. However, clearly our captions must be self-explaining and not require explanations of their own!

In the following code, we caption our programming languages table:

<table>
<caption>Some programming languages, with their release year.</caption> <tr> <th>Programming language</th> <th>Release year</th> </tr> <tr> <td>JavaScript</td> <td>1995</td> </tr> <tr> <td>Java</td> <td>1995</td> </tr> <tr> <td>C++</td> <td>1985</td> </tr> </table>
Some programming languages, with their release year.
Programming languageRelease year
JavaScript1995
Java1995
C++1985

Notice that <caption> is only as long as the length of its associated table; it can't be larger than the table.

Seems pretty simple to use <caption>, doesn't it?

While we're here, it's worthwhile discussing a couple of important points regarding <caption>.

<caption> must be the first child of <table>

Firstly, <caption> can only appear inside <table>, and secondly, it must be the <table> element's first child.

That is, if we wish to caption a table using <caption> (which is the standard way), the <caption> element must be the first element directly inside <table>.

It's possible to caption a table using a <p> (or worse yet, a <div>) before or after a <table> element but that doesn't constitute good HTML coding practice. The standard way to caption a table is to use <caption> and that inside <table>.

So in this way, the following code is semantically invalid:

<table>
   <tr>
      <th>Programming language</th>
      <th>Release year</th>
   </tr>
   <tr>
      <td>JavaScript</td>
      <td>1995</td>
   </tr>
   <!-- <caption> can't be the last element! -->
<caption>Some programming languages, with their release year.</caption> </table>

The <caption> element comes last in the <table> here and that's precisely the issue in the code.

The correct way to express this is as follows:

<table>
   <!-- This is correct -->
<caption>Some programming languages, with their release year.</caption> <tr> <th>Programming language</th> <th>Release year</th> </tr> <tr> <td>JavaScript</td> <td>1995</td> </tr> </table>

The <caption> element comes first now and that's a <table> virtue.

<caption> can contain other HTML elements

Second, the <caption> element isn't bound to hold just mere text; we can put any valid text-related HTML elements inside <caption>.

For example, in the following code, we use the <strong> element to mark up the keywords in our caption:

<table>
<caption>Some <strong>programming languages</strong>, with their <strong>release year</strong>.</caption> <tr> <th>Programming language</th> <th>Release year</th> </tr> <tr> <td>JavaScript</td> <td>1995</td> </tr> ... </table>
Some programming languages, with their release year.
Programming languageRelease year
JavaScript1995
Java1995
C++1985

As a matter of fact, <caption> can also contain <p>s and other flow content elements in HTML.

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage