diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index 32d4110..1a00206 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -234,6 +234,15 @@ drupal.progress:
     - core/jquery
     - core/drupalSettings
 
+drupal.revealpass:
+  version: VERSION
+  js:
+    misc/revealpass.js: {}
+  dependencies:
+    - core/drupal
+    - core/jquery
+    - core/jquery.once
+
 drupal.states:
   version: VERSION
   js:
diff --git a/core/lib/Drupal/Core/Form/FormBuilderInterface.php b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
index 89813ca..17ab404 100644
--- a/core/lib/Drupal/Core/Form/FormBuilderInterface.php
+++ b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
@@ -178,8 +178,7 @@ public function rebuildForm($form_id, FormStateInterface &$form_state, $old_form
    * $form_state = new FormState();
    * $values['name'] = 'robo-user';
    * $values['mail'] = 'robouser@example.com';
-   * $values['pass']['pass1'] = 'password';
-   * $values['pass']['pass2'] = 'password';
+   * $values['pass']['pass'] = 'password';
    * $values['op'] = t('Create new account');
    * $form_state->setValues($values);
    * \Drupal::formBuilder()->submitForm('user_register_form', $form_state);
diff --git a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
index 3b43dee..141bdc5 100644
--- a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
+++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
@@ -179,6 +179,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#attributes' => array('class' => array('username')),
     );
     $form['admin_account']['account']['pass'] = array(
+      '#title' => $this->t('Password'),
       '#type' => 'password_confirm',
       '#required' => TRUE,
       '#size' => 25,
diff --git a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
index 00295d5..55fec3d 100644
--- a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
+++ b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
@@ -10,10 +10,9 @@
 use Drupal\Core\Form\FormStateInterface;
 
 /**
- * Provides a form element for double-input of passwords.
+ * Provides a form element for entering a password.
  *
- * Formats as a pair of password fields, which do not validate unless the two
- * entered passwords match.
+ * Password form element has hidden text that may be revealed by the user.
  *
  * Usage example:
  * @code
@@ -28,94 +27,26 @@
  *
  * @FormElement("password_confirm")
  */
-class PasswordConfirm extends FormElement {
+class PasswordConfirm extends Password {
 
   /**
    * {@inheritdoc}
    */
   public function getInfo() {
-    $class = get_class($this);
-    return array(
-      '#input' => TRUE,
-      '#markup' => '',
-      '#process' => array(
-        array($class, 'processPasswordConfirm'),
-      ),
-      '#theme_wrappers' => array('form_element'),
-    );
-  }
+    $info = parent::getInfo();
+    $info['#process'][] = [get_class($this), 'processPasswordConfirm'];
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
-    if ($input === FALSE) {
-      $element += ['#default_value' => []];
-      return $element['#default_value'] + ['pass1' => '', 'pass2' => ''];
-    }
-    $value = ['pass1' => '', 'pass2' => ''];
-    // Throw out all invalid array keys; we only allow pass1 and pass2.
-    foreach ($value as $allowed_key => $default) {
-      // These should be strings, but allow other scalars since they might be
-      // valid input in programmatic form submissions. Any nested array values
-      // are ignored.
-      if (isset($input[$allowed_key]) && is_scalar($input[$allowed_key])) {
-        $value[$allowed_key] = (string) $input[$allowed_key];
-      }
-    }
-    return $value;
+    return $info;
   }
 
   /**
    * Expand a password_confirm field into two text boxes.
    */
   public static function processPasswordConfirm(&$element, FormStateInterface $form_state, &$complete_form) {
-    $element['pass1'] =  array(
-      '#type' => 'password',
-      '#title' => t('Password'),
-      '#value' => empty($element['#value']) ? NULL : $element['#value']['pass1'],
-      '#required' => $element['#required'],
-      '#attributes' => array('class' => array('password-field', 'js-password-field')),
-      '#error_no_message' => TRUE,
-    );
-    $element['pass2'] =  array(
-      '#type' => 'password',
-      '#title' => t('Confirm password'),
-      '#value' => empty($element['#value']) ? NULL : $element['#value']['pass2'],
-      '#required' => $element['#required'],
-      '#attributes' => array('class' => array('password-confirm', 'js-password-confirm')),
-      '#error_no_message' => TRUE,
-    );
-    $element['#element_validate'] = array(array(get_called_class(), 'validatePasswordConfirm'));
-    $element['#tree'] = TRUE;
-
-    if (isset($element['#size'])) {
-      $element['pass1']['#size'] = $element['pass2']['#size'] = $element['#size'];
-    }
-
-    return $element;
-  }
-
-  /**
-   * Validates a password_confirm element.
-   */
-  public static function validatePasswordConfirm(&$element, FormStateInterface $form_state, &$complete_form) {
-    $pass1 = trim($element['pass1']['#value']);
-    $pass2 = trim($element['pass2']['#value']);
-    if (strlen($pass1) > 0 || strlen($pass2) > 0) {
-      if (strcmp($pass1, $pass2)) {
-        $form_state->setError($element, t('The specified passwords do not match.'));
-      }
-    }
-    elseif ($element['#required'] && $form_state->getUserInput()) {
-      $form_state->setError($element, t('Password field is required.'));
-    }
-
-    // Password field must be converted from a two-element array into a single
-    // string regardless of validation results.
-    $form_state->setValueForElement($element['pass1'], NULL);
-    $form_state->setValueForElement($element['pass2'], NULL);
-    $form_state->setValueForElement($element, $pass1);
+    $element['#attributes']['class'][] = 'password-field';
+    $element['#attributes']['class'][] = 'password-confirm';
+    $element['#attached']['library'][] = 'core/drupal.revealpass';
+    $element['#attributes']['data-drupal-revealpass'] = TRUE;
 
     return $element;
   }
diff --git a/core/misc/revealpass.js b/core/misc/revealpass.js
new file mode 100644
index 0000000..bb42a31
--- /dev/null
+++ b/core/misc/revealpass.js
@@ -0,0 +1,36 @@
+(function ($, Drupal) {
+
+  "use strict";
+
+  var showPass = Drupal.t('Show password');
+  var hidePass = Drupal.t('Hide password');
+
+  function revealClickHandle(event) {
+    var $pass = $(event.data.password);
+    var $button = $(event.target);
+
+    if ($pass.attr('type') === 'password') {
+      $pass.attr('type', 'text');
+      $button.text(hidePass);
+    }
+    else {
+      $pass.attr('type', 'password');
+      $button.text(showPass);
+    }
+  }
+
+  function revealLink(index, element) {
+    var $trigger = $('<button type="button" class="link">' + showPass + '</button>');
+
+    $trigger.on('click', {password: element}, revealClickHandle);
+    $trigger.insertAfter(element);
+  }
+
+  Drupal.behaviors.revealPass = {
+    attach: function (context) {
+      $(context).find('input[type=password][data-drupal-revealpass]')
+        .once('revealpass')
+        .each(revealLink);
+    }
+  };
+})(jQuery, Drupal);
diff --git a/core/modules/contact/src/Tests/ContactPersonalTest.php b/core/modules/contact/src/Tests/ContactPersonalTest.php
index d133240..5ce5cab 100644
--- a/core/modules/contact/src/Tests/ContactPersonalTest.php
+++ b/core/modules/contact/src/Tests/ContactPersonalTest.php
@@ -289,8 +289,7 @@ protected function checkContactAccess($response, $contact_value = NULL) {
     $edit = array(
       'name' => $name,
       'mail' => $this->randomMachineName() . '@example.com',
-      'pass[pass1]' => $pass = $this->randomString(),
-      'pass[pass2]' => $pass,
+      'pass' => $this->randomString(),
       'notify' => FALSE,
     );
     if (isset($contact_value)) {
diff --git a/core/modules/dblog/src/Tests/DbLogTest.php b/core/modules/dblog/src/Tests/DbLogTest.php
index bffdb2e..18ef4ca 100644
--- a/core/modules/dblog/src/Tests/DbLogTest.php
+++ b/core/modules/dblog/src/Tests/DbLogTest.php
@@ -297,8 +297,7 @@ private function doUser() {
     $edit = array();
     $edit['name'] = $name;
     $edit['mail'] = $name . '@example.com';
-    $edit['pass[pass1]'] = $pass;
-    $edit['pass[pass2]'] = $pass;
+    $edit['pass'] = $pass;
     $edit['status'] = 1;
     $this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
     $this->assertResponse(200);
diff --git a/core/modules/simpletest/src/BrowserTestBase.php b/core/modules/simpletest/src/BrowserTestBase.php
index d93ed8b..a03fdc0 100644
--- a/core/modules/simpletest/src/BrowserTestBase.php
+++ b/core/modules/simpletest/src/BrowserTestBase.php
@@ -978,10 +978,7 @@ protected function installParameters() {
           'account' => array(
             'name' => $this->rootUser->name,
             'mail' => $this->rootUser->getEmail(),
-            'pass' => array(
-              'pass1' => $this->rootUser->passRaw,
-              'pass2' => $this->rootUser->passRaw,
-            ),
+            'pass' => $this->rootUser->passRaw,
           ),
           // form_type_checkboxes_value() requires NULL instead of FALSE values
           // for programmatic form submissions to disable a checkbox.
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 3ad7d56..859e503 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -922,10 +922,7 @@ protected function installParameters() {
           'account' => array(
             'name' => $this->rootUser->name,
             'mail' => $this->rootUser->getEmail(),
-            'pass' => array(
-              'pass1' => $this->rootUser->pass_raw,
-              'pass2' => $this->rootUser->pass_raw,
-            ),
+            'pass' => $this->rootUser->pass_raw,
           ),
           // \Drupal\Core\Render\Element\Checkboxes::valueCallback() requires
           // NULL instead of FALSE values for programmatic form submissions to
diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php
index f0e5af0..2d41375 100644
--- a/core/modules/system/src/Tests/Form/FormTest.php
+++ b/core/modules/system/src/Tests/Form/FormTest.php
@@ -74,11 +74,9 @@ function testRequiredFields() {
     $elements['password']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'password');
     $elements['password']['empty_values'] = $empty_strings;
 
+    // @todo remove element?
     $elements['password_confirm']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'password_confirm');
-    // Provide empty values for both password fields.
-    foreach ($empty_strings as $key => $value) {
-      $elements['password_confirm']['empty_values'][$key] = array('pass1' => $value, 'pass2' => $value);
-    }
+    $elements['password_confirm']['empty_values'] = $empty_strings;
 
     $elements['textarea']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'textarea');
     $elements['textarea']['empty_values'] = $empty_strings;
@@ -611,7 +609,7 @@ function testDisabledElements() {
     // All the elements should be marked as disabled, including the ones below
     // the disabled container.
     $actual_count = count($disabled_elements);
-    $expected_count = 42;
+    $expected_count = 41;
     $this->assertEqual($actual_count, $expected_count, SafeMarkup::format('Found @actual elements with disabled property (expected @expected).', array(
       '@actual' => count($disabled_elements),
       '@expected' => $expected_count,
diff --git a/core/modules/user/css/user.module.css b/core/modules/user/css/user.module.css
index 0b6afcf..6fbec09 100644
--- a/core/modules/user/css/user.module.css
+++ b/core/modules/user/css/user.module.css
@@ -16,6 +16,3 @@
   width: 0;
   background-color: gray;
 }
-.password-confirm-match {
-  visibility: hidden;
-}
diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index 8b0149e..b61c58d 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -119,9 +119,10 @@ public function form(array $form, FormStateInterface $form_state) {
     // assign a password during registration.
     if (!$register) {
       $form['account']['pass'] = array(
+        '#title' => $this->t('Password'),
         '#type' => 'password_confirm',
         '#size' => 25,
-        '#description' => $this->t('To change the current user password, enter the new password in both fields.'),
+        '#description' => $this->t('To change the current user password, enter the new password.'),
       );
 
       // To skip the current password field, the user must have logged in via a
@@ -160,9 +161,10 @@ public function form(array $form, FormStateInterface $form_state) {
     }
     elseif (!$config->get('verify_mail') || $admin) {
       $form['account']['pass'] = array(
+        '#title' => $this->t('Password'),
         '#type' => 'password_confirm',
         '#size' => 25,
-        '#description' => $this->t('Provide a password for the new account in both fields.'),
+        '#description' => $this->t('Provide a password for the new account.'),
         '#required' => TRUE,
       );
     }
diff --git a/core/modules/user/src/Tests/UserCreateFailMailTest.php b/core/modules/user/src/Tests/UserCreateFailMailTest.php
index 83bf5c1..dcae88b 100644
--- a/core/modules/user/src/Tests/UserCreateFailMailTest.php
+++ b/core/modules/user/src/Tests/UserCreateFailMailTest.php
@@ -37,8 +37,7 @@ public function testUserAdd() {
     $edit = array(
       'name' => $name,
       'mail' => $this->randomMachineName() . '@example.com',
-      'pass[pass1]' => $pass = $this->randomString(),
-      'pass[pass2]' => $pass,
+      'pass' => $this->randomString(),
       'notify' => TRUE,
     );
     $this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
diff --git a/core/modules/user/src/Tests/UserCreateTest.php b/core/modules/user/src/Tests/UserCreateTest.php
index 2674f09..15e17a5 100644
--- a/core/modules/user/src/Tests/UserCreateTest.php
+++ b/core/modules/user/src/Tests/UserCreateTest.php
@@ -94,8 +94,7 @@ public function testUserAdd() {
       $edit = array(
         'name' => $name,
         'mail' => $this->randomMachineName() . '@example.com',
-        'pass[pass1]' => $pass = $this->randomString(),
-        'pass[pass2]' => $pass,
+        'pass' => $this->randomString(),
         'notify' => $notify,
       );
       $this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
diff --git a/core/modules/user/src/Tests/UserEditTest.php b/core/modules/user/src/Tests/UserEditTest.php
index 07daeca..c050992 100644
--- a/core/modules/user/src/Tests/UserEditTest.php
+++ b/core/modules/user/src/Tests/UserEditTest.php
@@ -30,18 +30,6 @@ function testUserEdit() {
     $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
     $this->assertRaw(t('The username %name is already taken.', array('%name' => $edit['name'])));
 
-    // Check that filling out a single password field does not validate.
-    $edit = array();
-    $edit['pass[pass1]'] = '';
-    $edit['pass[pass2]'] = $this->randomMachineName();
-    $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
-    $this->assertText(t("The specified passwords do not match."), 'Typing mismatched passwords displays an error message.');
-
-    $edit['pass[pass1]'] = $this->randomMachineName();
-    $edit['pass[pass2]'] = '';
-    $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
-    $this->assertText(t("The specified passwords do not match."), 'Typing mismatched passwords displays an error message.');
-
     // Test that the error message appears when attempting to change the mail or
     // pass without the current password.
     $edit = array();
@@ -55,8 +43,7 @@ function testUserEdit() {
 
     // Test that the user must enter current password before changing passwords.
     $edit = array();
-    $edit['pass[pass1]'] = $new_pass = $this->randomMachineName();
-    $edit['pass[pass2]'] = $new_pass;
+    $edit['pass'] = $new_pass = $this->randomMachineName();
     $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
     $this->assertRaw(t("Your current password is missing or incorrect; it's required to change the %name.", array('%name' => t('Password'))));
 
diff --git a/core/modules/user/src/Tests/UserLanguageCreationTest.php b/core/modules/user/src/Tests/UserLanguageCreationTest.php
index 4c49a3b..59693d2 100644
--- a/core/modules/user/src/Tests/UserLanguageCreationTest.php
+++ b/core/modules/user/src/Tests/UserLanguageCreationTest.php
@@ -55,8 +55,7 @@ function testLocalUserCreation() {
     $edit = array(
       'name' => $username,
       'mail' => $this->randomMachineName(4) . '@example.com',
-      'pass[pass1]' => $username,
-      'pass[pass2]' => $username,
+      'pass' => $username,
     );
 
     $this->drupalPostForm($langcode . '/admin/people/create', $edit, t('Create new account'));
@@ -94,8 +93,7 @@ function testLocalUserCreation() {
     // Set pass_raw so we can login the new user.
     $user->pass_raw = $this->randomMachineName(10);
     $edit = array(
-      'pass[pass1]' => $user->pass_raw,
-      'pass[pass2]' => $user->pass_raw,
+      'pass' => $user->pass_raw,
     );
 
     $this->drupalPostForm($user_edit, $edit, t('Save'));
diff --git a/core/modules/user/src/Tests/UserPasswordResetTest.php b/core/modules/user/src/Tests/UserPasswordResetTest.php
index 420b97a..7e5d9d9 100644
--- a/core/modules/user/src/Tests/UserPasswordResetTest.php
+++ b/core/modules/user/src/Tests/UserPasswordResetTest.php
@@ -119,7 +119,7 @@ function testUserPasswordReset() {
 
     // Change the forgotten password.
     $password = user_password();
-    $edit = array('pass[pass1]' => $password, 'pass[pass2]' => $password);
+    $edit = array('pass' => $password);
     $this->drupalPostForm(NULL, $edit, t('Save'));
     $this->assertText(t('The changes have been saved.'), 'Forgotten password changed.');
 
diff --git a/core/modules/user/src/Tests/UserRegistrationTest.php b/core/modules/user/src/Tests/UserRegistrationTest.php
index 1e16bc7..71e1094 100644
--- a/core/modules/user/src/Tests/UserRegistrationTest.php
+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -77,15 +77,8 @@ function testRegistrationWithoutEmailVerification() {
     $edit['name'] = $name = $this->randomMachineName();
     $edit['mail'] = $mail = $edit['name'] . '@example.com';
 
-    // Try entering a mismatching password.
-    $edit['pass[pass1]'] = '99999.0';
-    $edit['pass[pass2]'] = '99999';
-    $this->drupalPostForm('user/register', $edit, t('Create new account'));
-    $this->assertText(t('The specified passwords do not match.'), 'Typing mismatched passwords displays an error message.');
-
     // Enter a correct password.
-    $edit['pass[pass1]'] = $new_pass = $this->randomMachineName();
-    $edit['pass[pass2]'] = $new_pass;
+    $edit['pass'] = $this->randomMachineName();
     $this->drupalPostForm('user/register', $edit, t('Create new account'));
     $this->container->get('entity.manager')->getStorage('user')->resetCache();
     $accounts = entity_load_multiple_by_properties('user', array('name' => $name, 'mail' => $mail));
@@ -99,8 +92,7 @@ function testRegistrationWithoutEmailVerification() {
     $edit = array();
     $edit['name'] = $name = $this->randomMachineName();
     $edit['mail'] = $mail = $edit['name'] . '@example.com';
-    $edit['pass[pass1]'] = $pass = $this->randomMachineName();
-    $edit['pass[pass2]'] = $pass;
+    $edit['pass'] = $pass = $this->randomMachineName();
     $this->drupalPostForm('user/register', $edit, t('Create new account'));
     $this->assertText(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.'), 'Users are notified of pending approval');
 
@@ -248,8 +240,7 @@ function testRegistrationDefaultValues() {
     $edit = array();
     $edit['name'] = $name = $this->randomMachineName();
     $edit['mail'] = $mail = $edit['name'] . '@example.com';
-    $edit['pass[pass1]'] = $new_pass = $this->randomMachineName();
-    $edit['pass[pass2]'] = $new_pass;
+    $edit['pass'] = $this->randomMachineName();
     $this->drupalPostForm(NULL, $edit, t('Create new account'));
 
     // Check user fields.
diff --git a/core/modules/user/src/Tests/UserRolesAssignmentTest.php b/core/modules/user/src/Tests/UserRolesAssignmentTest.php
index 60f4eab..4167f85 100644
--- a/core/modules/user/src/Tests/UserRolesAssignmentTest.php
+++ b/core/modules/user/src/Tests/UserRolesAssignmentTest.php
@@ -53,8 +53,7 @@ function testCreateUserWithRole() {
     $edit = array(
       'name' => $this->randomMachineName(),
       'mail' => $this->randomMachineName() . '@example.com',
-      'pass[pass1]' => $pass = $this->randomString(),
-      'pass[pass2]' => $pass,
+      'pass' => $this->randomString(),
       "roles[$rid]" => $rid,
     );
     $this->drupalPostForm('admin/people/create', $edit, t('Create new account'));
diff --git a/core/modules/user/user.js b/core/modules/user/user.js
index f4602c6..6496455 100644
--- a/core/modules/user/user.js
+++ b/core/modules/user/user.js
@@ -19,7 +19,7 @@
    */
   Drupal.behaviors.password = {
     attach: function (context, settings) {
-      var $passwordInput = $(context).find('input.js-password-field').once('password');
+      var $passwordInput = $(context).find('input[type=password][data-drupal-revealpass]').once('password');
 
       if ($passwordInput.length) {
         var translate = settings.password;
@@ -31,17 +31,6 @@
         // Add identifying class to password element parent.
         $passwordInputParent.addClass('password-parent');
 
-        // Add the password confirmation layer.
-        $passwordInputParentWrapper
-          .find('input.js-password-confirm')
-          .parent()
-          .append('<div aria-live="polite" aria-atomic="true" class="password-confirm js-password-confirm">' + translate.confirmTitle + ' <span></span></div>')
-          .addClass('confirm-parent');
-
-        var $confirmInput = $passwordInputParentWrapper.find('input.js-password-confirm');
-        var $confirmResult = $passwordInputParentWrapper.find('div.js-password-confirm');
-        var $confirmChild = $confirmResult.find('span');
-
         // If the password strength indicator is enabled, add its markup.
         if (settings.password.showStrengthIndicator) {
           var passwordMeter = '<div class="password-strength"><div class="password-strength__meter"><div class="password-strength__indicator js-password-strength__indicator"></div></div><div aria-live="polite" aria-atomic="true" class="password-strength__title">' + translate.strengthTitle + ' <span class="password-strength__text js-password-strength__text"></span></div></div>';
@@ -50,16 +39,6 @@
           $passwordSuggestions = $passwordInputParentWrapper.find('div.password-suggestions').hide();
         }
 
-        // Check that password and confirmation inputs match.
-        var passwordCheckMatch = function (confirmInputVal) {
-          var success = $passwordInput.val() === confirmInputVal;
-          var confirmClass = success ? 'ok' : 'error';
-
-          // Fill in the success message and set the class accordingly.
-          $confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')])
-            .removeClass('ok error').addClass(confirmClass);
-        };
-
         // Check the password strength.
         var passwordCheck = function () {
           if (settings.password.showStrengthIndicator) {
@@ -84,20 +63,10 @@
             // Update the strength indication text.
             $passwordInputParent.find('.js-password-strength__text').html(result.indicatorText);
           }
-
-          // Check the value in the confirm input and show results.
-          if ($confirmInput.val()) {
-            passwordCheckMatch($confirmInput.val());
-            $confirmResult.css({visibility: 'visible'});
-          }
-          else {
-            $confirmResult.css({visibility: 'hidden'});
-          }
         };
 
         // Monitor input events.
         $passwordInput.on('input', passwordCheck);
-        $confirmInput.on('input', passwordCheck);
       }
     }
   };
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 3d76074..50050d9 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1239,9 +1239,6 @@ function user_element_info_alter(array &$types) {
  */
 function user_form_process_password_confirm($element) {
   $password_settings = array(
-    'confirmTitle' => t('Passwords match:'),
-    'confirmSuccess' => t('yes'),
-    'confirmFailure' => t('no'),
     'showStrengthIndicator' => FALSE,
   );
 
diff --git a/core/themes/classy/css/components/user.css b/core/themes/classy/css/components/user.css
index d62ff25..03ef7f0 100644
--- a/core/themes/classy/css/components/user.css
+++ b/core/themes/classy/css/components/user.css
@@ -26,10 +26,8 @@
   background-color: #77b259;
 }
 
-.password-confirm,
 .password-field,
-.password-strength,
-.password-confirm-match {
+.password-strength {
   width: 55%;
 }
 
@@ -54,6 +52,9 @@
 [dir="rtl"] .password-parent {
   clear: right;
 }
+.password-parent button.link {
+  margin: 0 0.75em;
+}
 
 /* Styling for the status indicator of the passwords match test.  */
 .password-confirm .ok {
diff --git a/core/themes/seven/css/theme/install-page.css b/core/themes/seven/css/theme/install-page.css
index 0ebeaac..5289651 100644
--- a/core/themes/seven/css/theme/install-page.css
+++ b/core/themes/seven/css/theme/install-page.css
@@ -50,14 +50,7 @@
   .install-configure-form .form-type-password {
     width: 100%;
   }
-  .password-confirm,
   .password-field {
     float: none;
   }
-  .password-confirm-match {
-    float: none;
-    width: auto;
-    max-width: 100%;
-  }
-
 }
