Responsive Solutions for Feature Comparison Tables

Share this article

Responsive Web Design and tables are not necessarily the best of friends. Many people have researched the situation and a lot of approaches have been devised (some of them were even rounded up in a recent article here on SitePoint). However we are still far away from the perfect solution and the search continues.

While things are still complicated in the generic case, certain specific cases can be treated with a lot more attention. I am talking here about the feature comparison table. We encounter it in many places – when choosing a car and trying to decide what extra options to choose; on web hosting websites when comparing plans and features; on any membership-based portal that lets you decide what features you need to receive in exchange for your money.

Because this kind of table has a relatively stable and consistent structure, it is possible to coax a better behavior when displayed on small screens.

Anatomy of a Feature Comparison Table

The classic comparison table brings together at least three products (displayed in columns) while the features are displayed on rows below. In the traditional structure, the first cell of each row has the name of the feature, while the cells under each product have a checkmark or some other symbol, showing whether that feature belongs to the product or not. We can find great examples of this classic structure: here, here, and here

Based on these examples, we can summarize the structure of a comparison table with the following code:

<table>
  <thead>
    <tr>
      <th>&nbsp;</th>
      <th>Product 1</th>
      <th>Product 2</th>
      <th>Product 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Feature 1</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td>Feature 2</td>
      <td>&mdash;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td>Feature 3</td>
      <td>&mdash;</td>
      <td>&mdash;</td>
      <td>&#10004;</td>
    </tr>
    <tr>
      <td>Feature 4</td>
      <td>&mdash;</td>
      <td>&mdash;</td>
      <td>&#10004;</td>
    </tr>
  </tbody>
</table>

It is easy to identify the elements mentioned earlier: the product names, the feature names, and the marks that show whether the feature is present or not. Note that the &#10004; code represents a checkmark (✔) character.

We now arrive at the root of the problem. In order for the table to maintain optimum effectiveness at low screen widths, a few conditions must be fulfilled:

  • The user must be able to easily differentiate the products;
  • The features must be easily identifiable; and
  • It must be clear if a feature for a product is present or not.

The best way to achieve this result is to shift the cell containing the feature name on top of the other three cells that mark the presence or absence of the feature.

First Solution: Flexbox

How can we get this to happen? One answer is flexbox. If you don’t know what flexbox is or if you need a refresher, you can check out Nick Salloum’s recent article on the topic. The rest of us can dive into the solution.

First we need to make sure our changes happen only on small screens. For this to happen, we target our code using a media query, using the classic width of 768px as a breakpoint:

@media screen and (max-width: 768px) {
  tr {
    display: flex;
    flex-flow: row wrap;
    justify-content: space-around;
  }

  td, th {
    display: block;
    width: 33%;
  }

  th:first-child,
  td:first-child {
    text-align: center;
    background: #efefef;
    width: 100%;
  }

  th:first-child {
    display: none;
  }
}

There are a few important things in this set of rules that make the magic happen:

  • We change the display value for the table row to flex and we tell its children to flow in a row, evenly spaced.
  • Next we direct the cells to adopt display:block to normalize them as ordinary containers (leaving the default value will bring interference from the table rules, especially regarding the size).
  • The next step targets the first cell in each row, making it full width and changing the background color, for added contrast. The flow rules make it stay on top of the other three cells – exactly what we needed.
  • We finish the change by hiding the first th so that there is nothing displayed above the product names.

The demo can be viewed here.

Obviously a solution is valid only as long as it has enough support. According to caniuse.com, support for flexbox is over 80% for the most modern variants and over 93% if we include browser versions that require prefixes or use the previous versions of the rules. Support for IE starts with IE10 (only the 2012 syntax), while IE11 has full support. Because we are mainly interested in support on small screens, we can disregard the lack of support for previous versions of IE. On the mobile front, support starts from Android 4.4 and iOS 7.1. Previous versions require vendor prefixes and don’t support the wrap feature.

You should also provide fallbacks, such as the scrolling div used in Bootstrap. This way the visitors that fall outside the support bracket will still have another alternative for their display.

Second Solution: Extra Markup + ARIA Roles

If a large portion of the browsers you’re going to support lack support for flexbox, there is an alternative. In fact this is the solution I used in a real project in 2013. We will need a bit of extra markup: we will have to add one extra row, duplicating the feature name. While this can appear tedious to do by hand, it can be automated if the information is read from a data source. In the end, the code from our initial example should look like this:

