Tables unlock a hidden door in displaying information on a web page. They are one of the hardest tags to master in HTML and also one of the most powerful. By using tables on your web page, you can greatly increase the range of what your website is able to do. In addition to displaying data, tables can also enhance, sort, filter, and modify existing information. With help from JavaScript, tables can go from static displays of information to becoming a window to how the world works. HTML makes this information easily sharable through websites and applications. Each table has quite a few sub-tags that can only be used inside it though. Below is an overview of some of them.

For a video overview of tables below, see:

Table <caption> and header content

As mentioned in the article on organizing your website with HTML, structuring your information is one of HTML’s primary objectives. With a complex element like a table, it’s often necessary to describe what the table is about. This is why it helps to include a <caption> tag inside the table. It’s often included at the top or at the bottom of the table. We will include it at the top, before the table heading tag, <thead>. Let’s start by creating a sudoku puzzle using an HTML table. Create an HTML file with the following content:

<!DOCTYPE html>
<html>
    <head>
        <title>Sudoku Puzzle in HTML</title>
    </head>
    <body>
        <main>
            <h1>Sudoku using the HTML table tag</h1>
            <br />
            <!-- Table tag with a border property representing 2 pixel borders -->
            <table border="2">
                <!-- Outermost caption tag for enclosing table information -->
                <caption>
                    <h4>Sudoku Puzzle</h4>
                    <p><em>Directions</em>: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.</p>
                </caption>
            </table>
        </main>
    </body>
</html>

By adding a caption above, web browsers and screen readers can more easily read web pages to disadvantaged or disabled users. Tables are especially difficult to read aloud and this makes the process just a bit easier. This also hints at one of the biggest challenges in Web Development: accessibility, which helps ensure that all users are able to access the content on your page, despite their potential disability. Let’s continue by finishing up our table’s header with a <thead> tag. This is a special type of header tag that is only used inside of tables. Its purpose is to enclose header information (sometimes including the caption) in the top of the table. We will add a difficulty of easy in a two-column format. Read the comments in the code to understand what each of these tags is doing.

<!DOCTYPE html>
<html>
    <head>
        <title>Sudoku Puzzle in HTML</title>
    </head>
    <body>
        <main>
            <h1>Sudoku using the HTML table tag</h1>
            <br />
            <!-- Table tag with a border property representing 2 pixel borders -->
            <table border="2">
                <!-- Outermost caption tag for enclosing table information -->
                <caption>
                    <h4>Sudoku Puzzle</h4>
                    <p><em>Directions</em>: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.</p>
                </caption>
                <!-- <thead> tag is commonly used to include informative description of table -->
                <thead>
                    <!-- The <tr> tag represents the first `row` of the table -->
                    <tr>
                        <!-- These <th> tags are header columns, one for difficulty, and one for the difficulty level (Easy) -->
                        <th colspan="5" style="border: none">Difficulty</th>
                        <th colspan="3" style="border: none">Easy</th>
                    </tr>
                </thead>
            </table>
        </main>
    </body>
</html>

There are three new tags introduced in the code block above: a table header (<thead>) tag, a row (<tr>) tag, and a header column (<th>) tag. By adding these tags, we have created a solid header element for the sudoku puzzle, informing our readers about directions to solve it and its difficulty. Remember that when creating a table, the row tags always have to enclose the column tags. First you create a row (<tr>) and then you can add the columns (<th> for header columns or <td> for regular columns). As long as you follow the rule, you are well on your way to publishing a sudoku game and selling it on the app stores! Let’s get to the fun part of adding the numbers in the puzzle.

Adding table rows to the sudoku puzzle

The first row will have a 3, 9, and 8 in the first three cells, and the rest of the cells (columns) will be empty. We create this row by adding a <tr> tag to enclose its contents. Then, start adding table cells (<td> tags) with either the number in the puzzle or a non-breaking space (&nbsp;) if there is no number. This is demonstrated in the table code below. Try opening an HTML file with the code below in your browser.

