Create super flexy responsive tables

Using a simple grid + Flexbox


Bob Visser
CoffeeCup Chief


Diego Naves
CoffeeCup Designer

Production rights

© CoffeeCup Software

Creating responsive tables has always been a challenge. Depending on the table type and use-case, the challenge could be big...or immense. The table below has been created using the CSS flexbox module in Responsive Site Designer. There are a number of benefits of using Flexbox for this type of table, two of them deserve to be mentioned here.

A first advantage is that you don’t have to ‘fight height’. We all know text wraps when the display size decreases. Therefore the table cells with the paragraphs will increase in height, while the cells with the check markers don't. Minimum height settings would then be used to keep the cell borders connected. However, at some point they would disconnect again, requiring another breakpoint and new min-height settings. Very likely this would happen at least once, but often multiple times more, at a smaller width.

Adding updates at some point in the future, surely with different paragraph lengths, can create new disconnects. The result is yet another height battle, making it clear that is a tedious undertaking at the very minimum.

Using the flexbox stretch property all table cells (flex-children in a column) can automagically keep the same height. Thus the cell borders will dynamically continue to connect, no matter the height of a paragraph.

Keeping the content perfectly vertically centered within the cells is something else that was troublesome at best in a world without flexbox. The center property provided by flexbox, makes this super easy. A very welcome addition to our design arsenal!

Dynamically maintaining height and perfect vertical centering are the big advantages of using Flexbox for a table layout.

Now, let’s look at the table and test it a bit before we go into detail on how this was made. Spoiler: it’s surprisingly simple! The design teardown can be found below the table.

To test this in Responsive Site Designer, just use the width slider up top. You can also preview it in the browser or use the publish function to test the table on mobile devices. If you’re viewing this in a browser simply reduce the window size (width).

There are various other approaches to creating responsive tables, all with varying complexity out there. Chris Coyier compiled an overview of responsive data tables. Most of them rely on Javascript and do require coding. Clearly, they could also be created with an app similar to RSD. Let’s call it Responsive Table Builder for good measure — if you’re interested in something like that drop us a note on Twitter and we will consider adding this to our responsive app portfolio. For now, when using tables with a limited number of columns, the flexbox solution below works wonders.

Functional Overview & Pricing


Responsive Tools & Elements

Full range viewport slider — view and work on the design at any possible width right in the app.

Adapt the layout or tweak the design at any display width using custom breakpoints

Up to 10

Responsive images: use the HTML picture element to serve different images at different display widths

Performance matters and lighter weight images can greatly improve the user experience on mobile devices

Enhance responsiveness using Flexbox where desired for sizing, aligning and (re)ordering elements

Mobile-first and desktop downworkflows with corresponding media queries.

Working on a small monitor? Use the zoom-out function to design for larger screens.

Adaptable Layout Creation & Management

Fluid grid systems with configurable columns, gutter and widths.

Choose between ems, pixels, mobile-first and desktop down based grid systems

Sublime column management: span, offset, push and pull with simple drop downs

And change the settings at any breakpoint for an optimal viewing experience on any device!

Optionally use the power of Flexbox for layout perfection

Automagically maintain heights of containers, effortlessly center vertically, evenly space elements and more!

Rows can be constrained to certain widths or allowed to display full-width for appealing visual (background) effects

Subgrids and container elements give unique granular control over the layout at any width

Fix header or footer rows, place elements outside of the flow and more with comprehensive positioning controls

Finishing Touches

Use the tag switcher to create the utmost semantic HTML

Yup, turn that <DIV> into a <NAV>

Add meta data and other head (or footer) code for SEO or plugins

One-click publishing to the CoffeeCup Cloud servers with link sharing for feedback and collaboration

Export clean, semantic, HTML & CSS that can be uploaded to any server (or hand-tweaked with any editor)

(Includes any added plugins)

Traditional CoffeeCup Perks

Free support from the fastest, friendliest, support staff on the web

Plethora of upgrades, free in between major version increases

Cool release special, buy now and save $40 plus get 12+ awesome-looking free themes

Themes are easily worth over $350, wow CoffeeCup!

Table design teardown

Building the flex table.

The HTML structure of the table above uses a row for each feature group, starting with a column for the category header, followed by a series of stacked columns for each feature. This allows us to easily move an entire feature group up or down in the table. The feature columns can be easily moved within the group (drag and drop using the Inspector in RSD or cut and past in a code editor). The feature category columns are self explanatory, they are simply holding a single heading with some styles attached.

The actual feature columns are a lot more interesting. These columns encompass two containers. One container is used for the feature description, the other container for the checkmark icon or explanatory text. This structure can be extended to 3 - 5 containers (which are figuring as table cells — we will get to that with the second demo example further down below).

