All you need to know about HTML tables
Tags: webdev, beginners, html, codenewbie
Published: 2021-01-24 17:33:49

This week's subject is HTML tables, this post is a part of my HTML beginner series. If you haven't checked the previous ones I highly recommend you to read them! If you already know the basics and just one to know about HTML tables you can skip them and read this one directly instead. This course is structured in a way that will make you grasp the information more clearly. You will learn how to create basic HTML tables, their components, how to have those tables that have cells expanding on more than one cell, when to use tables, and more! Let's get started!

#Why Tables?
One of the most efficient ways to present a large amount of information to a reader is to collect them in a table, tables can supplement the text and also make it easier for you to explain something hard to explain with plain text. Tables are also the best when you want to have spreadsheet-like content. In HTML, you can create tables easily.

#Create your first table
Let's go back to the basics, a table should have rows, columns, and the intersection between them create cells, and sometimes, you may find a caption attached to a table (like in Microsoft word). We'll first try to create our table using this definition:
* In HTML, a table is defined using the `<table>` element, it has an opening tag and a closing tag, and you put the content in between.
* Rows are defined using the `<tr></tr>` element (table row), so if you want a table with three rows it would look like something like this:

```HTML
<table>
<tr></tr> 
<tr></tr> 
<tr></tr> 
</table>
```

* For columns, there is no such thing as <tc> if you tried to guess the next element, instead, you have full control over the number of columns you want to have in each row (but I advise you to have the same number otherwise it would look weird and has no sense). The columns are indirectly defined using the table data element `<td></td>` , it has also an opening tag and a closing tag, and your actual data is in between, simple as that.
So let's see how our table is structured so far:

```HTML
<table>
  <tr>
    <td>Saturday</td>
    <td>Sunday</td>
    <td>Monday</td>
  </tr> 
  <tr>
    <td>Vegetables Soup</td>
    <td>Jardiniere</td>
    <td>Fish & Potato</td>
  </tr> 
 <tr>
    <td>$10</td>
    <td>$12</td>
    <td>$16</td>
  </tr> 
</table>
```
You can check here the result, I styled it a bit so that you can see clearly the elements:

