diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
index caddbad..a3faf22 100644
--- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php
+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -331,7 +331,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
       foreach ($reasons as $reason) {
         $reason_message[] = implode(', ', $reason);
       }
-      throw new ModuleUninstallValidatorException(format_string('The following reasons prevents the modules from being uninstalled: @reasons', array(
+      throw new ModuleUninstallValidatorException(format_string('The following reasons prevent the modules from being uninstalled: @reasons', array(
         '@reasons' => implode(', ', $reason_message),
       )));
     }
diff --git a/core/modules/system/css/system.admin.css b/core/modules/system/css/system.admin.css
index 1dd5da9..b4af1d0 100644
--- a/core/modules/system/css/system.admin.css
+++ b/core/modules/system/css/system.admin.css
@@ -157,7 +157,8 @@ small .admin-link:after {
   margin-bottom: 0;
 }
 .admin-requirements,
-.admin-required {
+.admin-required,
+.validation-reasons {
   font-size: 0.9em;
   color: #666;
 }
diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php
index eb894f6..b1de7be 100644
--- a/core/modules/system/src/Form/ModulesListForm.php
+++ b/core/modules/system/src/Form/ModulesListForm.php
@@ -8,6 +8,7 @@
 namespace Drupal\system\Form;
 
 use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\PreExistingConfigException;
 use Drupal\Core\Config\UnmetDependenciesException;
@@ -209,19 +210,22 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     // Add a wrapper around every package.
     foreach (Element::children($form['modules']) as $package) {
-      $form['modules'][$package] += array(
-        '#type' => 'details',
-        '#title' => $this->t($package),
-        '#open' => TRUE,
-        '#theme' => 'system_modules_details',
+      $table = array(
+        '#type' => 'table',
         '#header' => array(
           array('data' => $this->t('Installed'), 'class' => array('checkbox', 'visually-hidden')),
           array('data' => $this->t('Name'), 'class' => array('name', 'visually-hidden')),
           array('data' => $this->t('Description'), 'class' => array('description', 'visually-hidden', RESPONSIVE_PRIORITY_LOW)),
         ),
-        '#attributes' => array('class' => array('package-listing')),
+      ) + $form['modules'][$package];
+      $form['modules'][$package] = array(
+        '#type' => 'details',
+        '#title' => $this->t($package),
+        '#open' => TRUE,
         // Ensure that the "Core" package comes first.
         '#weight' => $package == 'Core' ? -10 : NULL,
+        '#attributes' => ['class' => ['package-listing']],
+        'table' => $table,
       );
     }
 
@@ -258,31 +262,33 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   protected function buildRow(array $modules, Extension $module, $distribution) {
     // Set the basic properties.
-    $row['#required'] = array();
+    $row['#version'] = $module->info['version'];
     $row['#requires'] = array();
     $row['#required_by'] = array();
 
-    $row['name']['#markup'] = $module->info['name'];
-    $row['description']['#markup'] = $this->t($module->info['description']);
-    $row['version']['#markup'] = $module->info['version'];
-
     // Generate link for module's help page, if there is one.
-    $row['links']['help'] = array();
+    $row_links['help'] = array();
     if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) {
       if ($this->moduleHandler->invoke($module->getName(), 'help', array('help.page.' . $module->getName(), $this->routeMatch))) {
-        $row['links']['help'] = array(
+        $row_links['help'] = array(
           '#type' => 'link',
           '#title' => $this->t('Help'),
           '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]),
-          '#options' => array('attributes' => array('class' =>  array('module-link', 'module-link-help'), 'title' => $this->t('Help'))),
+          '#options' => array(
+            'attributes' => array(
+              'id' => 'edit-modules-core-' . $module->getName() . '-links-help',
+              'class' => ['module-link', 'module-link-help'],
+              'title' => $this->t('Help'),
+            ),
+          ),
         );
       }
     }
 
     // Generate link for module's permission, if the user has access to it.
-    $row['links']['permissions'] = array();
+    $row_links['permissions'] = array();
     if ($module->status && \Drupal::currentUser()->hasPermission('administer permissions') && in_array($module->getName(), $this->moduleHandler->getImplementations('permission'))) {
-      $row['links']['permissions'] = array(
+      $row_links['permissions'] = array(
         '#type' => 'link',
         '#title' => $this->t('Permissions'),
         '#url' => Url::fromRoute('user.admin_permissions'),
@@ -291,7 +297,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
     }
 
     // Generate link for module's configuration page, if it has one.
-    $row['links']['configure'] = array();
+    $row_links['configure'] = array();
     if ($module->status && isset($module->info['configure'])) {
       $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array();
       if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) {
@@ -313,7 +319,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
           $description = $this->titleResolver->getTitle($request, $route_object);
         }
 
-        $row['links']['configure'] = array(
+        $row_links['configure'] = array(
           '#type' => 'link',
           '#title' => $this->t('Configure'),
           '#url' => Url::fromRoute($module->info['configure'], $route_parameters),
@@ -330,7 +336,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
     // Present a checkbox for installing and indicating the status of a module.
     $row['enable'] = array(
       '#type' => 'checkbox',
-      '#title' => $this->t('Install'),
+      '#wrapper_attributes' => ['class' => ['checkbox']],
       '#default_value' => (bool) $module->status,
       '#disabled' => (bool) $module->status,
     );
@@ -424,6 +430,62 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
       }
     }
 
+    // Set id for checkbox here so module label can reference it.
+    $id = Html::getClass('edit-modules-' . $module->info['package'] . '-' . $module->getName() . '-enable');
+
+    $row['enable'] += array(
+      '#id' => $id,
+      '#parents' => ['modules', $module->info['package'], $module->getName(), 'enable'],
+    );
+
+    // Add the module label and expand/collapse functionality.
+    $row['name'] = array(
+      '#type'   => 'inline_template',
+      '#template' => '<label id="module-{{ machine_name }}" for="{{ label_id }}" class="module-name table-filter-text-source">{{ module_name }}</label>',
+      '#context' => array(
+        'machine_name' =>  $module->getName(),
+        'label_id' => $id,
+        'module_name' => $module->info['name'],
+      ),
+      '#wrapper_attributes' => ['class' => ['module']],
+    );
+
+    // Add the description, along with any modules it requires.
+    $description = '<div class="requirements">';
+    $description .= '<div class="admin-requirements">' . $this->t('Machine name: !key', array('!key' => $module->getName())) . '</div>';
+    if ($module->info['version'] || $row['#requires'] || $row['#required_by']) {
+      if ($module->info['version']) {
+        $description .= '<div class="admin-requirements">' . $this->t('Version: !module-version', array('!module-version' => $module->info['version'])) . '</div>';
+      }
+      if ($row['#requires']) {
+        $description .= '<div class="admin-requirements">' . $this->t('Requires: !module-list', array('!module-list' => implode(', ', $row['#requires']))) . '</div>';
+      }
+      if ($row['#required_by']) {
+        $description .= '<div class="admin-requirements">' . $this->t('Required by: !module-list', array('!module-list' => implode(', ', $row['#required_by']))) . '</div>';
+      }
+    }
+    $description .= '</div>';
+
+    $links = '';
+    foreach (['help', 'permissions', 'configure'] as $key) {
+      $links .= (isset($row_links[$key]) ? drupal_render($row_links[$key]) : '');
+    }
+
+    if ($links) {
+      $description .= '  <div class="links">';
+      $description .= $links;
+      $description .= '</div>';
+    }
+
+    $row['description'] = array(
+      '#type' => 'details',
+      '#title' => $this->t('<span class="text"> ' . $module->info['description'] . '</span>'),
+      '#attributes' => array('id' => $id . '-description'),
+      '#description' => $description,
+      '#collapsed' => TRUE,
+      '#wrapper_attributes' => ['class' => ['description', 'expand']]
+    );
+
     return $row;
   }
 
@@ -456,6 +518,7 @@ protected function buildModuleList(FormStateInterface $form_state) {
 
     // First, build a list of all modules that were selected.
     foreach ($packages as $items) {
+      unset($items['table']);
       foreach ($items as $name => $checkbox) {
         if ($checkbox['enable'] && !$this->moduleHandler->moduleExists($name)) {
           $modules['install'][$name] = $data[$name]->info['name'];
diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php
index 153e2ca..e8fb208 100644
--- a/core/modules/system/src/Form/ModulesUninstallForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallForm.php
@@ -110,7 +110,23 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       ),
     );
 
-    $form['modules'] = array();
+    $profile = drupal_get_profile();
+
+    // Sort all modules by their name.
+    if (!empty($uninstallable)) {
+      uasort($uninstallable, 'system_sort_modules_by_info_name');
+      $validation_reasons = $this->moduleInstaller->validateUninstall(array_keys($uninstallable));
+    }
+
+    $form['uninstall'] = array(
+      '#type' => 'table',
+      '#header' => array(
+        'title' => ['data' => $this->t('Name')],
+        'description' => ['data' => $this->t('Description')],
+      ),
+      '#empty' => $this->t('There are no items available to uninstall.'),
+      '#tableselect' => TRUE,
+    );
 
     // Only build the rest of the form if there are any modules available to
     // uninstall;
@@ -118,41 +134,53 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       return $form;
     }
 
-    $profile = drupal_get_profile();
-
-    // Sort all modules by their name.
-    uasort($uninstallable, 'system_sort_modules_by_info_name');
-    $validation_reasons = $this->moduleInstaller->validateUninstall(array_keys($uninstallable));
-
-    $form['uninstall'] = array('#tree' => TRUE);
     foreach ($uninstallable as $module_key => $module) {
-      $name = $module->info['name'] ?: $module->getName();
-      $form['modules'][$module->getName()]['#module_name'] = $name;
-      $form['modules'][$module->getName()]['name']['#markup'] = $name;
-      $form['modules'][$module->getName()]['description']['#markup'] = $this->t($module->info['description']);
-
-      $form['uninstall'][$module->getName()] = array(
-        '#type' => 'checkbox',
-        '#title' => $this->t('Uninstall @module module', array('@module' => $name)),
-        '#title_display' => 'invisible',
+      // Define <label> element for autogenerated checkbox.
+      $form['uninstall'][$module->getName()]['title']['#type'] = 'label';
+      $form['uninstall'][$module->getName()]['title']['#title'] = $module->info['name'] ?: $module->getName();
+
+      $form['uninstall'][$module->getName()]['description'] = array(
+        '#markup' => $this->t($module->info['description']),
+        '#wrapper_attributes' => array(
+          'class' => array('description'),
+        )
       );
 
       // If a validator returns reasons not to uninstall a module,
       // list the reasons and disable the check box.
       if (isset($validation_reasons[$module_key])) {
-        $form['modules'][$module->getName()]['#validation_reasons'] = $validation_reasons[$module_key];
         $form['uninstall'][$module->getName()]['#disabled'] = TRUE;
       }
       // All modules which depend on this one must be uninstalled first, before
       // we can allow this module to be uninstalled. (The installation profile
       // is excluded from this list.)
+      $required_modules = array();
       foreach (array_keys($module->required_by) as $dependent) {
         if ($dependent != $profile && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) {
           $name = isset($modules[$dependent]->info['name']) ? $modules[$dependent]->info['name'] : $dependent;
-          $form['modules'][$module->getName()]['#required_by'][] = $name;
           $form['uninstall'][$module->getName()]['#disabled'] = TRUE;
+          $required_modules[] = $name;
         }
       }
+      if (!empty($required_modules)) {
+        $disabled_message = \Drupal::translation()->formatPlural(count($required_modules),
+          'To uninstall @module, the following module must be uninstalled first: @required_modules',
+          'To uninstall @module, the following modules must be uninstalled first: @required_modules',
+          array('@module' => $module->getName(), '@required_modules' => implode(', ', $required_modules)));
+        $disabled_message = '<div class="admin-requirements">' . $disabled_message . '</div>';
+      }
+      else {
+        $disabled_message = '';
+      }
+      if (isset($validation_reasons[$module_key])) {
+        $disabled_message = \Drupal::translation()->formatPlural(count($validation_reasons[$module_key]),
+          'The following reason prevents @module from being uninstalled: @reasons',
+          'The following reasons prevent @module from being uninstalled: @reasons',
+          array('@module' => $module->getName(), '@reasons' => implode('; ', $validation_reasons[$module_key])));
+        $disabled_message = '<div class="validation-reasons">' . $disabled_message . '</div>';
+      }
+
+      $form['uninstall'][$module->getName()]['description']['uninstall']['#markup'] = $this->t($disabled_message);
     }
 
     $form['#attached']['library'][] = 'system/drupal.system.modules';
diff --git a/core/modules/system/src/Tests/Field/FieldModuleUninstallValidatorTest.php b/core/modules/system/src/Tests/Field/FieldModuleUninstallValidatorTest.php
index f427ade..d571e4b 100644
--- a/core/modules/system/src/Tests/Field/FieldModuleUninstallValidatorTest.php
+++ b/core/modules/system/src/Tests/Field/FieldModuleUninstallValidatorTest.php
@@ -83,7 +83,7 @@ public function testUninstallingModule() {
     }
     catch (ModuleUninstallValidatorException $e) {
       $this->pass($message);
-      $this->assertEqual($e->getMessage(), 'The following reasons prevents the modules from being uninstalled: There is data for the field extra_base_field on entity type Test entity.');
+      $this->assertEqual($e->getMessage(), 'The following reasons prevent the modules from being uninstalled: There is data for the field extra_base_field on entity type Test entity.');
     }
 
     // Verify uninstalling entity_test is not possible when there is content for
diff --git a/core/modules/system/src/Tests/Module/UninstallTest.php b/core/modules/system/src/Tests/Module/UninstallTest.php
index 337258c..1413e6f 100644
--- a/core/modules/system/src/Tests/Module/UninstallTest.php
+++ b/core/modules/system/src/Tests/Module/UninstallTest.php
@@ -56,7 +56,7 @@ function testUninstallPage() {
     $this->drupalGet('admin/modules/uninstall');
     $this->assertTitle(t('Uninstall') . ' | Drupal');
 
-    $this->assertText(\Drupal::translation()->translate('The following reasons prevents Node from being uninstalled: There is content for the entity type: Content'), 'Content prevents uninstalling node module.');
+    $this->assertText('The following reason prevents node from being uninstalled: There is content for the entity type: Content', 'Content prevents uninstalling node module.');
     // Delete the node to allow node to be uninstalled.
     $node->delete();
 
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 81fa6af..d167a52 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -197,160 +197,6 @@ function template_preprocess_status_report(&$variables) {
 }
 
 /**
- * Returns HTML for the modules form.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_system_modules_details($variables) {
-  $form = $variables['form'];
-
-  // Individual table headers.
-  $rows = array();
-  // Iterate through all the modules, which are children of this element.
-  foreach (Element::children($form) as $key) {
-    // Stick the key into $module for easier access.
-    $module = $form[$key];
-    // Create the row for the table.
-    $row = array();
-    // Add the checkbox into the first cell.
-    unset($module['enable']['#title']);
-    $module['#requires'] = array_filter($module['#requires']);
-    $module['#required_by'] = array_filter($module['#required_by']);
-
-    $requires = !empty($module['#requires']);
-    $required_by = !empty($module['#required_by']);
-    $version = !empty($module['version']['#markup']);
-
-    $row[] = array('class' => array('checkbox'), 'data' => drupal_render($module['enable']));
-
-    // Add the module label and expand/collapse functionality.
-    $id = Html::getUniqueId('module-' . $key);
-    $col2 = '<label id="' . $id . '" for="' . $module['enable']['#id'] . '" class="module-name table-filter-text-source">' . drupal_render($module['name']) . '</label>';
-    $row[] = array('class' => array('module'), 'data' => SafeMarkup::set($col2));
-
-    // Add the description, along with any modules it requires.
-    $description = '';
-    $description .= '<div class="requirements">';
-    $description .= '<div class="admin-requirements">' . t('Machine name: !machine-name', array('!machine-name' => '<span dir="ltr" class="table-filter-text-source">' . $key . '</span>')) . '</div>';
-    if ($version || $requires || $required_by) {
-      if ($version) {
-        $description .= '<div class="admin-requirements">' . t('Version: !module-version', array('!module-version' => drupal_render($module['version']))) . '</div>';
-      }
-      if ($requires) {
-        $description .= '<div class="admin-requirements">' . t('Requires: !module-list', array('!module-list' => implode(', ', $module['#requires']))) . '</div>';
-      }
-      if ($required_by) {
-        $description .= '<div class="admin-requirements">' . t('Required by: !module-list', array('!module-list' => implode(', ', $module['#required_by']))) . '</div>';
-      }
-    }
-    $description .= '</div>';
-    $links = '';
-    foreach (array('help', 'permissions', 'configure') as $link_type) {
-      $links .= drupal_render($module['links'][$link_type]);
-    }
-    if ($links) {
-      $description .= '  <div class="links">';
-      $description .= $links;
-      $description .= '</div>';
-    }
-    $details = array(
-      '#type' => 'details',
-      '#title' => SafeMarkup::set('<span class="text"> ' . drupal_render($module['description']) . '</span>'),
-      '#attributes' => array('id' => $module['enable']['#id'] . '-description'),
-      '#description' => $description,
-    );
-    $col4 = drupal_render($details);
-    $row[] = array('class' => array('description', 'expand'), 'data' => $col4);
-
-    $rows[] = $module['#attributes'] + array('data' => $row);
-  }
-
-  $table = array(
-    '#type' => 'table',
-    '#header' => $form['#header'],
-    '#rows' => $rows,
-  );
-  return drupal_render($table);
-}
-
-/**
- * Returns HTML for a table of currently disabled modules.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_system_modules_uninstall($variables) {
-  $form = $variables['form'];
-
-  // No theming for the confirm form.
-  if (isset($form['confirm'])) {
-    return drupal_render($form);
-  }
-
-  // Table headers.
-  $header = array(t('Uninstall'),
-    t('Name'),
-    t('Description'),
-  );
-
-  // Display table.
-  $rows = array();
-  foreach (Element::children($form['modules']) as $module) {
-    $disabled_message = '';
-    // Add the modules requiring the module in question as a validation reason.
-    if (!empty($form['modules'][$module]['#required_by'])) {
-      $form['modules'][$module]['#validation_reasons'][] = \Drupal::translation()->translate('Required by: @modules', array('@modules' => implode(', ',$form['modules'][$module]['#required_by'])));
-    }
-    if (!empty($form['modules'][$module]['#validation_reasons'])) {
-      $disabled_message = \Drupal::translation()->formatPlural(count($form['modules'][$module]['#validation_reasons']),
-        'The following reason prevents @module from being uninstalled: @reasons',
-        'The following reasons prevents @module from being uninstalled: @reasons',
-        array('@module' => $form['modules'][$module]['#module_name'], '@reasons' => implode('; ', $form['modules'][$module]['#validation_reasons'])));
-    }
-    $rows[] = array(
-      array('data' => drupal_render($form['uninstall'][$module]), 'align' => 'center'),
-      array(
-        'data' => array(
-          '#type' => 'inline_template',
-          '#template' => '<label for="{{ module_id }}" class="module-name table-filter-text-source">{{ module_name }}</label>',
-          '#context' => array('module_id' => $form['uninstall'][$module]['#id'], 'module_name' => drupal_render($form['modules'][$module]['name'])),
-        )
-      ),
-      array(
-        'data' => array(
-          '#type' => 'inline_template',
-          '#template' => '{{ module_description }} {% if disabled_message is not empty %} <div class="admin-requirements">{{ disabled_message }}</div> {% endif %}',
-          '#context' => array(
-            'module_description' => drupal_render($form['modules'][$module]['description']),
-            'disabled_message' => $disabled_message,
-          ),
-        ),
-        'class' => array('description'),
-      ),
-    );
-  }
-
-  $table = array(
-    '#type' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#empty' => t('No modules are available to uninstall.'),
-  );
-  $output = drupal_render($form['filters']);
-  $output .= drupal_render($table);
-  $output .= drupal_render_children($form);
-
-  return $output;
-}
-
-/**
  * Prepares variables for appearance page templates.
  *
  * Default template: system-themes-page.html.twig.
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 88f9023..3e6ea8a 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -188,16 +188,6 @@ function system_theme() {
     'confirm_form' => array(
       'render element' => 'form',
     ),
-    'system_modules_details' => array(
-      'render element' => 'form',
-      'file' => 'system.admin.inc',
-      'function' => 'theme_system_modules_details',
-    ),
-    'system_modules_uninstall' => array(
-      'render element' => 'form',
-      'file' => 'system.admin.inc',
-      'function' => 'theme_system_modules_uninstall',
-    ),
     'status_report' => array(
       'variables' => array('requirements' => NULL),
       'file' => 'system.admin.inc',
