Tables enable us to prepare knowledge into grid-like format of rows and columns. Scanning the desk in a single course permits customers to go looking and evaluate the information whereas scanning within the different course lets customers get all particulars for a single merchandise by matching the information to their respective desk header parts.

Tables typically depend on having sufficient display screen area to speak these knowledge relations successfully. This makes designing and creating extra complicated responsive tables considerably of a problem. There may be no common, silver-bullet resolution for making the tables responsive as we regularly see with different parts like accordions, dropdowns, modals, and so forth. All of it is dependent upon the primary function of the desk and the way it’s getting used.
If we fail to think about these components and use the unsuitable method, we are able to probably make usability worse for some customers.

On this article, we’re going to be strictly targeted on numerous methods we are able to make tables on the internet responsive, relying on the information kind and desk use-case, so we’re not going to cowl desk search, filtering, and different related functionalities.
In case you are excited about enhancing consumer expertise (UX) for tables and different UI parts past simply responsiveness, be sure to take a look at Smashing Journal’s extremely helpful Sensible Interface Design Patterns workshop, which covers greatest practices and pointers for numerous UI parts, tables included.
Quick Primer On Accessible Tables
Earlier than diving into particular responsive desk patterns, let’s rapidly go over some greatest practices concerning design and accessibility. We’ll cowl some basic factors on this part and different, extra particular ones in later examples.
Design And Visible Options
First, we have to be sure that customers can simply scan the desk and intuitively match the information to their respective desk header parts. From the design perspective, we are able to guarantee the next:
- Use correct vertical and horizontal alignment (“A Record Aside” covers this of their article).
- Design a desk with clear divisions and optimum spacing between rows and cells.
- Desk header parts ought to stand out and be styled otherwise from knowledge cells.
- Think about using alternate background colour for rows or columns (“zebra stripes”) for simpler scanning.
ARIA Roles
We need to embrace correct ARIA attributes to our desk aspect and its descendants. Making use of some CSS kinds like show: block
or show: flex
(to create responsive stacked columns) could trigger points in some browsers. In these circumstances, display screen readers interpret the desk
aspect otherwise, and we lose the helpful desk semantics. By including ARIA labels, we are able to repair the problem and retain the desk semantics.
Together with these roles in HTML manually might turn out to be tedious and liable to error. In case you are snug about utilizing JavaScript for including further markup, and also you aren’t utilizing a framework that generates static HTML information, you should utilize this useful little JavaScript operate made by Adrian Roselli to mechanically add ARIA roles to desk parts:
operate AddTableARIA() {
strive {
var allTables = doc.querySelectorAll("desk");
for (var i = 0; i < allTables.size; i++) {
allTables[i].setAttribute("position", "desk");
}
var allRowGroups = doc.querySelectorAll("thead, tbody, tfoot");
for (var i = 0; i < allRowGroups.size; i++) {
allRowGroups[i].setAttribute("position", "rowgroup");
}
var allRows = doc.querySelectorAll("tr");
for (var i = 0; i < allRows.size; i++) {
allRows[i].setAttribute("position", "row");
}
var allCells = doc.querySelectorAll("td");
for (var i = 0; i < allCells.size; i++) {
allCells[i].setAttribute("position", "cell");
}
var allHeaders = doc.querySelectorAll("th");
for (var i = 0; i < allHeaders.size; i++) {
allHeaders[i].setAttribute("position", "columnheader");
}
// This accounts for scoped row headers
var allRowHeaders = doc.querySelectorAll("th[scope=row]");
for (var i = 0; i < allRowHeaders.size; i++) {
allRowHeaders[i].setAttribute("position", "rowheader");
}
// Caption position not wanted as it's not an actual position, and
// browsers don't dump their very own position with the show block.
} catch (e) {
console.log("AddTableARIA(): " + e);
}
}
Nevertheless, take into account the next potential drawbacks of utilizing JavaScript right here:
- Customers may select to browse the web site with JavaScript turned off.
- The JavaScript file is probably not downloaded or could also be downloaded a lot later if the consumer is looking the web site on an unreliable or gradual community.
- If that is bundled alongside different JavaScript code in the identical file, an error in different components of the file may stop this operate from working in some circumstances.
Including An a11y-Friendy Title
Including a title subsequent to the desk helps each sighted customers and customers with assistive units get a whole understanding of the content material.
Ideally, we would come with a caption
aspect contained in the desk
aspect as a primary baby. Discover how we are able to nest any HTML heading aspect as a toddler to keep up the title hierarchy.
<desk>
<caption>
<h2>High 10 best-selling albums of all time</h2>
</caption>
<!-- Desk markup -->
</desk>
If we’re utilizing a wrapper aspect to make the desk scrollable or including another performance that makes the caption
aspect not excellent, we are able to embrace the desk
inside a determine
aspect and use a figcaption
so as to add a title. Ensure that to incorporate a correct ARIA label on both the desk aspect or a wrapper aspect and hyperlink it to a figcaption
aspect:
<determine>
<figcaption id="caption">High 10 best-selling albums of all time</figcaption>
<desk aria-labelledby="caption"><!-- Desk markup --></desk>
</determine>
<determine>
<figcaption id="caption">
<h2>High 10 best-selling albums of all time</h2>
</figcaption>
<div class="table-wrapper" position="group" aria-labelledby="caption" tabindex="0">
<desk><!-- Desk markup --></desk>
</div>
</determine>
There are different accessibility facets to think about when designing and creating tables, like keyboard navigation, print kinds, excessive distinction mode, and others. We’ll cowl a few of these within the following sections. For a extra complete information on creating accessible desk parts, be sure to take a look at Heydon Pickering’s information and Adrian Roselli’s article which is being saved updated with the most recent options and greatest practices.
Naked-bones Responsive Method
Typically we don’t should make any main adjustments to our desk to make it responsive. We simply want to make sure the desk width responds to the viewport width. That may be simply achieved with width: 100%
, however we also needs to take into account setting a dynamic max-width
worth, so our desk doesn’t develop too broad on bigger containers and turns into troublesome to scan, like within the following instance:

desk {
width: fit-content;
}
With the fit-content
worth, we be sure that the desk doesn’t develop past the minimal width required to optimally show the desk contents and that it stays responsive.
The desk responds to viewport measurement, and it appears good on small screens, however on wider screens, it turns into troublesome to scan because of the pointless area between the columns.

fit-content
worth, we’ve fastened the above-mentioned difficulty. (Giant preview)We are able to additionally be sure that the desk max-width
worth all the time adapts to its content material. We don’t should depend on assigning a magic quantity for every desk or wrap the desk in a container that constrains the width to a set worth.

auto
or max-content
, we get a most width worth that adapts to desk contents. (Giant preview)This works effectively for easy tables that don’t require an excessive amount of display screen area to be successfully parsed and aren’t affected by word-break
. We are able to even use fluid typography and fluid spacing to ensure these easy tables stay readable on smaller screens.
/* Values generated with Utopia https://utopia.fyi/kind/calculator/ */
tbody {
font-size: clamp(1.13rem, calc(0.35rem + 2.19vw), 1.75rem);
}
tbody td {
padding-top: clamp(1.13rem, calc(0.35rem + 2.19vw), 1.75rem);
padding-bottom: clamp(2rem, calc(0.62rem + 3.9vw), 3.11rem);
}
See the Pen [Responsive table – as is [forked]](https://codepen.io/smashingmag/pen/yLEVLbX) by Adrian Bece.
On complicated tables with a number of columns the place we can’t depend on fluid sizing and word-break
to maintain the desk readable, we wish the desk to stretch so far as it must show the content material optimally and permit customers to scroll the desk horizontally, so the desk stays usable.
See the Pen [Table – scrollbars with dynamic cropping [forked]](https://codepen.io/smashingmag/pen/KKeNKvm) by Adrian Bece.
By wrapping the desk and making use of overflow: auto
on the wrapper aspect, we are able to add scrollbars to our desk when there may be not sufficient area on the display screen for the desk to suit.
That is helpful on complicated tables after we need to maintain the default desk format and hierarchy for readabilityand after we need to enable customers to check the information between cells and simply match them to desk headers.
We are able to use a determine
aspect to take action and add a figcaption
for the desk title or use one other HTML container aspect with a heading for a title:
<determine>
<figcaption id="caption">
<h1>Nations with most inhabitants</h1>
</figcaption>
<div class="table-wrapper" position="group" aria-labelledby="caption">
<desk>
<!-- Desk contents -->
</desk>
</div>
</determine>
Both method, this configuration is not usable for customers who’re utilizing keyboard navigation because the desk aspect will not be focusable. We are able to simply try this by including a tabindex
attribute to the desk wrapper aspect or desk aspect immediately (if we aren’t utilizing any wrappers).
<div tabindex="0" class="table-wrapper" position="group" aria-labelledby="caption">
<desk>
<!-- Desk contents -->
</desk>
</div>
Utilizing Shadows To Point out Potential Scrolling Instructions
Browser scrollbars are managed by the working system, which means that they may look and behave otherwise, relying on the machine.

That is vital to know as a result of on some units, like smartphones and tablets, scrollbars aren’t seen straight away, and customers may get the impression that the desk will not be scrollable.

Lea Verou and Roman Komarov have recommended utilizing “scrolling shadows” to subtly point out the scrolling course utilizing gradient background and background-attachment
property. Utilizing this property, we are able to set background gradient conduct when scrolling. We additionally use linear gradients as edge covers for shadows, so we regularly disguise the shadow when the consumer has reached an edge and can’t scroll in that course anymore.
.table-wrapper {
overflow: auto;
background:
linear-gradient(90deg, var(--color-background) 20%, rgba(255, 255, 255, 0)),
linear-gradient(90deg, rgba(255, 255, 255, 0), var(--color-background) 80%)
100% 0,
radial-gradient(farthest-side at 0 0%, var(--color-shadow), rgba(0, 0, 0, 0)),
radial-gradient(farthest-side at 100% 0%, var(--color-shadow), rgba(0, 0, 0, 0))
100% 0;
background-repeat: no-repeat;
background-size: 20% 200%, 20% 200%, 8% 400%, 8% 400%;
background-attachment: native, native, scroll, scroll;
}
See the Pen [Table – scrollbars with background [forked]](https://codepen.io/smashingmag/pen/ExRNxpd) by Adrian Bece.
Discover how shadows subtly disguise and present as we scroll from one edge to a different. And we added this good impact with just some further CSS attributes with out utilizing JavaScript or further HTML parts or wrappers.


Needless to say background-attachment
property is not supported on iOS Safari and some different browsers, so be sure to both present a fallback or take away the background on unsupported browsers. We are able to additionally present useful textual content subsequent to the desk to ensure customers perceive that the desk may be scrolled.

Forcing Desk Cropping
We are able to additionally dynamically set the desk column width to implement desk cropping mid-content, so the consumer will get a transparent trace that the desk is scrollable. I’ve created a easy operate for this instance. The final column will all the time get cropped to 85% of its measurement, and we’ll cut back the variety of seen columns by one if we can’t present no less than 5% of the column’s width.
operate cropTable(visibleCols) {
const desk = doc.querySelector("determine");
const { width: tableWidth } = desk.getBoundingClientRect();
const cols = desk.querySelectorAll("th, td");
const newWidth = tableWidth / visibleCols;
// Resize columns to suit a desk.
cols.forEach(operate(col) {
// All the time make it possible for col is cropped by no less than 15%.
col.model.minWidth = newWidth + (newWidth * 0.15) + "px";
});
// Return if we're about to fall beneath min column rely.
if (visibleCols <= MIN_COLS) {
return;
}
// Measure a pattern desk column to verify if resizing was profitable.
const { width: colWidth } = cols[0].getBoundingClientRect();
// Verify if we must always crop to 1 column much less (calculate new column width).
if (colWidth * visibleCols > tableWidth + newWidth * 0.95) {
cropTable(visibleCols - 1);
}
}
This operate may have to be adjusted to a extra complicated use case. Verify the instance beneath and see how the desk column width responds to window resizing:
See the Pen [Table – scrollbars with dynamic cropping [forked]](https://codepen.io/smashingmag/pen/xxzRxBB) by Adrian Bece.
Because the consumer scrolls the desk, both horizontally or vertically, desk header parts will turn out to be hidden, and the consumer may begin having hassle matching the information to the headers, relying on the desk and knowledge complexity. They must shuttle and memorize the information order.
To keep away from this difficulty, we are able to make the desk headers sticky by making use of place: sticky
and making some model changes to repair the background colour and borders. This can be a nice enhancement as a result of place: sticky
and magnificence changes don’t have an effect on the desk model or format if it’s not scrollable.
See the Pen [Table – fixed table-heads + background [forked]](https://codepen.io/smashingmag/pen/QWxGWXq) by Adrian Bece.
Mixed with the aforementioned “scrolling shadows” impact, we’ve ensured that customers can simply scan the desk knowledge and have correct scrolling indicators.

Stacking Method (Rows To Blocks)
The stacking method has been a extremely popular sample for years. It entails changing every desk row right into a block of vertically stacked columns. This can be a very helpful method for tables the place knowledge will not be comparable or when we don’t want to spotlight the hierarchy and order between objects.
For instance, cart objects in a webshop or a easy contacts desk with particulars — this stuff are impartial, and customers primarily scan them individually and seek for a particular merchandise.
As talked about earlier than, changing the desk rows to blocks often entails making use of show: block
on small screens. Nevertheless, as Adrian Roselli has famous, making use of a show
property overrides native desk semantics and makes the aspect much less accessible on display screen readers. This discovery was jarring to me, as I’ve spent years crafting responsive tables utilizing this sample with out realizing I used to be making them much less accessible within the course of.
It’s not all dangerous information, as Adrian Roselli notes the next change for Chrome model 80:
Large progress. Chrome 80 not drops semantics for HTML tables when the
show
propertiesflex
,grid
,inline-block
, orcontents
are used. The brand new Edge (ChromiEdge) follows swimsuit. Firefox nonetheless dumps desk semantics for less thanshow: contents
. Safari dumps desk semantics for all the pieces.— Adrian Roselli
For this instance, we’ll use show: flex
as an alternative of utilizing show: block
for our stacking sample. This isn’t a really perfect resolution as different browsers may nonetheless drop desk semantics, so be sure to check the accessibility on numerous browsers and units.
/* Small display screen width kinds */
desk, tbody, tbody tr, tbody td, caption {
show: flex;
flex-direction: column;
width: 100%;
word-break: break-all;
}
See the Pen [Table – stacked [forked]](https://codepen.io/smashingmag/pen/bGKBNNr) by Adrian Bece.
Accordion
The stacking sample may look good initially and appears to be a chic resolution from a design perspective. Nevertheless, relying on the desk and knowledge complexity, this sample may considerably improve web page top, and the consumer might need to scroll longer to succeed in the content material beneath the desk.
One enchancment I discovered fascinating was to present the first knowledge column (often the primary column) and disguise the much less vital knowledge (different columns) underneath an accordion. This is sensible for our instance, as customers would first search for a reputation by contact after which scan for his or her particulars within the row.
<tr>
<td onclick="toggle()">
<button aria-label="Broaden contact particulars">
<!-- Icon -->
</button>
<!-- Primary content-->
</td>
<td><!-- Secondary content--></td>
<td><!-- Secondary content--></td>
<td><!-- Secondary content--></td>
</tr>
We’ll assume that the primary desk column comprises major knowledge, and we’ll disguise different columns until a row-active
class is utilized:
/* Small display screen width kinds */
thead tr > *:not(:first-child) {
show: none;
}
tbody,
tbody tr,
tbody td {
show: flex;
flex-direction: column;
word-break: break-all;
}
tbody td:first-child {
flex-direction: row;
align-items: middle;
}
tbody tr:not(.row-active) > *:not(:first-child) {
max-width: 0;
max-height: 0;
overflow: hidden;
padding: 0;
}
Now we’ve all the pieces in place for exhibiting and hiding desk row particulars. We additionally want to remember the display screen reader help and toggle the aria-hidden
property to cover secondary data from display screen readers. We don’t have to toggle the ARIA property if we’re toggling the aspect visibility with the show
property:
operate toggle() {
const row = this.window.occasion.goal.closest("tr");
row.classList.toggle("row-active");
const isActive = row.classList.comprises("row-active");
if (isActive) {
const activeColumns = row.querySelectorAll("td:not(:first-child)");
activeColumns.forEach(operate (col) {
col.setAttribute("aria-hidden", "false");
});
} else {
const activeColumns = row.querySelectorAll(`td[aria-hidden="false"]`);
activeColumns.forEach(operate (col) {
col.setAttribute("aria-hidden", "true");
});
}
We’ll assign this operate to the onclick
attribute on our predominant desk column parts to make the entire column clickable. We additionally have to assign correct ARIA labels when initializing and resizing the window. We don’t need incorrect ARIA labels utilized after we resize the display screen between two modes.
operate handleResize() {
const isMobileMode = window.matchMedia("display screen and (max-width: 880px)");
const inactiveColumns = doc.querySelectorAll(
"tbody > tr > td:not(:first-child)"
);
inactiveColumns.forEach(operate (col) {
col.setAttribute("aria-hidden", isMobileMode.matches.toString());
});
}
//On window resize
window.addEventListener("resize", handleResize);
// On doc load
handleResize();
See the Pen [Table – accordion [forked]](https://codepen.io/smashingmag/pen/dyKOYVr) by Adrian Bece.
This method considerably reduces desk top on smaller screens in comparison with the earlier instance. The content material beneath the desk would now simply be reachable by rapidly scrolling previous the desk.
Toggleable Columns Method
Going again to our scrollable desk instance, in some circumstances, we are able to give customers an choice to customise the desk view by permitting them to point out and conceal particular person columns, briefly lowering desk complexity within the course of. That is helpful for customers that need to scan or evaluate knowledge solely by particular columns.
We’ll use a checkbox type and have them run a JavaScript operate. We’ll solely should go an index of the column that we need to toggle. We’ll have to cover each the columns in knowledge rows in a desk physique and a desk header aspect:
operate toggleRow(index) {
// Disguise an information column for all rows within the desk physique.
allBodyRows.forEach(operate (row) {
const cell = row.querySelector(`td:nth-child(${index + 1})`);
cell.classList.toggle("hidden");
});
// Disguise a desk header aspect.
allHeadCols[index].classList.toggle("hidden");
}
This can be a neat resolution if you wish to keep away from the stacking sample and permit customers to simply evaluate the information however give them choices to cut back the desk complexity by toggling particular person columns. On this case, we’re utilizing a show
property to toggle the visibility, so we don’t should deal with toggling ARIA labels.
See the Pen [Responsive table – column toggle [forked]](https://codepen.io/smashingmag/pen/RwJoWQb) by Adrian Bece.
Conclusion
Desk complexity and design rely upon the use case and the information they show. They typically depend on having sufficient display screen area to show columns in a method consumer can simply scan them. There isn’t a common resolution for making tables responsive and usable on smaller screens for all these potential use circumstances, so we’ve to depend on numerous patterns.
On this article, we’ve coated a handful of those patterns. We’ve targeted totally on easy design adjustments with a scrolling desk sample and a stacking sample and commenced trying out extra complicated patterns that contain including some JavaScript performance.
Within the subsequent article, we’ll discover extra particular and complicated responsive desk patterns and take a look at some responsive desk libraries that add much more helpful options (like filtering and pagination) to tables out of the field.
References
- “Tables, CSS Show Properties, And ARIA”, Adrian Roselli
- “A Responsive Accessible Desk”, Adrian Roselli
- “Capabilities To Add ARIA To Tables And Lists”, Adrian Roselli
- Knowledge Tables, Heydon Pickering
- “Desk Design Patterns On The Net”, Chen Hui Jing
- “Pure CSS Scrolling Shadows With background-attachment: native”, Lea Verou
- Tables Caption & Abstract, Net Accessibility Initiative
- Tables Suggestions And Methods, Net Accessibility Initiative

(yk, il)