<!DOCTYPE html>
<html>
    <head>
        <title>Sudoku Puzzle in HTML</title>
    </head>
    <body>
        <main>
            <h1>Sudoku using the HTML table tag</h1>
            <br />
            <!-- Table tag with a border property representing 2 pixel borders -->
            <table border="2">
                <!-- Outermost caption tag for enclosing table information -->
                <caption>
                    <h4>Sudoku Puzzle</h4>
                    <p><em>Directions</em>: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.</p>
                </caption>
                <!-- <thead> tag is commonly used to include informative description of table -->
                <thead>
                    <!-- The <tr> tag represents the first `row` of the table -->
                    <tr>
                        <!-- These <th> tags are header columns, one for difficulty, and one for the difficulty level (Easy) -->
                        <th colspan="5" style="border: none">Difficulty</th>
                        <th colspan="3" style="border: none">Easy</th>
                    </tr>
                </thead>
                <tr>
                    <!-- First three cells have a 3, 9, and 8 -->
                    <td>3</td>
                    <td>9</td>
                    <td>8</td>
                    <!-- empty cells filled with non-breaking spaces to give more whitespace -->
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                </tr>
            </table>
        </main>
    </body>
</html>

Before moving further, let’s take a look at what the above code will create on your webpage:


Sudoku using the HTML table tag


Sudoku Puzzle

Directions: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.

DifficultyEasy
  3    9    8                                            

The style of the table may look significantly different for you depending on your browser. This blog also has several default CSS styles added to its HTML elements, and I also added extra spacing in the table columns to make them look square compared to the code sample above. Feel free to experiment with the number of spaces you add and other styling adjustments until you feel satisfied with the first row of this sudoku table because we will be using this same template for the rest of our rows. Note that copying the code directly will no longer help you with this table because you should try to use your own template that you believe looks good in your sudoku table. The code sample above is just an example of a table row you can start with.

Experimenting with other people’s code is openly encouraged in your web development journey. Often, instead of reinventing the wheel, it’s better to use other people’s openly available code, and then modify it for your own use case. Some developers forget about the modifying part or are too lazy to change something copied from the Internet because of course people are always right online, right? Anyway, let’s continue by adding two more rows to the puzzle. As mentioned earlier, your row template should be slightly different from the code sample above. Adjust the number of non-breaking spaces, add spaces before and after each number, add more spaces to each <td> tageach celldo what you must to make the row look better and create your own template for copy and pasting two more rows. The next two rows will look something like the following:

<!DOCTYPE html>
<html>
    <head>
        <title>Sudoku Puzzle in HTML</title>
    </head>
    <body>
        <main>
            <h1>Sudoku using the HTML table tag</h1>
            <br />
            <!-- Table tag with a border property representing 2 pixel borders -->
            <table border="2">
                <!-- Outermost caption tag for enclosing table information -->
                <caption>
                    <h4>Sudoku Puzzle</h4>
                    <p><em>Directions</em>: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.</p>
                </caption>
                <!-- <thead> tag is commonly used to include informative description of table -->
                <thead>
                    <!-- The <tr> tag represents the first `row` of the table -->
                    <tr>
                        <!-- These <th> tags are header columns, one for difficulty, and one for the difficulty level (Easy) -->
                        <th colspan="5" style="border: none">Difficulty</th>
                        <th colspan="3" style="border: none">Easy</th>
                    </tr>
                </thead>
                <tr>
                    <!-- First three cells have a 3, 9, and 8 -->
                    <td>3</td>
                    <td>9</td>
                    <td>8</td>
                    <!-- empty cells filled with non-breaking spaces to give more whitespace -->
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>2</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>8</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>3</td>
                    <td>5</td>
                    <td>9</td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>1</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>4</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                </tr>
            </table>
        </main>
    </body>
</html>

After adding the first three rows of the main puzzle, let’s add a couple of empty row tags (<tr>) to include whitespace before starting the rest of the sudoku puzzle. The effects of these extra row tags can’t be seen unless you add the next row, so we’ll go ahead and do that too.

<!DOCTYPE html>
<html>
    <head>
        <title>Sudoku Puzzle in HTML</title>
    </head>
    <body>
        <main>
            <h1>Sudoku using the HTML table tag</h1>
            <br />
            <!-- Table tag with a border property representing 2 pixel borders -->
            <table border="2">
                <!-- Outermost caption tag for enclosing table information -->
                <caption>
                    <h4>Sudoku Puzzle</h4>
                    <p><em>Directions</em>: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.</p>
                </caption>
                <!-- <thead> tag is commonly used to include informative description of table -->
                <thead>
                    <!-- The <tr> tag represents the first `row` of the table -->
                    <tr>
                        <!-- These <th> tags are header columns, one for difficulty, and one for the difficulty level (Easy) -->
                        <th colspan="5" style="border: none">Difficulty</th>
                        <th colspan="3" style="border: none">Easy</th>
                    </tr>
                </thead>
                <tr>
                    <!-- First three cells have a 3, 9, and 8 -->
                    <td>3</td>
                    <td>9</td>
                    <td>8</td>
                    <!-- empty cells filled with non-breaking spaces to give more whitespace -->
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>2</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>8</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>3</td>
                    <td>5</td>
                    <td>9</td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>1</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>4</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                </tr>
                <tr></tr>
                <tr></tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>4</td>
                    <td>9</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>1</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                </tr>
            </table>
        </main>
    </body>
