Responsive HTML Tables

If you have ever built a webpage that includes a wide HTML table, you have likely ran into the problem of how to make it display in a usable way on various common view port sizes. I have researched ideas to solve this but I haven’t been 100% happy with the solutions I have found. Usually there is some facet of a good webpage that is not being satisfied such as semantics, accessibility, or usability. I also don’t like to install additional JavaScript libraries unless absolutely necessary.

I have come up with my own solution that to the best of my knowledge I haven’t seen elsewhere. The following solution discussed is specific to WordPress but the concept can easily be adapted to other platforms.

Summary/Details of Solution:

  • On the template itself in PHP, it outputs 2 copies of the table. One for large view and another for small. The small view is actually a series of individual tables.
  • The large and small table displays are visible based on the visibility classes of whatever front end framework you happen to be using. In my case I am using Foundation 6, but this can easily be adapted for use with Bootstrap. Custom visibility classes can also be used too.
  • I feel the small view of the table display presents a more semantically correct HTML table structure compared to some of the other solutions I found online
  • If images are being displayed in table cells there is no concern for images being downloaded twice (once for the large table view and again for the small view). Once the browser downloads the image the first time, it will be cached in the browser and won’t be downloaded again (as long as the file paths are the same)
  • No need for additional front end libraries to handle responsive tables
  • This approach does have time complexity (on server side PHP code) of O(2n). On the server side, ‘the loop’ for the table data is being executed twice (once for the large table output and again for the small). It is not exactly double the execution time though. Once the WP_Query object fetches the data results, the data will be cached for the second iteration of the loop.
  • This approach does result in additional HTML being sent to the web browser. This is pure HTML text and will have a negligible effect on page load time in most cases
  • This approach can also be adapted for static tables.

Here is the template code. This shows a simple example and can be adapted for your specific needs:

<h3>Responsive Table</h3>
<div class="show-for-small-only" >
  <!-- 'show-for-small-only' is a utility class for the foundation 6 framework which only displays on small view ports -->

  <?php

    $args = array(
      'post_type'      => array('post'),
      'posts_per_page' => -1,
    );                  

    $post_query = new WP_Query( $args );

    if ( $post_query->have_posts() ) {
      while ( $post_query->have_posts() ) {
        $post_query->the_post();
        ?>
          <table>
            <caption><?php the_title(); ?></caption>
            <tr>
              <th>Post Date</th>
              <td><?php the_Date(); ?></td>
            </tr>
            <tr>
              <th>Post Status</th>
              <td><?php echo get_post_status(); ?></td>
            </tr>
            <tr>
              <th>Post Type</th>
              <td>
                <?php echo get_post_type(); ?>
              </td>
            </tr>
            <tr>
              <th>Featured Image</th>
              <td><?php the_post_thumbnail(); ?></td>
            </tr>
          </table>
        <?php
      }
    } else {
      ?>
        <p>No posts to display.</p>
      <?php
    }

    $post_query->rewind_posts();

  ?>
</div>
<div class="hide-for-small-only">
  <!-- 'hide-for-small-only' is a utility class for the foundation 6 framework which only displays on view ports larger than small -->

  <div class="" style="max-width: 100%;overflow-x: auto;" >
    <!-- The 'large view' table is wrapped in a horizontally scrollable div. This accounts for any edge cases where the table is wider than the container, but the small view port hasn't been triggered yet. -->
    <table>
      <thead>
        <tr>
          <th>Title</th>
          <th>Post Date</th>
          <th>Post Status</th>
          <th>Post Type</th>
          <th>Featured Image</th>
        </tr>
      </thead>
      <tbody>
        <?php
          if ( $post_query->have_posts() ) {
            while ( $post_query->have_posts() ) {
              $post_query->the_post();
              ?>
                <tr>
                  <td>
                    <?php the_title(); ?>
                  </td>
                  <td>
                    <?php the_Date(); ?>
                  </td>
                  <td>
                    <?php echo get_post_status(); ?>
                  </td>
                  <td>
                    <?php echo get_post_type(); ?>
                  </td>
                  <td>
                    <?php the_post_thumbnail(); ?>
                  </td>
                </tr>
              <?php
            }
          } else {
            ?>
              <tr>
                <td colspan="6" >
                  No posts to display.
                </td>
              </tr>
            <?php
          }
        ?>
      </tbody>
    </table>
  </div>
  <?php
    wp_reset_query();
  ?>
</div>

And here is the output it produces in this table about Web Rockstar posts. Try resizing the window to see the responsiveness in action:

Responsive Table

Updates to WP Notes Widget Pro and Notes Widget Wrapper Pro
Post Date January 12, 2021
Post Status publish
Post Type post
Featured Image
Optimization Techniques for Video Listing Pages
Post Date November 23, 2018
Post Status publish
Post Type post
Featured Image
Web Rockstar Website Adjustments
Post Date August 3, 2018
Post Status publish
Post Type post
Featured Image
Notes Widget Wrapper PRO Launched!
Post Date April 23, 2018
Post Status publish
Post Type post
Featured Image
Coming Soon – Notes Widget Wrapper PRO
Post Date February 25, 2018
Post Status publish
Post Type post
Featured Image
Title Post Date Post Status Post Type Featured Image
Updates to WP Notes Widget Pro and Notes Widget Wrapper Pro January 12, 2021 publish post
Optimization Techniques for Video Listing Pages November 23, 2018 publish post
Web Rockstar Website Adjustments August 3, 2018 publish post
Notes Widget Wrapper PRO Launched! April 23, 2018 publish post
Coming Soon – Notes Widget Wrapper PRO February 25, 2018 publish post

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>