shoppersmood

How To Create A Responsive Table Using CSS & JavaScript

Responsive Table that can be fit in any devices. With these simple lines of HTML code, all tables look good on Responsive and will never break your layout on mobile devices. Responsive Table is flexible to fit in screens of any devices with CSS3 Media Queries. On mobile devices, we know that we won't have enough space to show all these columns, so we need to allow table to be scrolled vertically or horizontally with ease or switch to table in the tabular form.

Responsive Table

For Responsive table simply insert a table code and apply the class "mytable" or any class name which are suitable and then add the class "mytable" to table(<table class="mytable">). The styles to make the table responsive are added by applying a media query with rules to switch to the tabular form.

Responsive Table HTML
  • HTML
  • CSS
  • JavaScript
<table class="mytable">
    <thead>
        <tr>
            <th>Sr. No.</th>
            <th>Name</th>
            <th>EMP Code</th>
            <th>Contact No.</th>
            <th>Email ID</th>
            <th>Feedback Data</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>1</td>
            <td>Name</td>
            <td>EMP:01245</td>
            <td>+91 425789569</td>
            <td>xyz@xyz.com</td>
            <td>Ganga, Krishna, Narmada, Kaveri – many of our great rivers are depleting fast. </td>            
        </tr>
        <tr>
            <td>2</td>
            <td>Name</td>
            <td>EMP:01245</td>
            <td>+91 425789569</td>
            <td>xyz@xyz.com</td>
            <td>Ganga, Krishna, Narmada, Kaveri – many of our great rivers are depleting fast. </td>            
        </tr>
    </tbody>
</table> 
<style>
    table.mytable {
        margin: 0 auto;
        border-collapse: collapse;
        width: 100%;
        background: #fff;
    }
    table.mytable thead th {
        padding: 15px 10px;
        font-size: 15px;
        color: #797777;
        border-bottom: 2px solid #2f2b68;
        font-weight: normal;
        word-wrap: break-word;
        white-space: nowrap;
        font-weight: 500;
        text-align: left;
        background: #333;
    }
    table.mytable tbody td {
        padding: 15px 10px;
        font-size: 14px;
        color: #858585;
        font-weight: normal;
        border-bottom: 1px solid #dcdcdc;
    }
    table.mytable tbody td > a > a {
        color: #333;
        text-decoration: none;
    }
    table.mytable tbody tr:nth-child(odd){
        background: #fff;
    }
    table.mytable tbody tr:nth-child(even) {
        background: #f6f6f6;
    }
    @media screen and (max-width: 767px) {
        table.mytable caption {
            background-image: none;
        }
        table.mytable thead {
            display: none;
        }
        table.mytable tbody td {
            display: block;
            padding: 10px;
            text-align: left;
        }
        table.mytable tbody td:before:before {
            content: attr(data-th);
            font-weight: bold;
            display: inline-block;
            width: 100%;
        }
    }
    @media screen and (max-width: 767px) {
        table.mytable thead th {
        padding: 10px;
        }
        table.mytable tbody td {
            padding: 10px;
        }
    }
</style>
<script type="text/javascript">
var headertext = [],
headers = document.querySelectorAll(".mytable th"),
tablerows = document.querySelectorAll(".mytable th"),
tablebody = document.querySelector(".mytable tbody");

for(var i = 0; i < headers.length; i++) {
  var current = headers[i];
  headertext.push(current.textContent.replace(/\r?\n|\r/,""));
}
for (var i = 0, row; row = tablebody.rows[i]; i++) {
  for (var j = 0, col; col = row.cells[j]; j++) {
    col.setAttribute("data-th", headertext[j]);
  }
}

