Responsive tables
open-source CSS solution

Download on GitHub



Table Demo

Resize your browser to see the two other states the table layout adapts too.

Dessert Calories Fat Carbs Protien Sodium
Frozen yogurt 461.8 22.3 3.9 1.10 6.3
Ice cream sandwich 461.8 22.3 3.9 1.10 6.3
Cupcake 461.8 22.3 3.9 1.10 6.3
Jelly doughnut 461.8 22.3 3.9 1.10 6.3
Eclair 461.8 22.3 3.9 1.10 6.3
Gingerbread 461.8 22.3 3.9 1.10 6.3
Jam scone 461.8 22.3 3.9 1.10 6.3

Source code

HTML

<table class="data-table data-table--large">
    <thead>
      <tr>
        <th>Dessert</th>
        <th>Calories</th>
        <th>Fat</th>
        <th>Carbs</th>
        <th>Protien</th>
        <th>Sodium</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td scope="row" aria-label="Dessert"><a href="#">Frozen yogurt</a></td>
        <td aria-label="Calories">461.8</td>
        <td aria-label="Fat">22.3</td>
        <td aria-label="Carbs">3.9</td>
        <td aria-label="Protien">1.10</td>
        <td aria-label="Sodium">6.3</td>
      </tr>
      <tr>
        <td scope="row" aria-label="Dessert"><i class="table-drop-down-trigger"></i><a href="#">Jam scone</a></td>
        <td aria-label="Calories">461.8</td>
        <td aria-label="Fat">22.3</td>
        <td aria-label="Carbs">3.9</td>
        <td aria-label="Protien">1.10</td>
        <td aria-label="Sodium">6.3</td>
      </tr>
      <tr>
        <td colspan="6" class="table-drop-down">
          <div class="table-drop-down-row">
            <p><a href="#">Link example</a></p>
          </div>
        </td>
      </tr>
    </tbody>
  </table>

CSS

.data-table {
  margin: 20px 0 30px 0;
  overflow-x: scroll;
}

.data-table tr {
  border-bottom: 1px solid #ddd;
}

.data-table thead tr th {
  padding: 16px 56px 16px 24px;
  color: grey;
  font-weight: normal;
  font-size: 13px;
  border-radius: 0px;
}

.data-table tbody tr td {
  padding: 16px 56px 16px 24px;
  font-size: 14px;
  border-radius: 0px;
}

.data-table--medium thead tr th,
.data-table--medium tbody tr td {
  padding: 8px 16px;
}

.data-table--small thead tr th,
.data-table--small tbody tr td {
  padding: 8px 10px;
}

.data-table--small thead tr th {
  font-size: 10px;
}

.data-table--small tbody tr td {
  font-size: 12px;
}

//pf-tables : option 2 : manual call
@media only screen and (min-width: 769px) {

  .data-table--fixed-first-large tr > td:first-child,
  .data-table--fixed-first-large tr > th:first-child { // Specificity 55
  position: absolute;
  z-index: 10;
  background: palette(grey, 50) !important;
  table-layout: fixed;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
  width: 100%;
  padding-left: 10px!important;
  padding-right: 10px!important;
  }

  .data-table--fixed-first-large tr > td:nth-child(2),
  .data-table--fixed-first-large tr > th:nth-child(2) {
  padding-left: 220px!important;
  display: inline-block;
  }

  .data-table--fixed-first-large tr > th:first-child,
  .data-table--fixed-first-large tr > th:first-child .fa {
  color:black !important;
  }

  .data-table--fixed-first-large {
   width: 100%;
   overflow: scroll;
   display: block;
   margin: 0;
   padding: 20px;
  }

  //Message box
  .data-table--fixed-first-large:before {
  content: "Scroll horizontally to view table";
  background: #f5f5f5;
  color: #666;
  font-size: 13px;
  border-radius: 5px;
  padding: 5px 10px;
  display: inline-block;
  margin: 10px auto 20px auto;
  }

  //Stop text wrapping too small on responsive device
  .data-table--fixed-first-large tr,
  .data-table--fixed-first-large th,
  .data-table--fixed-first-large td {
  white-space: nowrap;
  }

  .data-table--fixed-first-large tr > th {
  padding-top: 16px !important;
  padding-bottom: 16px !important;
  line-height: 1;
  }

}