</html>

This should create a table something along the lines of the one shown below. Again, it’s expected to look a little different depending on the row pattern you selected. However, the numbers and layout should be similar.


Sudoku using the HTML table tag


Sudoku Puzzle

Directions: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.

DifficultyEasy
  3    9    8                                            
                2           8           3    5    9  
                       1                  4                
         4    9           1                              

Just as you did with the empty column cells and padded number cells, feel free to modify the empty rows in a way that you see fit. To adjust the height of the whitespace after the first three rows, feel free to add more <tr> tags or adjust each row’s height by adding the following style attribute: style="height: 4px;". You can change the 4 to any number you like for the height of the <tr> tag. Once you’ve settled on template for adding empty row tags, go ahead and keep using that template to finish out the rest of the puzzle. Its HTML code is included below:

<!DOCTYPE html>
<html>
    <head>
        <title>Sudoku Puzzle in HTML</title>
    </head>
    <body>
        <main>
            <h1>Sudoku using the HTML table tag</h1>
            <br />
            <!-- Table tag with a border property representing 2 pixel borders -->
            <table border="2">
                <!-- Outermost caption tag for enclosing table information -->
                <caption>
                    <h4>Sudoku Puzzle</h4>
                    <p><em>Directions</em>: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.</p>
                </caption>
                <!-- <thead> tag is commonly used to include informative description of table -->
                <thead>
                    <!-- The <tr> tag represents the first `row` of the table -->
                    <tr>
                        <!-- These <th> tags are header columns, one for difficulty, and one for the difficulty level (Easy) -->
                        <th colspan="5" style="border: none">Difficulty</th>
                        <th colspan="3" style="border: none">Easy</th>
                    </tr>
                </thead>
                <tr>
                    <!-- First three cells have a 3, 9, and 8 -->
                    <td>3</td>
                    <td>9</td>
                    <td>8</td>
                    <!-- empty cells filled with non-breaking spaces to give more whitespace -->
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>2</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>8</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>3</td>
                    <td>5</td>
                    <td>9</td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>1</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>4</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                </tr>
                <tr></tr>
                <tr></tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>4</td>
                    <td>9</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>1</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                </tr>
                <tr>
                    <td>8</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>6</td>
                    <td>9</td>
                    <td>5</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>4</td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>4</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>5</td>
                    <td>9</td>
                    <td>&nbsp;&nbsp;</td>
                </tr>
                <tr></tr>
                <tr></tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>5</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>3</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                </tr>
                <tr>
                    <td>7</td>
                    <td>8</td>
                    <td>6</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>2</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>1</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                </tr>
                <tr>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td>&nbsp;&nbsp;</td>
                    <td style="border: none"></td>
                    <td>7</td>
                    <td>8</td>
                    <td>2</td>
                </tr>
            </table>
        </main>
    </body>
</html>

After converting it using your template, the puzzle should look something like this:


Sudoku using the HTML table tag


Sudoku Puzzle

Directions: Have each 3x3 square, each row, and each column have a number from 1 - 9. No repeat numbers allowed per row, column, or 3x3 square.

DifficultyEasy
  3    9    8                                            
                2           8           3    5    9  
                       1                  4                
         4    9           1                              
  8                  6    9    5                  4  
                              4           5    9         
                5                  3                       
  7    8    6           2           1                
                                            7    8    2  

For a video going over the code above, see:

Whew, that was a doozy! If you’ve stuck this far, congratulations! Mastering HTML tables is a very difficult thing to do, and a sudoku puzzle takes HTML tables to the edge of their complexity in terms of what vanilla HTML is capable of. Vanilla meaning HTML that gets very little or no help from the rest of the web ecosystem that includes CSS and JavaScript. Unsurprisingly, that is where most of the interesting things with website and web apps happen. This concludes the most complicated post on HTML. For further reading, continue by learning about CSS and JavaScript. With them, you can make your web pages more beautiful and add engaging interactions to them.

About the author

Nowispow Inc. is a socially driven company for democratizing professional education and reskilling for the modern workforce.