<table>
  <thead>
    <tr>
      <th>&nbsp;</th>
      <th>Product 1</th>
      <th>Product 2</th>
      <th>Product 3</th>
    </tr>
  </thead>
  <tbody>
    <tr class="visible-xs" aria-hidden="true">
      <td>&nbsp;</td>
      <td colspan="3">Feature 1</td>
    </tr>
    <tr>
      <td>Feature 1</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr class="visible-xs" aria-hidden="true">
      <td>&nbsp;</td>
      <td colspan="3">Feature 2</td>
    </tr>
    <tr>
      <td>Feature 2</td>
      <td>&mdash;</td>
      <td>&#10004;</td>
      <td>&#10004;</td>
    </tr>
    <tr class="visible-xs" aria-hidden="true">
      <td>&nbsp;</td>
      <td colspan="3">Feature 3</td>
    </tr>
    <tr>
      <td>Feature 3</td>
      <td>&mdash;</td>
      <td>&mdash;</td>
      <td>&#10004;</td>
    </tr>
    <tr class="visible-xs" aria-hidden="true">
      <td>&nbsp;</td>
      <td colspan="3">Feature 4</td>
    </tr>
    <tr>
      <td>Feature 4</td>
      <td>&mdash;</td>
      <td>&mdash;</td>
      <td>&#10004;</td>
    </tr>
  </tbody>
</table>

The CSS is also pretty simple:

.visible-xs {
  display: none;
}

@media screen and (max-width: 768px) {
  .visible-xs {
    display: table-row;
  }

  td:first-child,
  th:first-child {
    display: none;
  }
}

We can go one extra step for the sake of accessibility and hide the extra markup from screen readers with aria-hidden="true". This way, those screen reader applications that respect the aria-hidden specification will not read the duplicated content twice.

Here is demo of this second solution.

Conclusion

We found here two ways to make a comparison table truly responsive. Both have their pros and cons. In the end, the selected choice should depend on the specifics of your audience. For most cases, the first option (with the fall-back) should be enough. If you really need to cater to the older versions of Android and iOS, you can deploy the second option. Either way, from now on, your feature comparison tables will look a lot better, no matter the screen size.

Frequently Asked Questions (FAQs) on Responsive Solutions for Feature Comparison Tables

What are the key elements to consider when designing a responsive feature comparison table?

When designing a responsive feature comparison table, it’s crucial to consider the following elements: readability, accessibility, and usability. The table should be easy to read on all devices, including mobile phones, tablets, and desktop computers. It should also be accessible to all users, including those with disabilities. Lastly, the table should be user-friendly, meaning it should be easy to navigate and understand.

How can I make my feature comparison table more user-friendly?

To make your feature comparison table more user-friendly, consider using clear and concise language, organizing information logically, and highlighting key features. You can also use visual cues, such as colors and icons, to help users quickly understand the information. Additionally, ensure that the table is responsive and works well on all devices.

How can I ensure that my feature comparison table is accessible to all users?

To ensure that your feature comparison table is accessible, consider using ARIA roles and properties, which can help screen readers understand the table structure. Also, use high contrast colors for text and background to make the table easy to read for users with visual impairments.

How can I use CSS to style my feature comparison table?

CSS can be used to style your feature comparison table in various ways. You can use it to change the table’s layout, colors, fonts, borders, and more. For example, you can use the ‘border’ property to add borders to your table cells, and the ‘background-color’ property to change their background color.

What are some common mistakes to avoid when designing a feature comparison table?

Some common mistakes to avoid when designing a feature comparison table include overloading the table with too much information, using confusing language or jargon, and not making the table responsive. It’s also important to avoid using low contrast colors, which can make the table hard to read.

How can I highlight key features in my feature comparison table?

You can highlight key features in your feature comparison table by using bold or italic text, different colors, or icons. You can also use a separate column or row to highlight the key features.

How can I test the responsiveness of my feature comparison table?

You can test the responsiveness of your feature comparison table by viewing it on different devices and screen sizes. You can also use online tools, such as Google’s Mobile-Friendly Test, to check if your table is mobile-friendly.

How can I use HTML to create a feature comparison table?

You can use HTML to create a feature comparison table by using the ‘table’, ‘tr’ (table row), ‘th’ (table header), and ‘td’ (table data) elements. You can also use the ‘colspan’ and ‘rowspan’ attributes to span cells across multiple columns or rows.

Can I use JavaScript to enhance my feature comparison table?

Yes, you can use JavaScript to enhance your feature comparison table. For example, you can use it to add interactivity, such as sorting and filtering capabilities. You can also use it to dynamically load data into the table.

How can I make my feature comparison table stand out?

To make your feature comparison table stand out, consider using a unique design, vibrant colors, and engaging visuals. You can also use interactive elements, such as hover effects and tooltips, to make the table more engaging. Additionally, ensure that the table provides valuable and accurate information, as this will make it more useful to users.

Adrian SanduAdrian Sandu
View Author

Adrian is a UX Developer, creator, and speaker living in Iasi, Romania. He believes happiness is the true measure of success and he wants to help other developers achieve their dreams. In the off time, he loves playing video games and tinker with custom PC builds.

feature tableLouisLresponsive data tablesresponsive tables
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week