@media only screen and (min-width: 0px) and (max-width: 768px) {
  .data-table {
    width: 100%;
    border: 1px solid #ddd;
    display: table;
  }
  .data-table thead {
    display: none;
  }
  .data-table tr {
    border-bottom: 4px solid #ddd;
    display: block;
  }
  .data-table tr td:first-child {
    font-weight: 700;
    background-color: #eff2f3;
  }
  .data-table td {
    border-bottom: 1px solid #ddd;
    display: block;
    text-align: left;
  }
  .data-table td:before {
    content: attr(aria-label);
    display: block;
    clear: both;
    font-weight: bold;
    color: grey;
    font-size: 0.8em;
  }
  .data-table tbody tr:first-child td {
    border-top: none;
  }
  .data-table tbody tr:first-child td:first-child {
    border-top: 2px solid #dcdcdc;
  }
}

@media only screen and (min-width: 769px) and (max-width: 1000px) {
  .data-table {
    width: 100%;
    overflow: scroll;
    display: block;
    margin: 0;
    padding: 20px;
  }
  .data-table:before {
    content: "Scroll horizontally to view table";
    background: #f5f5f5;
    color: #666;
    font-size: 13px;
    border-radius: 5px;
    padding: 5px 10px;
    display: inline-block;
    margin: 10px auto 20px auto;
  }
  .data-table tr, .data-table th, .data-table td {
    white-space: nowrap;
  }
  .data-table tr > td:first-child,
  .data-table tr > th:first-child {
    position: absolute;
    z-index: 10;
    background: #eff2f3;
    table-layout: fixed;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 200px;
    width: 100%;
    padding-left: 10px;
    padding-right: 10px;
  }
  .data-table tr > td:nth-child(2),
  .data-table tr > th:nth-child(2) {
    padding-left: 220px;
    display: inline-block;
  }
  .data-table tr > th:first-child {
    color: black;
  }
  .data-table tr > th {
    padding-top: 16px !important;
    padding-bottom: 16px !important;
    line-height: 1;
  }
}

//responsive.pf-tables : option 2
@media only screen and (min-width: 769px) and (max-width: 1000px) {

  .data-table.data-table--fixed-first tr > td:first-child,
  .data-table.data-table--fixed-first tr > th:first-child { // Specificity 55
  position: absolute;
  z-index: 10;
  background: palette(grey, 50) !important;
  table-layout: fixed;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
  width: 100%;
  padding-left: 10px!important;
  padding-right: 10px!important;
  }

  .data-table.data-table--fixed-first tr > td:nth-child(2),
  .data-table.data-table--fixed-first tr > th:nth-child(2) {
  padding-left: 220px!important;
  display: inline-block;
  }

  .data-table.data-table--fixed-first tr > th:first-child,
  .data-table.data-table--fixed-first tr > th:first-child .fa {
  color:black !important;
  }

}


//data-table toggle arrow
.data-table.data-table--fixed-first tr .table-drop-down {
display:none;
}

.data-table.data-table--fixed-first tr .table-drop-down.active {
display:table-cell;
position: relative!important;
}

JS

//Table row reveal on trigger
  $(document).ready(function(){

    $('.data-table').on('click', '.table-drop-down-trigger', function() {
      $(this).toggleClass("active");
      $(this).closest("tr").next().find(".table-drop-down").toggleClass("active");
    });

  });

How to use it

Getting started

Copy the CSS into your own style sheet and use the table example HTML as your guiding template for creating your own tables. Adjust the two breakpoints in the css to suit your own but make sure they dont overlap as you will end up with two competing/conflicting styles trying to override each other.

Building your table

Size: The "table" can take a class that will allow you to adjust the overall size.

  • data-table--large
  • data-table--medium
  • data-table--small

Responsive labels

  • Table body "td" tag's can take a attribute of "aria-label='***', which will be used to display the heading of the cell.
  • The first "td" tag of every "tr" row takes the attribute "scope='row'" which creates a visual difference for each row.
  • The Table can take a class of ".data-table--fixed-first-large" which will set the first responsive step as active between the sizes of 769-1000px wide.

Row reveal

  • Requires jQuery code above and understanding of how to implement.
  • Follow example above in HTML code preview window. The row will appear when the trigger class is clicked "table-drop-down-trigger". The following "tr" which contains a "td" with a class of "table-drop-down" will be used to display more content when active.

Extras

You can give your table additional informative support by adding tooltip elements.
Check out Ballon.css.