When viewed in Responsive Site Designer the structure can easily be visualized using the Show Guides dropdown in the toolbar. Simply toggle the selection to show the outline of the Grid Rows, Columns and Containers. Alternatively you can select the Inspector pane and view the elements (DOM) tree — hovering over the elements on the pane will also show their outline.

A free (time limited) version of RSD can be downloaded here. Alternatively, you can load this document in a code editor or use the web inspectors in browsers such as Firefox and Chrome. I also summarized the HTML structure below.

<!—- Feature row -->
<div class="row feature-group-row">
  <!—- Column with feature group heading -->
  <div class="coffee-span-12 feature-group-col top-column">
    <h6 class="feature-group-heading">Responsive Tools & Elements</h6>
  <!—- Stacked feature column using a span-12 --->
  <div class="coffee-span-12 feature-column">
    <!—- Feature paragraph container —->
    <div class="container feature-description">
      <p class="paragraph feature">Full range viewport slider…</p>
    <!—- Feature checkmark container —->
    <div class="container feature-check">
      <span class="glyph check">?</span>
  <!—- Next stacked feature column —->
  <div class="coffee-span-12 feature-column">
    . . .
  . . .

So where’s that <table>  element at?

Tables have always posted a bit of a problem in responsive design. Adjusting the visual structure for small screens can be a serious amount of work. Also, these adjustments often are at the expense of clarity or make the table less meaningful. In our examples, we stack the cells and use design elements such as color to preserve (most of) the clarity and meaning. In order to do that, we would need to instruct the table elements to behave like <div>’s. That’s why we sometimes opt for the 'direct-div’ approach, which has the benefit of a simpler HTML & CSS structure. Although this solution is less semantic, for our HTML structure this does not create accessibility issues. Screenreaders would be able to go through the content just fine. And the information that preceeds the table provides helpful context. But what options do we have if we want, or need, to follow a more semantical approach? 

One approach would be to add ARIA roles. In short, ARIA exists to help web authors communicate semantic information, when the native semantics of the HTML aren’t enough. In this case we could use that to tell accessibility devices, such as screen readers, that they are looking at a div with role="grid” which is aria-readonly=“true”. The same thing could be done for the rows and table cells. Some small tweak to the HTML structure might be needed were we to take this approach. We plan to add support for ARIA in Responsive Site Designer V1.6.

The other option is…to use a real <table>! Too obvious? Well hold on while I explain. I would be using flexbox in a very similar way as we are in the 'direct-div' approach. There would however be some extra markup, some of which would require flexbox properties as well, making the code slightly more complex. And screen readers would navigate the content in our example in largely the same way as in the 'direct-div’ method. Nevertheless, I did some experimenting using flexbox for table rows and cells by hand, and was really happy with the results. I might even argue that the table layout is easier to manage using flexbox, than using ‘old’ methods such as collspan. Even at ‘full-widts’… We plan to add (two) preconfigured responsive table elements to the next version of Responsive Site Designer, at which point I will definitely come back to this statement and update this article!

Phew, that was a big side-step. Now let’s get back to what we came here for and flex our HTML construct!

Adding flex properties

Making it flex

The flex construct starts with the feature column, by setting the display property to flex the column will become the flex-parent and the containers the flex-children.  This will squash the containers if they don’t have content yet. So next is the allocation of space for each of the flex-children (the table cells). The feature-text container gets most of the space, this is done by setting the flex-basis property of this container to 70%

Giving the feature-check container a flex-grow of 1 makes it take up the remaining space, but let’s be precise and also specify the flex-basis. This container gets a value of 30%. This already creates the basic table structure. To make this visible we can add some horizontal and vertical borders — these lines will visualize the table cell structure. 

I chose to add a bottom border to the column (I could have opted for the containers) and a left border to the feature-check container (could have been a right border for the feature-text container) to create the structure depicted above.

Mixing in content

The next step is to place the content into the containers. The feature-container gets one main paragraph, and in some cases a secondary paragraph. The feature-check container gets a font icon, which is sometimes replaced by a short paragraph. The design styles (font-size, left-margin,…) for these items are self explanatory and beyond the scope of this article. 

As we touched upon earlier, all borders continue to stay connected because both the feature-text and feature-check containers ‘flex’ with the content.

If one container becomes higher because of a larger amount of content, the other container follows. This behavior is unique to flexbox and is created by the default  stretch setting for align-items on the flex-parent (the column in this case).

The containers are both flex-children (from the column) and flex-parents (for the paragraphs and font icons). By setting the flex-direction to column the paragraphs are stacked (in case there is more than one). The paragraphs and icons are perfectly vertically aligned in their containers thanks to the center setting for the justify-content property.

Responsifying a flex table.

Beyond the initial flex: adjustments for smaller screens