;(function($) {
  $.fn.cardtable = function(options) {
    var $tables = this,
        defaults = {id:'mytable small-only',hideOriginal:true,headIndex:0},
        settings = $.extend({}, defaults, options);

    // checking the "headIndex" option presence... or defaults it to 0
    if(options && options.headIndex)
      headIndex = options.headIndex;
    else
      headIndex = 0;

    return $tables.each(function() {
      $table = $(this);
      if ($table.hasClass('mytable')) {
        return;
      }
      var table_css = $(this).prop('class');
      var $mytable = $('<div></div>');
      if (typeof settings.myClass !== 'undefined') $mytable.addClass(settings.myClass);
      var markup = '';

      $table.addClass('mytable large-only');
      $caption = $table.find("caption").clone();
      $topRow = $table.find('tr').eq(0);
      // using rowIndex and cellIndex in order to reduce ambiguity
      $table.find('tbody tr').each(function(rowIndex,value) {
        // declaring headMarkup and bodyMarkup, to be used for separately head and body of single records
        headMarkup = '';
        bodyMarkup = '';
        tr_class = $(this).prop('class');
        // for the first row, "headIndex" cell is the head of the table
        // for the other rows, put the "headIndex" cell as the head for that row
        // then iterate through the key/values
        $(this).find('td,th').each(function(cellIndex,value) {
          if ($(this).html() !== ''){
            bodyMarkup += '<tr class="' + tr_class +'">';
            if ($topRow.find('td,th').eq(cellIndex).html()){
              bodyMarkup += '<td class="st-key">'+$table.find('thead th').eq(cellIndex).html()+'</td>';
            } else {
              bodyMarkup += '<td class="st-key"></td>';
            }
            bodyMarkup += '<td class="st-val '+$(this).prop('class')  +'">'+$(this).html()+'</td>';
            bodyMarkup += '</tr>';
          }
        });
        markup += '<table class=" '+ table_css +' '+settings.id+'"><tbody>' + headMarkup + bodyMarkup + '</tbody></table>';
      });

      $table.find('tfoot tr td').each(function(rowIndex,value) {
        if ($.trim($(value).text()) !== '') {
          markup += '<table class="'+ table_css + ' ' +settings.id+'"><tbody><tr><td>' + $(value).html() + '</td></tr></tbody></table>';
        }
      });

      $mytable.prepend($caption);
      $mytable.append($(markup));
      $table.before($mytable);
      if (!settings.hideOriginal) $table.show();
    });
  };

  $.fn.mytable = function(options) {
    var $tables = this,
        defaults = {id:'mytable small-only',hideOriginal:true,headIndex:0},
        settings = $.extend({}, defaults, options);
    // checking the "headIndex" option presence... or defaults it to 0
    if(options && options.headIndex)
      headIndex = options.headIndex;
    else
      headIndex = 0;
    return $tables.each(function() {
      var table_css = $(this).prop('class');
      var $mytable = $('<table class="'+ table_css +' '+settings.id+'"><tbody></tbody></table>');
      if (typeof settings.myClass !== 'undefined') $mytable.addClass(settings.myClass);
      var markup = '';

      $table = $(this);
      $table.addClass('mytable large-only');
      $caption = $table.find("caption").clone();
      $topRow = $table.find('tr').eq(0);

      // using rowIndex and cellIndex in order to reduce ambiguity
      $table.find('tr').each(function(rowIndex,value) {
        // declaring headMarkup and bodyMarkup, to be used for separately head and body of single records
        headMarkup = '';
        bodyMarkup = '';
        tr_class = $(this).prop('class');
        // for the first row, "headIndex" cell is the head of the table
        if (rowIndex === 0) {
          // the main heading goes into the markup variable
          markup += '<tr class=" '+tr_class +' "><th class="st-head-row st-head-row-main" colspan="2">'+$(this).find('th,td').eq(headIndex).html()+'</th></tr>';
        }
        else {
          // for the other rows, put the "headIndex" cell as the head for that row
          // then iterate through the key/values
          $(this).find('td,th').each(function(cellIndex,value) {
            if (cellIndex === headIndex) {
              headMarkup = '<tr class="'+ tr_class+'"><th class="st-head-row" colspan="2">'+$(this).html()+'</th></tr>';
            } else {
              if ($(this).html() !== ''){
                bodyMarkup += '<tr class="' + tr_class +'">';
                if ($topRow.find('td,th').eq(cellIndex).html()){
                  bodyMarkup += '<td class="st-key">'+$topRow.find('td,th').eq(cellIndex).html()+'</td>';
                } else {
                  bodyMarkup += '<td class="st-key"></td>';
                }
                bodyMarkup += '<td class="st-val '+$(this).prop('class')  +'">'+$(this).html()+'</td>';
                bodyMarkup += '</tr>';
              }
            }
          });
          markup += headMarkup + bodyMarkup;
        }
      });
      $mytable.prepend($caption);
      $mytable.append($(markup));
      $table.before($mytable);
      if (!settings.hideOriginal) $table.show();
    });
  };

 $.fn.stackcolumns = function(options) {
    var $tables = this,
        defaults = {id:'mytable small-only',hideOriginal:true},
        settings = $.extend({}, defaults, options);
    return $tables.each(function() {
      $table = $(this);
      var num_cols = $table.find('tr').eq(0).find('td,th').length; //first table <tr> must not contain colspans, or add sum(colspan-1) here.
      if(num_cols<3) //stackcolumns has no effect on tables with less than 3 columns
        return;
      var $stackcolumns = $('<table class="'+settings.id+'"></table>');
      if (typeof settings.myClass !== 'undefined') $stackcolumns.addClass(settings.myClass);
      $table.addClass('mytable large-only');
      var tb = $('<tbody></tbody>');
      var col_i = 1; //col index starts at 0 -> start copy at second column.

      while (col_i < num_cols) {
        $table.find('tr').each(function(index,value) {
          var tem = $('<tr></tr>'); // todo opt. copy styles of $this; todo check if parent is thead or tfoot to handle accordingly
          if(index === 0) tem.addClass("st-head-row st-head-row-main");
          first = $(this).find('td,th').eq(0).clone().addClass("st-key");
          var target = col_i;
          // if colspan apply, recompute target for second cell.
          if ($(this).find("*[colspan]").length) {
            var i =0;
            $(this).find('td,th').each(function(index,value) {
                var cs = $(this).attr("colspan");
                if (cs) {
                  cs = parseInt(cs, 10);
                  target -= cs-1;
                  if ((i+cs) > (col_i)) //out of current bounds
                    target += i + cs - col_i -1;
                  i += cs;
                }
                else
                  i++;

                if (i > col_i)
                  return false; //target is set; break.
            });
          }
          second = $(this).find('td,th').eq(target).clone().addClass("st-val").removeAttr("colspan");
          tem.append(first, second);
          tb.append(tem);
        });
        ++col_i;
      }
      $stackcolumns.append($(tb));
      $table.before($stackcolumns);
      if (!(settings.hideOriginal)) {
        $table.show();
      }
    });
  };

}(jQuery));
</script>
Responsive Table using pure css
<style>
.table-responsive {
    display: block;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    word-wrap: break-word;
  white-space: nowrap;
}
.table {
    width: 100%;
}
</style>
<div class="table-responsive">
    <table class="table" border="1">
        <thead>
            <tr>
              <th>Column 1</th>
              <th>Column 2</th>
              <th>Column 3</th>
              <th>Column 4</th>
              <th>Column 5</th>
              <th>Column 6</th>
              <th>Column 7</th>
              <th>Column 8</th>
              <th>Column 9</th>
              <th>Column 10</th>
            </tr>
        </thead>
        <tbody>
            <tr>
              <td>Column 1</td>
              <td>Column 2</td>
              <td>Column 3</td>
              <td>Column 4</td>
              <td>Column 5</td>
              <td>Column 6</td>
              <td>Column 7</td>
              <td>Column 8</td>
              <td>Column 9</td>
              <td>Column 10</td>
            </tr>
        </tbody>
    </table>
</div>

Responsive Table tutorials

You can customize this code further as per your requirement.