Irishstu.com stublog

Found and shared

Tables and Responsive Design

1 comment

Update: A simpler solution using nth-child instead of classes

Inspired by a post by Mark Boulton on Google+ I thought I’d have a look at responsive design for tables.

Here’s the HTML file to play with.

The problem: Smaller screens can’t display over a certain number of columns. So you either get long, squashed tables with epic scrolling on narrow screens (if you have lots of columns), or super-wide tables with little data on large screens (if you have only 2 or 3 columns).

The solution: Add more columns as the screen size expands, showing only the most important data first.

(Note: using images for tables to best illustrate resizing etc.)

Here’s a basic table, with styling:

<table id="iseqchart">

<tr>
	<th>Index</th>
	<th>Value</th>
	<th>Change</th>
	<th>Change %</th>
	<th>Year High</th>
	<th>Year Low</th>
	<th>Daily Low</th>
	<th>Daily High</th>
	<th>Turnover €(Mil.)</th>
</tr>
<tr>
	<td>ISEQ® Overall</td>
	<td>2,725.99</td>
	<td class="neg">-15.30</td>
	<td class="neg">-0.56%</td>
	<td>3,037.89</td>
	<td>2,333.35</td>
	<td>2,712.84</td>
	<td>2,743.31</td>
	<td>24.00</td>
</tr>
<tr>
	<td>ISEQ® Financial</td>
	<td>130.77</td>
	<td class="neg">-3.24</td>
	<td class="neg">-2.42%</td>
	<td>493.83</td>
	<td>101.54</td>
	<td>130.43</td>
	<td>136.14</td>
	<td>2.76</td>
</tr>
<tr>
	<td>ISEQ® General</td>
	<td>3,751.79</td>
	<td class="neg">-17.49</td>
	<td class="neg">-0.46%</td>
	<td>4,146.84</td>
	<td >3,188.68</td>
	<td>3,731.15</td>
	<td>3,770.88</td>
	<td>21.24</td>
</tr>
<tr>
	<td>ISEQ® Small Cap.</td>
	<td>1,661.94</td>
	<td class="pos">3.76</td>
	<td class="pos">0.23%</td>
	<td>2,175.60</td>
	<td>1,633.21</td>
	<td>1,643.92</td>
	<td>1,661.94</td>
	<td>0.20</td>
</tr>
</table>

Full width:

Small screen – text is squashed, lots of scrolling:

Next step: Use colgroup to identify columns, and hide them using media queries (I’m adding colours so you can see what goes wrong…):

The HTML:

<table id="iseqchart">

<colgroup id="name">
    <col/>
  </colgroup>
<colgroup id="delta">
    <col/>
	<col/>
</colgroup>
<colgroup id="deltapercent">
    <col/>
</colgroup>
<colgroup id="yearhigh">
    <col/>
	<col/>
</colgroup>
<colgroup id="dailyhigh">
    <col/>
	<col/>
</colgroup>
<colgroup id="turnover">
    <col/>
</colgroup>

<tr>
	<th>Index</th>
	<th>Value</th>
	<th>Change</th>
	<th>Change %</th>
	<th>Year High</th>
	<th>Year Low</th>
	<th>Daily Low</th>
	<th>Daily High</th>
	<th>Turnover €(Mil.)</th>
</tr>
<tr>
	<td>ISEQ® Overall</td>
	<td>2,725.99</td>
	<td class="neg">-15.30</td>
	<td class="neg">-0.56%</td>
	<td>3,037.89</td>
	<td>2,333.35</td>
	<td>2,712.84</td>
	<td>2,743.31</td>
	<td>24.00</td>
</tr>
<tr>
	<td>ISEQ® Financial</td>
	<td>130.77</td>
	<td class="neg">-3.24</td>
	<td class="neg">-2.42%</td>
	<td>493.83</td>
	<td>101.54</td>
	<td>130.43</td>
	<td>136.14</td>
	<td>2.76</td>
</tr>
<tr>
	<td>ISEQ® General</td>
	<td>3,751.79</td>
	<td class="neg">-17.49</td>
	<td class="neg">-0.46%</td>
	<td>4,146.84</td>
	<td >3,188.68</td>
	<td>3,731.15</td>
	<td>3,770.88</td>
	<td>21.24</td>
</tr>
<tr>
	<td>ISEQ® Small Cap.</td>
	<td>1,661.94</td>
	<td class="pos">3.76</td>
	<td class="pos">0.23%</td>
	<td>2,175.60</td>
	<td>1,633.21</td>
	<td>1,643.92</td>
	<td>1,661.94</td>
	<td>0.20</td>
</tr>
</table>

 

The CSS:

<style>
#iseqchart	{
	border:1px solid #000;
	border-collapse:collapse;
	font-family:Arial, Sans-Serif;
	font-size:12px;
	text-align:right;
	}

#iseqchart th	{
	border:1px solid #333;
	padding:3px 6px;
	}

#iseqchart td	{
	border:1px solid #999;
	padding:3px 6px;
	}

.neg	{
	color:red;
}

.pos	{
	color:green;
}

#name			{ background:#eff3f7; }
#delta			{ background:#ffffff; }
#deltapercent	{ background:#fafbdb; }
#yearhigh		{ background:#dbf8fb; }
#dailyhigh		{ background:#dbfbe5; }
#turnover		{ background:#e4dbfb; }

@media only screen and (max-width: 768px) {
	#yearhigh		{ display:none; visibility:hidden; }
	#dailyhigh		{ display:none; visibility:hidden; }
	#turnover		{ display:none; visibility:hidden; }
}

