Ali Jafarian

Today we’re going to create some simple, yet effective, responsive HTML tables.

Over the last few years responsive design has become an industry standard. One of the trickier DOM elements to “responsify” is the <table> tag. Tables are set to behave differently than other block/inline elements, so we have to give them some special attention. The best approach [in most cases] is to stack table rows, especially for smaller screen sizes. So let’s dig in!

The HTML

Our HTML will be very standard – nothing out of the ordinary here:

<table class="responsive-stacked-table">
	<thead>
		<tr>
			<th>Product</th>
			<th>Price</th>
			<th>Availability</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>Macbook Air 11"</td>
			<td>$899</td>
			<td><i class="fa fa-check-circle"></i> in stock</td>
		</tr>
		<tr>
			<td>Macbook Air 13"</td>
			<td>$999</td>
			<td><i class="fa fa-times-circle"></i> out of stock</td>
		</tr>
		<tr>
			<td>Macbook Pro 13"</td>
			<td>$1,299</td>
			<td><i class="fa fa-check-circle"></i> in stock</td>
		</tr>
		<tr>
			<td>Macbook Pro 15"</td>
			<td>$1,999</td>
			<td><i class="fa fa-times-circle"></i> out of stock</td>
		</tr>
		<tr>
			<td>iMac 21.5"</td>
			<td>$1,099</td>
			<td><i class="fa fa-check-circle"></i> in stock</td>
		</tr>
		<tr>
			<td>iMac 27"</td>
			<td>$1,799</td>
			<td><i class="fa fa-check-circle"></i> in stock</td>
		</tr>
	</tbody>
</table>

The CSS

Our CSS is what does all the magic. The general idea is to set all table elements to display: block so that it over-rides the default table styling of display: table-cell when we hit our mobile breakpoint (in this case it’s 767px). We will also hide our thead headers because let’s face it, they’re not that important in this context (people can piece together that this is a table for apple products, price, and availability).

.responsive-stacked-table thead {
	display: none;
}
.responsive-stacked-table tr,
.responsive-stacked-table th,
.responsive-stacked-table td {
	display: block;
}
.responsive-stacked-table td {
	border-top: none;
}
.responsive-stacked-table tr td:first-child {
	border-top: 1px solid #ddd;
	font-weight: bold;
}

Some Extra Magic!

In the event that you have more detailed table info, and you wish to display your thead headers I’ve provided another option that utilizes the CSS3 content property.

The HTML

<table class="responsive-stacked-table with-mobile-labels">
	<thead>
		<tr>
			<th>Product</th>
			<th>Processor</th>
			<th>Memory</th>
			<th>Hard Drive</th>
			<th>Graphics Card</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>Macbook Air 11"</td>
			<td>1.4GHz dual-core Intel Core i5</td>
			<td>4GB</td>
			<td>128GB Flash storage</td>
			<td>Intel HD Graphics 5000</td>
		</tr>
		<tr>
			<td>Macbook Air 13"</td>
			<td>1.4GHz dual-core Intel Core i5</td>
			<td>4GB</td>
			<td>128GB Flash storage</td>
			<td>Intel HD Graphics 5000</td>
		</tr>
		<tr>
			<td>Macbook Pro 13"</td>
			<td>2.6GHz dual-core Intel Core i5</td>
			<td>8GB</td>
			<td>128GB Flash storage</td>
			<td>Intel Iris Graphics</td>
		</tr>
		<tr>
			<td>Macbook Pro 15"</td>
			<td>2.2GHz quad-core Intel Core i7</td>
			<td>16GB</td>
			<td>256GB Flash storage</td>
			<td>Intel Iris Pro Graphics</td>
		</tr>
		<tr>
			<td>iMac 21.5"</td>
			<td>1.4GHz dual-core Intel Core i5</td>
			<td>8GB</td>
			<td>500GB</td>
			<td>Intel HD Graphics 5000</td>
		</tr>
		<tr>
			<td>iMac 27"</td>
			<td>3.2GHz quad-core Intel Core i5</td>
			<td>8GB</td>
			<td>1TB</td>
			<td>NVIDIA GeForce GT 755M with 1GB video memory</td>
		</tr>
	</tbody>
</table>

The CSS

Using the content property and nth-of-type we can create labels using CSS3. We’ll hide these behind our mobile media query so they only show up when the table rows stack.

.responsive-stacked-table.with-mobile-labels tr td:first-child {
	font-weight: 300;
}
.responsive-stacked-table.with-mobile-labels td:before {
	display: block;
	font-weight: bold;
}
.responsive-stacked-table.with-mobile-labels td:nth-of-type(1):before {
	content: "Product:";
}
.responsive-stacked-table.with-mobile-labels td:nth-of-type(2):before {
	content: "Processor:";
}
.responsive-stacked-table.with-mobile-labels td:nth-of-type(3):before {
	content: "Memory:";
}
.responsive-stacked-table.with-mobile-labels td:nth-of-type(4):before {
	content: "Hard Drive:";
}
.responsive-stacked-table.with-mobile-labels td:nth-of-type(5):before {
	content: "Graphics Card:";
}

Conclusion

That’s all there is to it – simple stacking for responsive HTML tables. I hope these are useful in your projects!

Discussion

13 thoughts on “Responsive HTML Tables”
  1. Is there any way to use this method with a scrollable body? I like the fact that it uses standard html table code though, but I use a lot of scrolling tables on my sites. Also I downloaded the source code. When I run the code locally the headings are out of alignment, but when I run the demo on this page the headings align. Have you got some sneaky jQuery aligning the headings on the page LOL.

  2. You said nothing here regarding @media rule u use

    @media (max-width: 767px)
    .responsive-stacked-table tr, .responsive-stacked-table th, .responsive-stacked-table td

    1. Pavel – if you read the tutorial you would see that I commented on that in “The CSS” section. It’s up to you where you put this CSS, as your media queries and breakpoints may be different.

  3. Useful comments . For my two cents , if anyone has been searching for a USPS Combined NCOALink Processing Acknowledgement Form , my business edited a sample version here https://goo.gl/il2o8f

  4. Wonderful thank you.
    I did not arrive with explanations but with the code in the demo it is perfect.
    I do not find how change with of column for md or lg.
    with=”50%”, with=500px, by style, by css, anything ok.
    I tried also
    .responsive-stacked-table td:nth-of-type(1):before {
    width: 50%;
    }
    But no effect.
    Can you help me

  5. Hi Ali, very helpful! I looked at about 15 references online before finding this, which worked for me. Very clear wording and layout. Much appreciated.

Leave a Comment

Your email address will not be published. Required fields are marked *