Skip to main content

Responsive Tables Exploring a Solution
25 November 2012

Tables have a habit of creeping into every other web development project. Finding a way to make them responsive has been a big issue and a hot topic this year. In this article a new way to make tables responsive has been explored and quite possibly a good solution has been found.

Let's Rule Out JavaScript in Making a Table Responsive

Why rule out JavaScript? JavaScript is a great wagon when it comes to progressive enhancements. The problem with JavaScript is it is not always available. If a table has been used in a project there is a good reason behind why it has been used. This is normally because the data is well suited to a table layout - or in other words it is tabular data.

You can choose to try and fix it with JavaScript, however, in this case you have to accept that some visitors will see a broken looking layout. As a Client-side Web Developer you are not doing your job properly if you accept this. Also, when you least expect it, someone will send your client a screen shot, and your client - quite rightly - will demand you fix it.

But First Let's Explore What a Table is

In order to begin to find a candidate solution, we need to understand the problem. We need to start by exploring briefly what the notion of a table is and what a table is used for. The simple answer, of course, is a table is a structure that semantically holds collections of comparable data; and we use tables to present data in such a way that information can be drawn.

This means that for a structure to act as a table it needs to support the concept of columns and of rows. Or otherwise no information can be reliably drawn from the data it holds. A HTML table fits this description perfectly after all it is what it was designed to do - its very name gives that away. The problem is HTML tables do not slim down on small screens. A row remains a row - full stop.

Now we have a good understanding of what the problem is, and while HTML tables fit the description, they do not fit the needs of a responsive layout. This is especially noticeable on mobile phone layouts as I am sure you are aware. This means if we can find an alternative HTML structure that can also fit the description of a table - to semantically holds collections of comparable data and present data in such a way that information can be drawn from it reliably, and fit the needs of a responsive layout then it is definitely worth looking for.

A Responsive Table from a Semantic Combination of HTML Elements

In any document headings (i.e. 'h*' elements) semantically indicate a section of a document. Therefore, an 'h*' element also makes a great contender as a row heading.

<h3>Row 1</h3>

By wrapping each row into an unordered list, we can begin to make a relationship between rows. You may ask what about the table's columns, and the column's headings? Definition lists, if structured well, make this possible - as shown below:

<ul class="responsive-table">
	<li class="first-row">
    	<h3>Row 1</h3>
        <dl>
            <dt>Heading 1</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 2</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 3</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 4</dt>
            <dd>data</dd>
        </dl>
	</li>
	<li>
    	<h3>Row 2</h3>
        <dl>
            <dt>Heading 1</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 2</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 3</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 4</dt>
            <dd>data</dd>
        </dl>
	</li>
	<li>
    	<h3>Row 3</h3>
        <dl>
            <dt>Heading 1</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 2</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 3</dt>
            <dd>data</dd>
        </dl>
        <dl>
            <dt>Heading 4</dt>
            <dd>data</dd>
        </dl>
	</li>
</ul>

As you can see, column headings are made constant for each item of each row. This thus creating continuity between each row and therefore, information can reliably be drawn from the data held in the semantic structure - fitting the description of a table. I believe that screen readers would also read this out in a way that makes the table's information attainable.

With a preconception of what a table looks like in a browser you may think that example 1 does not look very table like yet. However, I am sure you will agree information can be drawn from it in the same way that fits the discretion of a table.

At this point you can also see how it can easily take up less width to display - even without any styling.

Let's Style Our Responsive Table to Look Like a Table

Before we move on into the table, we need to fix up the containing unordered list and reset the margin, padding, line height and font-size of the 'ul', 'h*', 'dl', and the 'dd' elements. Once done, we need to make every definition list and h* elements sit next to each other both on the x-axes and on the y-axes. We can do this using the CSS's 'float: left' in combination with percentage widths. You can target each column width with classes if you like, as a proof of concept, I will keep this simple with a 20% width for row headings and 20% width for each column.

The trick to making it look like a normal table on a screen that is large enough to display a normal table is to use the first row's column headings. The conflict is, we do not wish to show any of the other row's headings in this layout. We will do this by making all 'dt' elements invisible except for the first row's 'dt' elements. Finally, the first row of the table needs the 'h*' element's padding at the top to be equivalent line height of the column headings: this gives the correct vertical alignment to the row's heading.

.responsive-table {
	width:100%;
}
.responsive-table ,
.responsive-table h3,
.responsive-table dl,
.responsive-table dd{
	margin:0;
	padding:0;
	font-size: 1em;
	line-height:1em;
}
.responsive-table li{
	list-style:none;
	display:block;
	clear:both;
}
.responsive-table h3,
.responsive-table dl{
	float:left;
	display:inline;
	width:20%;
}
.responsive-table .first-row h3{
	padding-top:1em;
}
.responsive-table dt{
	display:none;
	font-weight:bold;
}
.responsive-table .first-row dt{
	display:inline;
}

You will now see a table that also fits our preconception of what a table should look like in example 2.

Let's Style Our Responsive Table to Fit on Small Screens

For a small screen set the break point of your media query to the place that makes the most sense to the data inside of your table. For this demo I have chosen 600 pixels. For this layout all you need to do is set the 'td' and 'dl' elements to float.

Here is all of the CSS for each layout of the responsive table:

.responsive-table {
	width:100%;
}
.responsive-table ,
.responsive-table h3,
.responsive-table dl,
.responsive-table dd{
	margin:0;
	padding:0;
	font-size: 1em;
	line-height:1em;
}
.responsive-table li{
	list-style:none;
	display:block;
	clear:both;
	padding:5px 0 0; 
}
.responsive-table dt{
	font-weight:bold;
}
@media all and (max-width:600px){
	.responsive-table dt,
	.responsive-table dd{
		float:left;
		display:inline;
		padding-left:10px;
	}
}
@media all and (min-width:600px){
	.responsive-table h3,
	.responsive-table dl{
		float:left;
		display:inline;
		width:20%;
	}
	.responsive-table .first-row h3{
		padding-top:1em;
	}
	.responsive-table dt{
		display:none;
	}
	.responsive-table .first-row dt{
		display:inline;
	}
}

Please see example 3. To get the best idea of how this looks and works, resize IE9 and up or any other browser on a large screen.

A Tip Worth Noting

If you need to give the table heading a background colour, apply the colour to the unordered list and set the list items back to their intended colour.

Conclusion

With an open way of thinking about what a table is and how else we can construct a table with HTML this approach to a responsive table works. The CSS to present it is very light-weight and much more agile than its HTML table counterpart. What do you think?

Acknowledgements

This solution was co-developed by Neal Stammers and myself.

Mailing List


Responsive Media

With the ResponsiveMedia plugin for Joomla it is easy to add 3rd party content from YouTube, Vimeo, and Instagram right in to any Joomla! article.

ResponsiveMedia