diff --git a/core/modules/views/templates/views-view-table.html.twig b/core/modules/views/templates/views-view-table.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..50ae9d68ae9ca26ffcec810de8a6c6737b92ef71
--- /dev/null
+++ b/core/modules/views/templates/views-view-table.html.twig
@@ -0,0 +1,54 @@
+{#
+/**
+ * @file
+ * Default theme implementation for displaying a view as a table.
+ *
+ * Available variables:
+ * - attributes: Remaining HTML attributes for the element.
+ *   - class: HTML classes that can be used to style contextually through CSS.
+ * - title : The title of this group of rows.
+ * - header: Header labels.
+ * - header_classes: HTML classes to apply to each header cell, indexed by
+ *   the header's key.
+ * - rows: Table row items. Rows are keyed by row number, fields within rows
+ *   are keyed by field ID.
+ *   - field: Table data field ID.
+ *   - content: Table data content.
+ * - row_classes: HTML classes to apply to each row, indexed by row number.
+ *   This matches the index in rows.
+ * - field_classes: HTML classes to apply to each row, indexed by row number.
+ *   This matches the index in columns and rows.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_views_view_table()
+ *
+ * @ingroup themeable
+ */
+#}
+<table{{ attributes }}>
+  {% if title is not empty %}
+    <caption>{{ title }}</caption>
+  {% endif %}
+  {% if header %}
+    <thead>
+      <tr>
+        {% for key, field in header %}
+          <th{{ header_classes[key] }} scope="col">
+            {{ field }}
+          </th>
+        {% endfor %}
+      </tr>
+    </thead>
+  {% endif %}
+  <tbody>
+    {% for row_count, row in rows %}
+      <tr{{ row_classes[row_count] }}>
+        {% for field, content in row %}
+          <td{{ field_classes[field][row_count] }}>
+            {{ content }}
+          </td>
+        {% endfor %}
+      </tr>
+    {% endfor %}
+  </tbody>
+</table>
diff --git a/core/modules/views/templates/views-view-table.tpl.php b/core/modules/views/templates/views-view-table.tpl.php
deleted file mode 100644
index 4d44d42a313b3e5c023f0feaf0c186ed57dd09f6..0000000000000000000000000000000000000000
--- a/core/modules/views/templates/views-view-table.tpl.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * Template to display a view as a table.
- *
- * - $title : The title of this group of rows.  May be empty.
- * - $header: An array of header labels keyed by field id.
- * - $header_classes: An array of header classes keyed by field id.
- * - $fields: An array of CSS IDs to use for each field id.
- * - $classes: A class or classes to apply to the table, based on settings.
- * - $row_classes: An array of classes to apply to each row, indexed by row
- *   number. This matches the index in $rows.
- * - $rows: An array of row items. Each row is an array of content.
- *   $rows are keyed by row number, fields within rows are keyed by field ID.
- * - $field_classes: An array of classes to apply to each field, indexed by
- *   field id, then row number. This matches the index in $rows.
- * @ingroup views_templates
- */
-
-?>
-<table <?php print $attributes; ?>>
-  <?php if (!empty($title)) : ?>
-    <caption><?php print $title; ?></caption>
-  <?php endif; ?>
-  <?php if (!empty($header)) : ?>
-    <thead>
-      <tr>
-        <?php foreach ($header as $field => $label): ?>
-          <th <?php print $header_classes[$field]; ?> scope="col">
-            <?php print $label; ?>
-          </th>
-        <?php endforeach; ?>
-      </tr>
-    </thead>
-  <?php endif; ?>
-  <tbody>
-    <?php foreach ($rows as $row_count => $row): ?>
-      <tr <?php print $row_classes[$row_count]; ?>>
-        <?php foreach ($row as $field => $content): ?>
-          <td <?php print $field_classes[$field][$row_count]; ?>>
-            <?php print $content; ?>
-          </td>
-        <?php endforeach; ?>
-      </tr>
-    <?php endforeach; ?>
-  </tbody>
-</table>
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 6113b3d4f53358b747bf80b1155383a707be08d0..4c3cab8e63cb46fa9b735f1c305fc665b82ea296 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -429,44 +429,52 @@ function template_preprocess_views_view_summary_unformatted(&$vars) {
 }
 
 /**
- * Display a view as a table style.
+ * Prepares variables for views table templates.
+ *
+ * Default template: views-view-table.html.twig.
+ *
+ * @param array $vars
+ *   An associative array containing:
+ *   - view: A ViewExecutable object.
+ *   - rows: The raw row data.
  */
 function template_preprocess_views_view_table(&$vars) {
-  $view     = $vars['view'];
+  $view = $vars['view'];
 
-  // We need the raw data for this grouping, which is passed in as $vars['rows'].
+  // We need the raw data for this grouping, which is passed in
+  // as $vars['rows'].
   // However, the template also needs to use for the rendered fields.  We
   // therefore swap the raw data out to a new variable and reset $vars['rows']
   // so that it can get rebuilt.
   // Store rows so that they may be used by further preprocess functions.
-  $result   = $vars['result'] = $vars['rows'];
+  $result = $vars['result'] = $vars['rows'];
   $vars['rows'] = array();
   $vars['field_classes'] = array();
   $vars['header'] = array();
 
-  $options  = $view->style_plugin->options;
-  $handler  = $view->style_plugin;
+  $options = $view->style_plugin->options;
+  $handler = $view->style_plugin;
 
   $default_row_class = isset($options['default_row_class']) ? $options['default_row_class'] : TRUE;
   $row_class_special = isset($options['row_class_special']) ? $options['row_class_special'] : TRUE;
 
-  $fields   = &$view->field;
-  $columns  = $handler->sanitize_columns($options['columns'], $fields);
+  $fields = &$view->field;
+  $columns = $handler->sanitize_columns($options['columns'], $fields);
 
-  $active   = !empty($handler->active) ? $handler->active : '';
-  $order    = !empty($handler->order) ? $handler->order : 'asc';
+  $active = !empty($handler->active) ? $handler->active : '';
+  $order = !empty($handler->order) ? $handler->order : 'asc';
 
   // A boolean variable which stores whether the table has a responsive class.
   $responsive = FALSE;
 
-  $query    = tablesort_get_query_parameters();
+  $query = tablesort_get_query_parameters();
   if (isset($view->exposed_raw_input)) {
     $query += $view->exposed_raw_input;
   }
 
   foreach ($columns as $field => $column) {
-    // Create a second variable so we can easily find what fields we have and what the
-    // CSS classes should be.
+    // Create a second variable so we can easily find what fields we have and
+    // what the CSS classes should be.
     $vars['fields'][$field] = drupal_clean_css_identifier($field);
     if ($active == $field) {
       $vars['fields'][$field] .= ' active';
@@ -516,11 +524,10 @@ function template_preprocess_views_view_table(&$vars) {
         $vars['header_classes'][$field]['class'][] = $options['info'][$field]['responsive'];
         $responsive = TRUE;
       }
-      // Add a CSS align class to each field if one was set
+      // Add a CSS align class to each field if one was set.
       if (!empty($options['info'][$field]['align'])) {
         $vars['header_classes'][$field]['class'][] = drupal_clean_css_identifier($options['info'][$field]['align']);
       }
-
       // Add a header label wrapper if one was selected.
       if ($vars['header'][$field]) {
         $element_label_type = $fields[$field]->element_label_type(TRUE, TRUE);
@@ -528,17 +535,16 @@ function template_preprocess_views_view_table(&$vars) {
           $vars['header'][$field] = '<' . $element_label_type . '>' . $vars['header'][$field] . '</' . $element_label_type . '>';
         }
       }
-
     }
 
-    // Add a CSS align class to each field if one was set
+    // Add a CSS align class to each field if one was set.
     if (!empty($options['info'][$field]['align'])) {
       $vars['fields'][$field] .= ' ' . drupal_clean_css_identifier($options['info'][$field]['align']);
     }
 
     // Render each field into its appropriate column.
     foreach ($result as $num => $row) {
-      // Add field classes
+      // Add field classes.
       $vars['field_classes'][$field][$num] = array();
       if ($fields[$field]->options['element_default_classes']) {
         $vars['field_classes'][$field][$num]['class'][] = 'views-field';
@@ -575,12 +581,12 @@ function template_preprocess_views_view_table(&$vars) {
         else {
           $vars['rows'][$num][$column] = '';
         }
-
         $vars['rows'][$num][$column] .= $field_output;
       }
     }
 
-    // Remove columns if the option is hide empty column is checked and the field is not empty.
+    // Remove columns if the option is hide empty column is checked and the
+    // field is not empty.
     if (!empty($options['info'][$field]['empty_column'])) {
       $empty = TRUE;
       foreach ($vars['rows'] as $num => $columns) {
@@ -639,7 +645,7 @@ function template_preprocess_views_view_table(&$vars) {
   $vars['attributes']['class'][] = 'cols-' . count($vars['header']);
 
   if (!empty($handler->options['summary'])) {
-    $vars['attributes_array'] = array('summary' => $handler->options['summary']);
+    $vars['attributes']['summary'] = $handler->options['summary'];
   }
   // If the table has headers and it should react responsively to columns hidden
   // with the classes represented by the constants RESPONSIVE_PRIORITY_MEDIUM