The table rows have a max-width of 1200px. When display sizes decrease, so do the rows. The table cells keep their percentage of the overall width, but can take up fewer pixels. This causes the text to wrap, which is most noticeable for the feature-containers.

Most of the feature-check containers however, still have abundant width for the single font icon. A good solution can be to increase the percentage of the total width the feature-containers can take up. At the first breakpoint (from right to left) the flex-basis is changed to 80%. That means there’s 20% left for the feature-check containers and their content.

Following the change (use the width slider in RSD to view the actual design adjustment past the breakpoint) it’s clear that this does not create problems for the feature-checks with an icon. However, when these containers hold text, the design feels a bit crammed. To battle that, the font-size of these paragraphs is decreased to 14px. Since they use a double class name selector, the feature-paragraphs are not affected by this change.

To bring the balance back between all these text elements, the font sizes for the category headers and paragraphs is decreased a little as well. Smaller screens are usually a little closer to the eye, creating less of a need for large fonts. But also at a larger distance, the bigger feature paragraphs remain very easy to read at a font-size of 15px.

Changing the table structure

Whatever way we split the widths, at some point there will not be enough room to comfortably display several columns next to each other.

As mentioned in the introduction, depending on the table type a number of solutions is available. For this table I elected to place the feature-check column below the feature description and use a color variation to create the visual connection between the cells. This is done at the second breakpoint (620px).

Several methods can be used to change a flex-based layout at a breakpoint. In this case I changed the column (first flex-parent) back to display block. This will automatically stack them, no further changes are needed. Other than that, it is just a matter of changing the background colors for the different containers (selectors). The feature-group headers get the darkest background (#87827b), while the font color is changed to white. The background of the feature-description container is set to #ededed. The border of the feature-check container is removed but it keeps its white background.

Advantages of this approach are that Javascript is not used and off-screen scrolling by the viewer is not required. Even with more cells this can be a good options as can be seen from the (small) example below.

Responsive Email Designer




Web front end workflow using custom CSS selectors



Full range viewport slider

Automagical column stacking without media queries

Export and import email components for usage across projects

import only


Free support from the fastest, friendliest, support staff on the web

If time permits

These unreal sounding features for an email designer are totally real!

The structure of this new table is very similar to the one we looked at before. The main difference is in the values for the flex-basis — since there are more columns the width is allocated differently. (Please note that I added a second class to the containers so the containers in the previous example would not be affected by the required style changes here.)

To create this table I simply copied a row from the table above and pasted it above. Additional classes were added where needed. Then the feature-check container was duplicated twice. The new flex-basis values are 55% for the feature-description, and 15% for each of the feature-check boxes.

Finally the parent containers must have the same dimensional settings to make the lines connect, so no padding for the table-header for example.

Extra containers, column headers with the different versions of the app, have been added to the table header to provide the context for comparing the features. Clearly the containers in the header column have to use the same values for flex-basis in order to get the same distribution of width.

That’s it, a rock solid yet flexible table structure. Now let’s see what is needed to make this version look good on small screens as well.

Another note about accessibility and semantics

Most screen readers can read the column heading for a cell. There was no real need for this in our previous example, we were presenting a list of features, each feature followed by a ‘check’ or little explanation. The association is pretty straightforward.

In this case each feature checkmark is associated with a version. Readers would need to build a visual reference when scrolling down the table. Listeners would need to associate the ‘checkmark’ order with previous information from the table header. This might be a little harder than remembering the visual placement.

Interestingly enough, without the vertical lines, the visual association might become harder when the check marks are placed below each feature at small widths. These two problems of ‘lost context’ are very similar. I feel both could be addressed by repeating the version column headers within each category header. 

Changing the table structure — part 2

This table is treated differently at smaller widths than our previous example. Simply changing the feature column to display block would make all containers stack, not providing much of an overview.

What we want to do in this case is to place the three feature-check containers next to each other, stacked below the feature-description container. However, flex-children will always remain inline, unless the wrap property of the parent is set to…wrap.

To place the feature-check containers below the feature-text container we simply have to make sure there is no space available for them. Setting the flex-basis value for the feature-description container to 100% will do the job. Now, with the three feature-check containers below, the only remaining task is to adjust their flex-basis as well. Giving each one of them 33% of the space seems a fair solution.

Start flexing

Just like any any new approach, mixing Flexbox into a design might take a little to get used to. It is however a great addition to our toolkit for creating responsive layouts constructs. The more I use it, the more cases I discover where it can be of great help.

If you like this article be sure to also check out the CoffeeCup guide to designing with Flexbox, chock full of real life design cases and interactive demos.

For feedback or questions, just send me a note on twitter (I do check it and and then) or leave a comment in the CoffeeCup forums.

Have a good one!