</style>

 

This creates 6 groups of columns – the name of the index, the value and change, the percentage change, the year’s high and low, the daily high and low, and turnover. All this information is useful, but at a bare minimum you’d need to know the name, value and change. So we try and hide the extra stuff with media queries – if you go smaller than 768px the high/low columns and turnover columns should be switched off.

Full width:

Less than 768px width:

 

The bad news: Only the styling from the table columns gets hidden, not the headings and rows that should be associated with that column through <colgroup>

The hacky icky way – style ALL THE THINGS!

The HTML – add a class to each cell

<table id="iseqchart">

<colgroup id="name">
    <col/>
  </colgroup>
<colgroup id="delta">
    <col/>
	<col/>
</colgroup>
<colgroup id="deltapercent">
    <col/>
</colgroup>
<colgroup id="yearhigh">
    <col/>
	<col/>
</colgroup>
<colgroup id="dailyhigh">
    <col/>
	<col/>
</colgroup>
<colgroup id="turnover">
    <col/>
</colgroup>

<tr>
	<th>Index</th>
	<th>Value</th>
	<th>Change</th>
	<th>Change %</th>
	<th class="yearhigh" scope="colgroup">Year High</th>
	<th class="yearhigh" scope="colgroup">Year Low</th>
	<th class="dailyhigh" scope="colgroup">Daily Low</th>
	<th class="dailyhigh" scope="colgroup">Daily High</th>
	<th class="turnover" scope="colgroup">Turnover €(Mil.)</th>
</tr>
<tr>
	<td>ISEQ® Overall</td>
	<td>2,725.99</td>
	<td class="neg">-15.30</td>
	<td class="neg">-0.56%</td>
	<td class="yearhigh">3,037.89</td>
	<td class="yearhigh">2,333.35</td>
	<td class="dailyhigh">2,712.84</td>
	<td class="dailyhigh">2,743.31</td>
	<td class="turnover">24.00</td>
</tr>
<tr>
	<td>ISEQ® Financial</td>
	<td>130.77</td>
	<td class="neg">-3.24</td>
	<td class="neg">-2.42%</td>
	<td class="yearhigh">493.83</td>
	<td class="yearhigh">101.54</td>
	<td class="dailyhigh">130.43</td>
	<td class="dailyhigh">136.14</td>
	<td class="turnover">2.76</td>
</tr>
<tr>
	<td>ISEQ® General</td>
	<td>3,751.79</td>
	<td class="neg">-17.49</td>
	<td class="neg">-0.46%</td>
	<td class="yearhigh">4,146.84</td>
	<td class="yearhigh">3,188.68</td>
	<td class="dailyhigh">3,731.15</td>
	<td class="dailyhigh">3,770.88</td>
	<td class="turnover">21.24</td>
</tr>
<tr>
	<td>ISEQ® Small Cap.</td>
	<td>1,661.94</td>
	<td class="pos">3.76</td>
	<td class="pos">0.23%</td>
	<td class="yearhigh">2,175.60</td>
	<td class="yearhigh">1,633.21</td>
	<td class="dailyhigh">1,643.92</td>
	<td class="dailyhigh">1,661.94</td>
	<td class="turnover">0.20</td>
</tr>
</table>

The CSS

<style>
#iseqchart	{
	border:1px solid #000;
	border-collapse:collapse;
	font-family:Arial, Sans-Serif;
	font-size:12px;
	text-align:right;
	}

#iseqchart th	{
	border:1px solid #333;
	padding:3px 6px;
	}

#iseqchart td	{
	border:1px solid #999;
	padding:3px 6px;
	}

.neg	{
	color:red;
}

.pos	{
	color:green;
}

#name			{ background:#eff3f7; }
#delta			{ background:#ffffff; }
#deltapercent	{ background:#fafbdb; }
#yearhigh		{ background:#dbf8fb; }
#dailyhigh		{ background:#dbfbe5; }
#turnover		{ background:#e4dbfb; }

@media only screen and (max-width: 768px) {
	#turnover, .turnover		{ display:none; visibility:hidden; }
}

@media only screen and (max-width: 420px) {
	#yearhigh, .yearhigh		{ display:none; visibility:hidden; }
	#turnover, .turnover		{ display:none; visibility:hidden; }
}

@media only screen and (max-width: 320px) {
	#yearhigh, .yearhigh		{ display:none; visibility:hidden; }
	#dailyhigh, .dailyhigh		{ display:none; visibility:hidden; }
	#turnover, .turnover		{ display:none; visibility:hidden; }
}

</style>

 

Small

Smaller

Smallest

This progressively hides columns that aren’t vital as the screen sizes decreases. It’s also pretty brutal in terms of styling overload.

Better Solutions:

It would be nice if <colgroup> passed through CSS display stylings to the cells it’s supposed to be containing and identifying - I’m testing in Chrome so if it’s different in other browsers let me know. Also, if I’ve missed something obvious do tell.

The elephant in the room is downloading extra data only to hide it, which is only a few KB in this case so not the end of the world. There’s also the question of what to show or hide, which is really a content issue and not one for the designer to decide.

What would be nice is a way to ‘weight’ visibility based on availabily width or height – an x-index or y-index if you will. In that case I could go:

#name		{ x-index:10; }
#delta		{ x-index:10; }
#deltapercent	{ x-index:4; }
#yearhigh	{ x-index:6; }
#dailyhigh	{ x-index:8; }
#turnover	{ x-index:1; }

and let the browser gradually show new columns IF there’s enough room to do it nicely – by calculating the width of each column versus screen width.