{% codepen https://codepen.io/Hildweig/pen/eYdwmeK %}

Now that I'm looking at it, I kinda want to make a distinction between the days of the week and my meals. And I also want at the end to have a row where there is the average cost of my meals, and there is a way to do that! In fact, what we've done earlier wasn't a "well created" table. HTML let us define three components in our table:
* __A header__ : you want to use it to contain the name of your columns in the header. Having a header inside your table makes it easier to find the data you're looking for if the header elements stand out from the other ones. Of course, there are other ways you might say (using CSS) but if you appreciate content that is highly semantically and you like doing things how they should be, I really recommend you to include it. So there, we will contain the days of the week in the header. The HTML element for the table header is `<thead></thead>`, and the content of your header is wrapper inside a header cell `<th></th>`, the text looks bold and is centered by default. You can check here the code and how it looks:

{% codepen https://codepen.io/Hildweig/pen/JjRQoeQ %}

And notice that we still have a row, we just added the thead element and replaced the tr with th!
* Now for the __data__ : you should wrap your table rows inside a `<tbody></tbody>` element (table body). The header element should always come before this element. Okay, so let's apply this to our table:

{% codepen https://codepen.io/Hildweig/pen/jOMjPpJ %}

* Our third step is to add a __footer__ : you don't always need to have a footer in your table, but if you need one then you can use the `<tfoot></tfoot>` element (table footer). Both the thead and tfoot elements contain ancillary information to support the main information of the tbody. Plus, even if it seems logical to have it at the end, it's not a general rule, sometimes you may find a header then footer then the body, and sometimes the header then body then the footer. I will show you soon an example with a footer.

## Add a little touch to your table
Now that we know how to create a basic table I want to show you some more of what you can do on tables.
### 1. Captions
Suppose I'm one of your users and I'm reading a content in your page, and then there is a table. Having a caption in your table will help me to understand what that table represents, and it will make things easier for me to decide if I want to read it or skip it. Captions also help people who use screen readers since most screen readers announce the content of captions. It should always come first (even before the thead element). 

```HTML
<table>
  <caption>
    My holidays meal plan and cost.
  </caption>
  <thead>
    <tr>
      <th>Saturday</th>
      <th>Sunday</th>
      <th>Monday</th>
    </tr> 
  </thead>
  <tbody>
    <tr>
      <td>Vegetables Soup</td>
      <td>Jardiniere</td>
      <td>Fish & Potato</td>
    </tr> 
    <tr>
      <td>$10</td>
      <td>$12</td>
      <td>$16</td>
    </tr>
  </tbody>
</table>
```

If you try this snippet, you'll see that the caption is centered by default. You can also add more details to the caption and nest elements inside if you want to style them differently later on. (It's okay if you don't know styling yet, just know that you can have a sort of title followed by a text if you want in your caption, and even more but it would be weird if you had something else I think).

{% codepen https://codepen.io/Hildweig/pen/QWKXjBj %}

### 2. Cells? Fuuuusion!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dthpn21cg6qa228lfiat.jpg)

Did you know that your cells can become super saiyan? By merging two or more cells your cell can take vertically or horizantally the space of the number of cells you want. To understand how this work we need to understand two attributes that can go on any cell element.
* 1. rowspan: by default, your cell has indirectly a rowspan= "1", if you want it to span more vertically, then you can add it to the cell you want, say 2 for example : rowspan= "2" will have the space of 2 rows.
* 2. colspan: here too, by default your cell has indirectly a colspan= "1", if you want to have more than that, add the attribute with the number you want. Of course, you can have rowspan and colspan included in the same cell.

Now, I want my table to have a footer for the sum of all meals, and since it's a sum, I will span the cell horizontally for the three meals.

{% codepen https://codepen.io/Hildweig/pen/zYKVrGW %}

## 3.Create groups for columns
We said earlier that the columns are implicitly represented with the `<td>` elements. This is true, but imagine later on if you want to apply different styles for each group of columns, let's say we have a table for a student semester grades, the first column is for subjects names, the following columns for the grades, and the last one for teachers remarks. The first and last columns I want them with a style, and the ones in between with a different style. (this is just an example) HTML lets us group our columns using the `<colgroup>` and `<col>` elements.
* 1. __colgroup__: The `<colgroup>` element should be child of the <table> element, you have to put it after the `<caption>` element if there is one, and before any `<thead>`, `<tbody>`, or `<tfoot>` elements.
* 2. __col__: Now to define your columns groups, use the `<col>` element within the `<colgroup>` element. You also need to add an attribute in this element which specifies how many columns your group __spans__, for example, if my group has three columns I would write `<col span="3">` (this element comes with just one tag)
<br>
```HTML
<table>
  <colgroup>
    <col span="3">
  </colgroup>
  <caption>
    My holidays meal plan and cost <br>
    <span>The first row represents the days, the second one the meals, and the third one the cost of each meal</span>
  </caption>
  <thead>
    <tr>
      <th>Saturday</th>
      <th>Sunday</th>
      <th>Monday</th>
    </tr> 
  </thead>
  <tbody>
    <tr>
      <td>Vegetables Soup</td>
      <td>Jardiniere</td>
      <td>Fish & Potato</td>
    </tr> 
    <tr>
      <td>$10</td>
      <td>$12</td>
      <td>$16</td>
    </tr>
  </tbody>
</table>

```
<br>
You will find them more useful once you learn CSS don't worry.

## Some advices
### 1- Do not use HTML tables for layouts
HTML tables should be only used for their real purpose which is to organise your data in a table form. Some people use it for layouts too (a row for header, one for the content, etc), and you really __should not__ use it this way, here are some reasons:
* 1. Screen readers used by blind people are tools that interpret the tags that exist in HTML and read the content to users. Because tables are not appropriate for layouts usage the screen readers won't read it in un "understandable" way. Imagine if someone would read to you a text backwards, or a word each line then go back to the first line, weird right? Well, you can imagine how confusing screen readers would read the content if you layout your page using tables.
* 2. Difficult to maintain: making modifications on such a page with all the rows and cells would bring you more pain than you could imagine.
* 3. Tables aren't responsive by default. They are sized according to what they contain, while the normal layout containers (header, section, article, div) have their width set to 100% of their parent element. Using tables would make you do extra work to make it responsive.

### 2- Can you have nested tables?
The answer is yes, it is doable. However you should avoid that practice as much as possible. You will have the same issue with screen readers (weird reading), so you can add extra columns and cells instead.

# Conclusion
That's it for today! If you read up to this point I'm so proud of you and you should be proud of yourself as well. No one can take away the hardwork you're putting and the results you'll get if you persevere. Don't forget to enjoy your journey and share your progress with the community to keep yourself motivated and motivate others with you!
If you liked this post, please share it and feel free to share your thoughts in the comments. If you have any suggestions about what you want to learn you can tell me in the comments as well.
Here is a summary of what you learned today:

<br>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/es5pk5mhlkxr4t66f0sd.png)

<br>
Thank you for reading and see you soon!