diff --git a/core/includes/form.inc b/core/includes/form.inc
index a555bf0..f46ca8c 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -2640,7 +2640,6 @@ function form_process_select($element) {
 function theme_select($variables) {
   $element = $variables['element'];
   element_set_attributes($element, array('id', 'name', 'size'));
-  _form_set_class($element, array('form-select'));
 
   return '<select' . drupal_attributes($element['#attributes']) . '>' . form_select_options($element) . '</select>';
 }
@@ -2753,8 +2752,11 @@ function form_get_options($element, $key) {
  */
 function theme_fieldset($variables) {
   $element = $variables['element'];
+
+  // The .form-wrapper class is required for #states to treat fieldsets like
+  // containers.
+  $element['#attributes']['class'][] = 'form-wrapper';
   element_set_attributes($element, array('id'));
-  _form_set_class($element, array('form-wrapper'));
 
   $output = '<fieldset' . drupal_attributes($element['#attributes']) . '>';
   if (!empty($element['#title'])) {
@@ -2796,7 +2798,6 @@ function theme_radio($variables) {
   if (isset($element['#return_value']) && $element['#value'] !== FALSE && $element['#value'] == $element['#return_value']) {
     $element['#attributes']['checked'] = 'checked';
   }
-  _form_set_class($element, array('form-radio'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />';
 }
@@ -3064,7 +3065,6 @@ function theme_checkbox($variables) {
   if (!empty($element['#checked'])) {
     $element['#attributes']['checked'] = 'checked';
   }
-  _form_set_class($element, array('form-checkbox'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />';
 }
@@ -3867,7 +3867,6 @@ function theme_button($variables) {
   $element['#attributes']['type'] = 'submit';
   element_set_attributes($element, array('id', 'name', 'value'));
 
-  $element['#attributes']['class'][] = 'form-' . $element['#button_type'];
   if (!empty($element['#attributes']['disabled'])) {
     $element['#attributes']['class'][] = 'form-button-disabled';
   }
@@ -3936,7 +3935,6 @@ function theme_textfield($variables) {
   $element = $variables['element'];
   $element['#attributes']['type'] = 'text';
   element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
-  _form_set_class($element, array('form-text'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
 }
@@ -3956,7 +3954,6 @@ function theme_email($variables) {
   $element = $variables['element'];
   $element['#attributes']['type'] = 'email';
   element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
-  _form_set_class($element, array('form-email'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
 }
@@ -3990,7 +3987,6 @@ function theme_tel($variables) {
   $element = $variables['element'];
   $element['#attributes']['type'] = 'tel';
   element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
-  _form_set_class($element, array('form-tel'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
 }
@@ -4011,7 +4007,6 @@ function theme_number($variables) {
 
   $element['#attributes']['type'] = 'number';
   element_set_attributes($element, array('id', 'name', 'value', 'step', 'min', 'max', 'placeholder'));
-  _form_set_class($element, array('form-number'));
 
   $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
 
@@ -4034,7 +4029,6 @@ function theme_range($variables) {
 
   $element['#attributes']['type'] = 'range';
   element_set_attributes($element, array('id', 'name', 'value', 'step', 'min', 'max'));
-  _form_set_class($element, array('form-range'));
 
   $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
 
@@ -4126,7 +4120,6 @@ function theme_url($variables) {
   $element = $variables['element'];
   $element['#attributes']['type'] = 'url';
   element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
-  _form_set_class($element, array('form-url'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
 }
@@ -4146,7 +4139,6 @@ function theme_search($variables) {
   $element = $variables['element'];
   $element['#attributes']['type'] = 'search';
   element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
-  _form_set_class($element, array('form-search'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
 }
@@ -4202,7 +4194,6 @@ function theme_form($variables) {
 function theme_textarea($variables) {
   $element = $variables['element'];
   element_set_attributes($element, array('id', 'name', 'rows', 'cols', 'placeholder'));
-  _form_set_class($element, array('form-textarea'));
 
   $wrapper_attributes = array(
     'class' => array('form-textarea-wrapper'),
@@ -4234,7 +4225,6 @@ function theme_password($variables) {
   $element = $variables['element'];
   $element['#attributes']['type'] = 'password';
   element_set_attributes($element, array('id', 'name', 'size', 'maxlength', 'placeholder'));
-  _form_set_class($element, array('form-text'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />';
 }
@@ -4284,7 +4274,6 @@ function theme_file($variables) {
   $element = $variables['element'];
   $element['#attributes']['type'] = 'file';
   element_set_attributes($element, array('id', 'name', 'size'));
-  _form_set_class($element, array('form-file'));
 
   return '<input' . drupal_attributes($element['#attributes']) . ' />';
 }
@@ -4299,6 +4288,8 @@ function theme_file($variables) {
  * - form-item-#name: The internal form element #name (usually derived from the
  *   $form structure and set via form_builder()).
  * - form-disabled: Only set if the form element is #disabled.
+ * - form-required: Only set if the form element is #required.
+ * - form-error: Only set if the form element contains an error.
  *
  * In addition to the element itself, the DIV contains a label for the element
  * based on the optional #title_display property, and an optional #description.
@@ -4362,6 +4353,15 @@ function theme_form_element($variables) {
   if (!empty($element['#attributes']['disabled'])) {
     $attributes['class'][] = 'form-disabled';
   }
+  // Add a class indicating that the form element is required.
+  if (!empty($element['#required'])) {
+    $attributes['class'][] = 'form-required';
+  }
+  // Add a class indicating that the form element contains an error.
+  if (isset($element['#parents']) && form_get_error($element)) {
+    $attributes['class'][] = 'form-error';
+  }
+
   $output = '<div' . drupal_attributes($attributes) . '>' . "\n";
 
   // If #title is not set, we don't display any label or required marker.
@@ -4416,7 +4416,7 @@ function theme_form_required_marker($variables) {
   // This is also used in the installer, pre-database setup.
   $t = get_t();
   $attributes = array(
-    'class' => 'form-required',
+    'class' => 'form-required-marker',
     'title' => $t('This field is required.'),
   );
   return '<abbr' . drupal_attributes($attributes) . '>*</abbr>';
@@ -4479,38 +4479,6 @@ function theme_form_element_label($variables) {
 }
 
 /**
- * Sets a form element's class attribute.
- *
- * Adds 'required' and 'error' classes as needed.
- *
- * @param $element
- *   The form element.
- * @param $name
- *   Array of new class names to be added.
- */
-function _form_set_class(&$element, $class = array()) {
-  if (!empty($class)) {
-    if (!isset($element['#attributes']['class'])) {
-      $element['#attributes']['class'] = array();
-    }
-    $element['#attributes']['class'] = array_merge($element['#attributes']['class'], $class);
-  }
-  // This function is invoked from form element theme functions, but the
-  // rendered form element may not necessarily have been processed by
-  // form_builder().
-  if (!empty($element['#required'])) {
-    $element['#attributes']['class'][] = 'required';
-    // @todo Rename the _form_set_class() function to reflect that we're setting
-    //   non-class attributes too.
-    $element['#attributes']['required'] = 'required';
-    $element['#attributes']['aria-required'] = 'true';
-  }
-  if (isset($element['#parents']) && form_get_error($element)) {
-    $element['#attributes']['class'][] = 'error';
-  }
-}
-
-/**
  * @} End of "defgroup form_api".
  */
 
diff --git a/core/misc/states.js b/core/misc/states.js
index fa7a101..ec4373f 100644
--- a/core/misc/states.js
+++ b/core/misc/states.js
@@ -496,7 +496,7 @@ $(document).bind('state:disabled', function(e) {
     $(e.target)
       .attr('disabled', e.value)
       .filter('.form-element')
-        .closest('.form-item, .form-submit, .form-wrapper').toggleClass('form-disabled', e.value);
+        .closest('.form-item, input[type=submit], .form-wrapper').toggleClass('form-disabled', e.value);
 
     // Note: WebKit nightlies don't reflect that change correctly.
     // See https://bugs.webkit.org/show_bug.cgi?id=23789
@@ -506,17 +506,17 @@ $(document).bind('state:disabled', function(e) {
 $(document).bind('state:required', function(e) {
   if (e.trigger) {
     if (e.value) {
-      $(e.target).closest('.form-item, .form-wrapper').find('label').append('<abbr class="form-required" title="' + Drupal.t('This field is required.') + '">*</abbr>');
+      $(e.target).closest('.form-item, .form-wrapper').find('label').append('<abbr class="form-required-marker" title="' + Drupal.t('This field is required.') + '">*</abbr>');
     }
     else {
-      $(e.target).closest('.form-item, .form-wrapper').find('label .form-required').remove();
+      $(e.target).closest('.form-item, .form-wrapper').find('label .form-required-marker').remove();
     }
   }
 });
 
 $(document).bind('state:visible', function(e) {
   if (e.trigger) {
-    $(e.target).closest('.form-item, .form-submit, .form-wrapper').toggle(e.value);
+    $(e.target).closest('.form-item, input[type=submit], .form-wrapper').toggle(e.value);
   }
 });
 
diff --git a/core/misc/tableselect.js b/core/misc/tableselect.js
index 2bf708e..176ab4f 100644
--- a/core/misc/tableselect.js
+++ b/core/misc/tableselect.js
@@ -28,7 +28,7 @@ Drupal.tableSelect = function () {
   };
 
   // Find all <th> with class select-all, and insert the check all checkbox.
-  $table.find('th.select-all').prepend($('<input type="checkbox" class="form-checkbox" />').attr('title', strings.selectAll)).click(function (event) {
+  $table.find('th.select-all').prepend($('<input type="checkbox" />').attr('title', strings.selectAll)).click(function (event) {
     if ($(event.target).is('input:checkbox')) {
       // Loop through all checkboxes and set their state to the select all checkbox' state.
       checkboxes.each(function () {
diff --git a/core/modules/color/color.admin-rtl.css b/core/modules/color/color.admin-rtl.css
index d5bfbe8..f4d4a53 100644
--- a/core/modules/color/color.admin-rtl.css
+++ b/core/modules/color/color.admin-rtl.css
@@ -17,11 +17,11 @@
   float: right;
   clear: right;
 }
-.color-form .form-text,
-.color-form .form-select {
+.color-form input[type=text],
+.color-form select {
   float: right;
 }
-.color-form .form-text {
+.color-form input[type=text] {
   margin-right: 0;
   margin-left: 5px;
 }
diff --git a/core/modules/color/color.admin.css b/core/modules/color/color.admin.css
index e9aee91..fd71199 100644
--- a/core/modules/color/color.admin.css
+++ b/core/modules/color/color.admin.css
@@ -26,11 +26,11 @@
   clear: left; /* LTR */
   width: 10em;
 }
-.color-form .form-text,
-.color-form .form-select {
+.color-form input[type=text],
+.color-form select {
   float: left; /* LTR */
 }
-.color-form .form-text {
+.color-form input[type=text] {
   text-align: center;
   margin-right: 5px; /* LTR */
   cursor: pointer;
diff --git a/core/modules/color/color.js b/core/modules/color/color.js
index 31c526e..4f9befc 100644
--- a/core/modules/color/color.js
+++ b/core/modules/color/color.js
@@ -185,8 +185,7 @@ Drupal.behaviors.color = {
     }
 
     // Initialize color fields.
-    form.find('#palette input.form-text')
-    .each(function () {
+    form.find('#palette input[type=text]').each(function () {
       // Extract palette field name
       this.key = this.id.substring(13);
 
diff --git a/core/modules/dblog/dblog.css b/core/modules/dblog/dblog.css
index 88f4ba0..a094edc 100644
--- a/core/modules/dblog/dblog.css
+++ b/core/modules/dblog/dblog.css
@@ -10,7 +10,7 @@
    */
   width: 15em;
 }
-#dblog-filter-form .form-type-select select {
+#dblog-filter-form select {
   width: 100%;
 }
 #dblog-filter-form .form-actions {
diff --git a/core/modules/field/tests/field.test b/core/modules/field/tests/field.test
index 9a850d9..07fdd9f 100644
--- a/core/modules/field/tests/field.test
+++ b/core/modules/field/tests/field.test
@@ -1757,14 +1757,14 @@ class FieldFormTestCase extends FieldTestCase {
     );
     $this->drupalPost('test-entity/nested/1/2', $edit, t('Save'));
     $this->assertRaw(t('%label does not accept the value -1', array('%label' => 'Unlimited field')), t('Entity 1: the field validation error was reported.'));
-    $error_field = $this->xpath('//input[@id=:id and contains(@class, "error")]', array(':id' => 'edit-field-unlimited-und-1-value'));
+    $error_field = $this->xpath('//input[@id=:id]/parent::*[contains(@class, "form-error")]', array(':id' => 'edit-field-unlimited-und-1-value'));
     $this->assertTrue($error_field, t('Entity 1: the error was flagged on the correct element.'));
     $edit = array(
       'entity_2[field_unlimited][und][1][value]' => -1,
     );
     $this->drupalPost('test-entity/nested/1/2', $edit, t('Save'));
     $this->assertRaw(t('%label does not accept the value -1', array('%label' => 'Unlimited field')), t('Entity 2: the field validation error was reported.'));
-    $error_field = $this->xpath('//input[@id=:id and contains(@class, "error")]', array(':id' => 'edit-entity-2-field-unlimited-und-1-value'));
+    $error_field = $this->xpath('//input[@id=:id]/parent::*[contains(@class, "form-error")]', array(':id' => 'edit-entity-2-field-unlimited-und-1-value'));
     $this->assertTrue($error_field, t('Entity 2: the error was flagged on the correct element.'));
 
     // Test that reordering works on both entities.
diff --git a/core/modules/file/file.admin.css b/core/modules/file/file.admin.css
index c299bc0..3a77e64 100644
--- a/core/modules/file/file.admin.css
+++ b/core/modules/file/file.admin.css
@@ -7,8 +7,8 @@
 /**
  * File upload widget.
  */
-.form-managed-file .form-file,
-.form-managed-file .form-submit {
+.form-managed-file input[type=file],
+.form-managed-file input[type=submit] {
   margin: 0;
 }
 .form-managed-file input.progress-disabled {
diff --git a/core/modules/file/file.js b/core/modules/file/file.js
index cec3fe8..fbcaac9 100644
--- a/core/modules/file/file.js
+++ b/core/modules/file/file.js
@@ -49,13 +49,13 @@ Drupal.behaviors.fileValidateAutoAttach = {
 Drupal.behaviors.fileButtons = {
   attach: function (context) {
     var $context = $(context);
-    $context.find('input.form-submit').bind('mousedown', Drupal.file.disableFields);
-    $context.find('div.form-managed-file input.form-submit').bind('mousedown', Drupal.file.progressBar);
+    $context.find('input[type=submit]').bind('mousedown', Drupal.file.disableFields);
+    $context.find('div.form-managed-file input[type=submit]').bind('mousedown', Drupal.file.progressBar);
   },
   detach: function (context) {
     var $context = $(context);
-    $context.find('input.form-submit').unbind('mousedown', Drupal.file.disableFields);
-    $context.find('div.form-managed-file input.form-submit').unbind('mousedown', Drupal.file.progressBar);
+    $context.find('input[type=submit]').unbind('mousedown', Drupal.file.disableFields);
+    $context.find('div.form-managed-file input[type=submit]').unbind('mousedown', Drupal.file.progressBar);
   }
 };
 
@@ -111,7 +111,7 @@ Drupal.file = Drupal.file || {
     // Check if we're working with an "Upload" button.
     var $enabledFields = [];
     if ($(this).closest('div.form-managed-file').length > 0) {
-      $enabledFields = $(this).closest('div.form-managed-file').find('input.form-file');
+      $enabledFields = $(this).closest('div.form-managed-file').find('input[type=file]');
     }
 
     // Temporarily disable upload fields other than the one we're currently
@@ -122,7 +122,7 @@ Drupal.file = Drupal.file || {
     // behaviors) are excuted before any timeout functions are called, so we
     // don't have to worry about the fields being re-enabled too soon.
     // @todo If the previous sentence is true, why not set the timeout to 0?
-    var $fieldsToTemporarilyDisable = $('div.form-managed-file input.form-file').not($enabledFields).not(':disabled');
+    var $fieldsToTemporarilyDisable = $('div.form-managed-file input[type=file]').not($enabledFields).not(':disabled');
     $fieldsToTemporarilyDisable.attr('disabled', 'disabled');
     setTimeout(function (){
       $fieldsToTemporarilyDisable.attr('disabled', '');
diff --git a/core/modules/filter/filter.admin.js b/core/modules/filter/filter.admin.js
index b002041..a305c3f 100644
--- a/core/modules/filter/filter.admin.js
+++ b/core/modules/filter/filter.admin.js
@@ -5,7 +5,7 @@
 Drupal.behaviors.filterStatus = {
   attach: function (context, settings) {
     var $context = $(context);
-    $context.find('#filters-status-wrapper input.form-checkbox').once('filter-status', function () {
+    $context.find('#filters-status-wrapper input[type=checkbox]').once('filter-status', function () {
       var $checkbox = $(this);
       // Retrieve the tabledrag row belonging to this filter.
       var $row = $context.find('#' + $checkbox.attr('id').replace(/-status$/, '-weight')).closest('tr');
diff --git a/core/modules/locale/locale.test b/core/modules/locale/locale.test
index 09523fc..556d2c0 100644
--- a/core/modules/locale/locale.test
+++ b/core/modules/locale/locale.test
@@ -439,8 +439,8 @@ class LocaleTranslationFunctionalTest extends WebTestBase {
       );
       $this->drupalPost($path, $edit, t('Save translations'));
       // Check for a form error on the textarea.
-      $form_class = $this->xpath('//form[@id="locale-translate-edit-form"]//textarea/@class');
-      $this->assertNotIdentical(FALSE, strpos($form_class[0], 'error'), t('The string was rejected as unsafe.'));
+      $form_class = $this->xpath('//form[@id="locale-translate-edit-form"]//textarea/parent::*[contains(@class, "form-error")]');
+      $this->assertNotIdentical(FALSE, $form_class, t('The string was rejected as unsafe.'));
       $this->assertNoText(t('The string has been saved.'), t('The string was not saved.'));
     }
   }
diff --git a/core/modules/poll/poll.admin.css b/core/modules/poll/poll.admin.css
index f118de3..5edb8a8 100644
--- a/core/modules/poll/poll.admin.css
+++ b/core/modules/poll/poll.admin.css
@@ -7,7 +7,7 @@
 .node-form #edit-poll-more {
   margin: 0;
 }
-.node-form #poll-choice-table .form-text {
+.node-form #poll-choice-table input[type=text] {
   display: inline;
   width: auto;
 }
diff --git a/core/modules/poll/poll.theme.css b/core/modules/poll/poll.theme.css
index 3e91786..5144296 100644
--- a/core/modules/poll/poll.theme.css
+++ b/core/modules/poll/poll.theme.css
@@ -29,6 +29,6 @@
 td.poll-chtext {
   width: 80%;
 }
-td.poll-chvotes .form-text {
+td.poll-chvotes input[type=text] {
   width: 85%;
 }
diff --git a/core/modules/simpletest/simpletest.js b/core/modules/simpletest/simpletest.js
index 1e2d246..3c16f2f 100644
--- a/core/modules/simpletest/simpletest.js
+++ b/core/modules/simpletest/simpletest.js
@@ -65,7 +65,7 @@ Drupal.behaviors.simpleTestSelectAll = {
   attach: function (context, settings) {
     $('td.simpletest-select-all').once('simpletest-select-all', function () {
       var testCheckboxes = settings.simpleTest['simpletest-test-group-' + $(this).attr('id')].testNames;
-      var groupCheckbox = $('<input type="checkbox" class="form-checkbox" id="' + $(this).attr('id') + '-select-all" />');
+      var groupCheckbox = $('<input type="checkbox" id="' + $(this).attr('id') + '-select-all" />');
 
       // Each time a single-test checkbox is checked or unchecked, make sure
       // that the associated group checkbox gets the right state too.
diff --git a/core/modules/system/system.admin.css b/core/modules/system/system.admin.css
index 0f3c0e5..149096f 100644
--- a/core/modules/system/system.admin.css
+++ b/core/modules/system/system.admin.css
@@ -254,7 +254,7 @@ table.screenshot {
   font-weight: normal;
   width: 10em;
 }
-.exposed-filters .form-select {
+.exposed-filters select {
   width: 14em;
 }
 /* Current filters */
diff --git a/core/modules/system/system.theme.css b/core/modules/system/system.theme.css
index d5f41e1..a6dc16f 100644
--- a/core/modules/system/system.theme.css
+++ b/core/modules/system/system.theme.css
@@ -111,15 +111,16 @@ input.form-radio {
   vertical-align: middle;
 }
 .marker,
-.form-required {
+.form-required-marker {
   color: #f00;
 }
-abbr.form-required, abbr.tabledrag-changed, abbr.ajax-changed {
+abbr.form-required-marker, abbr.tabledrag-changed, abbr.ajax-changed {
   border-bottom: none;
 }
-.form-item input.error,
-.form-item textarea.error,
-.form-item select.error {
+.form-error input[type=text],
+.form-error input[type=password],
+.form-error textarea,
+.form-error select {
   border: 2px solid red;
 }
 
diff --git a/core/modules/system/tests/form.test b/core/modules/system/tests/form.test
index fe5f922..7e94cfb 100644
--- a/core/modules/system/tests/form.test
+++ b/core/modules/system/tests/form.test
@@ -86,7 +86,7 @@ class FormsTestCase extends WebTestBase {
     $elements['file']['empty_values'] = $empty_strings;
 
     // Regular expression to find the expected marker on required elements.
-    $required_marker_preg = '@<label.*<abbr class="form-required" title="This field is required\.">\*</abbr></label>@';
+    $required_marker_preg = '@<label.*<abbr class="form-required-marker" title="This field is required\.">\*</abbr></label>@';
 
     // Go through all the elements and all the empty values for them.
     foreach ($elements as $type => $data) {
@@ -378,7 +378,7 @@ class FormsTestCase extends WebTestBase {
     $this->assertEqual($values->offset, 6.9);
 
     $this->drupalPost('form-test/range/invalid', array(), 'Submit');
-    $this->assertFieldByXPath('//input[@type="range" and contains(@class, "error")]', NULL, 'Range element has the error class.');
+    $this->assertFieldByXPath('//div[contains(@class, "form-error")]/input[@type="range"]', NULL, 'Range element has the error class.');
   }
 
   /**
@@ -894,16 +894,16 @@ class FormsElementsLabelsTestCase extends WebTestBase {
 
     // Exercise various defaults for textboxes and modifications to ensure
     // appropriate override and correct behavior.
-    $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-and-required"]/child::abbr[@class="form-required"]/parent::*/following-sibling::input[@id="edit-form-textfield-test-title-and-required"]');
+    $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-and-required"]/child::abbr[@class="form-required-marker"]/parent::*/following-sibling::input[@id="edit-form-textfield-test-title-and-required"]');
     $this->assertTrue(isset($elements[0]), t("Label precedes textfield, with required marker inside label."));
 
-    $elements = $this->xpath('//input[@id="edit-form-textfield-test-no-title-required"]/preceding-sibling::label[@for="edit-form-textfield-test-no-title-required"]/abbr[@class="form-required"]');
+    $elements = $this->xpath('//input[@id="edit-form-textfield-test-no-title-required"]/preceding-sibling::label[@for="edit-form-textfield-test-no-title-required"]/abbr[@class="form-required-marker"]');
     $this->assertTrue(isset($elements[0]), t("Label tag with required marker precedes required textfield with no title."));
 
     $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-invisible"]/preceding-sibling::label[@for="edit-form-textfield-test-title-invisible" and @class="element-invisible"]');
     $this->assertTrue(isset($elements[0]), t("Label preceding field and label class is element-invisible."));
 
-    $elements = $this->xpath('//input[@id="edit-form-textfield-test-title"]/preceding-sibling::abbr[@class="form-required"]');
+    $elements = $this->xpath('//input[@id="edit-form-textfield-test-title"]/preceding-sibling::abbr[@class="form-required-marker"]');
     $this->assertFalse(isset($elements[0]), t("No required marker on non-required field."));
 
     $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-after"]/following-sibling::label[@for="edit-form-textfield-test-title-after" and @class="option"]');
diff --git a/core/themes/bartik/css/style-rtl.css b/core/themes/bartik/css/style-rtl.css
index 90638eb..9256f1f 100644
--- a/core/themes/bartik/css/style-rtl.css
+++ b/core/themes/bartik/css/style-rtl.css
@@ -51,7 +51,8 @@ ul.tips {
 #name-and-slogan {
   margin: 0 15px 30px 0;
 }
-.region-header .form-text {
+.region-header input[type=text],
+.region-header input[type=password] {
   margin-left: 2px;
   margin-right: 0;
 }
@@ -147,7 +148,7 @@ ul.tips {
 
 /* ----------------- Buttons ------------------ */
 
-input.form-submit,
+input[type=submit],
 a.button {
   margin-right: 0;
   margin-left: 0.6em;
diff --git a/core/themes/bartik/css/style.css b/core/themes/bartik/css/style.css
index 7ab3d4e..b19d885 100644
--- a/core/themes/bartik/css/style.css
+++ b/core/themes/bartik/css/style.css
@@ -326,7 +326,8 @@ h1#site-name {
   list-style-image: none;
   padding: 0;
 }
-.region-header .form-text {
+.region-header input[type=text],
+.region-header input[type=password] {
   background: #fefefe;
   background: rgba(255, 255, 255, 0.7);
   border-color: #ccc;
@@ -334,13 +335,16 @@ h1#site-name {
   margin-right: 2px; /* LTR */
   width: 120px;
 }
-.region-header .form-text:hover,
-.region-header .form-text:focus,
-.region-header .form-text:active {
+.region-header input[type=text]:hover,
+.region-header input[type=text]:focus,
+.region-header input[type=text]:active,
+.region-header input[type=password]:hover,
+.region-header input[type=password]:focus,
+.region-header input[type=password]:active {
   background: #fff;
   background: rgba(255, 255, 255, 0.8);
 }
-.region-header .form-required {
+.region-header .form-required-marker {
   color: #eee;
   color: rgba(255, 255, 255, 0.7);
 }
@@ -415,7 +419,7 @@ h1#site-name {
   padding: 0;
   clear: both;
 }
-.region-header #block-user-login input.form-submit {
+.region-header #block-user-login input[type=submit] {
   border: 1px solid;
   border-color: #ccc;
   border-color: rgba(255, 255, 255, 0.5);
@@ -424,8 +428,8 @@ h1#site-name {
   margin: 4px 0;
   padding: 3px 8px;
 }
-.region-header #block-user-login input.form-submit:hover,
-.region-header #block-user-login input.form-submit:focus {
+.region-header #block-user-login input[type=submit]:hover,
+.region-header #block-user-login input[type=submit]:focus {
   background: #fff;
   background: rgba(255, 255, 255, 0.9);
 }
@@ -433,7 +437,7 @@ h1#site-name {
 .region-header #block-search-form {
   width: 208px;
 }
-.region-header #block-search-form .form-text {
+.region-header #block-search-form input[type=text] {
   width: 154px;
 }
 /* Language switcher block in region header. */
@@ -787,7 +791,8 @@ ul.links {
 #triptych .block ol {
   padding-left: 0;
 }
-#triptych #block-user-login .form-text {
+#triptych #block-user-login input[type=text],
+#triptych #block-user-login input[type=password] {
   width: 185px;
 }
 #triptych #block-user-online p {
@@ -1058,7 +1063,7 @@ div.password-confirm {
 
 /* ---------------- Buttons    ---------------- */
 
-input.form-submit,
+input[type=submit],
 a.button {
   background: #fff url(../images/buttons.png) 0 0 repeat-x;
   border: 1px solid #e4e4e4;
@@ -1184,22 +1189,23 @@ textarea {
 textarea {
   line-height: 1.5;
 }
-textarea.form-textarea,
-select.form-select {
+textarea,
+select {
   padding: 4px;
 }
-input.form-text,
-input.form-tel,
-input.form-email,
-input.form-url,
-input.form-search,
-input.form-number,
-textarea.form-textarea,
-select.form-select {
+input[type=text],
+input[type=password],
+input[type=tel],
+input[type=email],
+input[type=url],
+input[type=search],
+input[type=number],
+textarea,
+select {
   border: 1px solid #ccc;
 }
-input.form-submit:hover,
-input.form-submit:focus {
+input[type=submit]:hover,
+input[type=submit]:focus {
   background: #dedede;
 }
 .password-suggestions ul li {
@@ -1278,7 +1284,7 @@ input.form-button-disabled:active,
   width: 120px;
 }
 .comment-form input,
-.comment-form .form-select {
+.comment-form select {
   margin: 0;
   -moz-border-radius: 4px;
   border-radius: 4px;
@@ -1289,7 +1295,7 @@ input.form-button-disabled:active,
 .comment-form .form-item,
 .comment-form .form-radios,
 .comment-form .form-type-checkbox,
-.comment-form .form-select {
+.comment-form select {
   margin-bottom: 10px;
   overflow: hidden;
 }
@@ -1302,16 +1308,16 @@ input.form-button-disabled:active,
   float: none;
   margin-top: 0;
 }
-.comment-form input.form-file {
+.comment-form input[type=file] {
   width: auto;
 }
-.no-sidebars .comment-form .form-text {
+.no-sidebars .comment-form input[type=text] {
   width: 800px;
 }
-.one-sidebar .comment-form .form-text {
+.one-sidebar .comment-form input[type=text] {
   width: 500px;
 }
-.two-sidebars .comment-form .form-text {
+.two-sidebars .comment-form input[type=text] {
   width: 320px;
 }
 .comment-form .form-item .description {
@@ -1322,7 +1328,7 @@ input.form-button-disabled:active,
 #content h2.comment-form {
   margin-bottom: 0.5em;
 }
-.comment-form .form-textarea {
+.comment-form textarea {
   -moz-border-radius-topleft: 4px;
   -moz-border-radius-topright: 4px;
   border-top-left-radius: 4px;
@@ -1337,7 +1343,7 @@ input.form-button-disabled:active,
   width: auto;
   float: none;
 }
-.filter-wrapper .form-select {
+.filter-wrapper select {
   min-width: 120px;
 }
 .comment-form fieldset.filter-wrapper .tips {
@@ -1394,8 +1400,8 @@ div.vertical-tabs .vertical-tabs-panes fieldset.vertical-tabs-pane {
   margin-right: 5px;
   width: 9em;
 }
-#search-block-form input.form-submit,
-#search-form input.form-submit {
+#search-block-form input[type=submit],
+#search-form input[type=submit] {
   margin-left: 0;
   margin-right: 0;
   height: 25px;
@@ -1407,10 +1413,10 @@ div.vertical-tabs .vertical-tabs-panes fieldset.vertical-tabs-pane {
   background: url(../images/search-button.png) no-repeat center top;
   overflow: hidden;
 }
-#search-block-form input.form-submit:hover,
-#search-block-form input.form-submit:focus,
-#search-form input.form-submit:hover,
-#search-form input.form-submit:focus {
+#search-block-form input[type=submit]:hover,
+#search-block-form input[type=submit]:focus,
+#search-form input[type=submit]:hover,
+#search-form input[type=submit]:focus {
   background-position: center bottom;
 }
 #search-form .form-item-keys label {
diff --git a/core/themes/seven/reset.css b/core/themes/seven/reset.css
index de53f28..31dcdd1 100644
--- a/core/themes/seven/reset.css
+++ b/core/themes/seven/reset.css
@@ -103,7 +103,7 @@ tr.even .form-item,
 .form-checkboxes .form-item,
 .form-radios .form-item,
 .marker,
-.form-required,
+.form-required-marker,
 .more-link,
 .more-help-link,
 .item-list .pager,
diff --git a/core/themes/seven/style-rtl.css b/core/themes/seven/style-rtl.css
index a41d325..595f8c2 100644
--- a/core/themes/seven/style-rtl.css
+++ b/core/themes/seven/style-rtl.css
@@ -43,7 +43,7 @@ ol {
 #branding div.block form div.form-item {
   float: right;
 }
-#branding div.block form input.form-text {
+#branding div.block form input[type=text] {
   margin-left: 10px;
   margin-right: 0;
 }
@@ -161,7 +161,7 @@ body div.form-type-checkbox div.description {
   margin-left: 0;
   margin-right: 1.5em;
 }
-input.form-submit,
+input[type=submit],
 a.button {
   margin-left: 1em;
   margin-right: 0;
diff --git a/core/themes/seven/style.css b/core/themes/seven/style.css
index a3d6773..1e83717 100644
--- a/core/themes/seven/style.css
+++ b/core/themes/seven/style.css
@@ -203,11 +203,11 @@ pre {
   margin: 0;
   padding: 0;
 }
-#branding div.block form input.form-text {
+#branding div.block form input[type=text] {
   width: 140px;
   margin-right: 10px; /* LTR */
 }
-#branding div.block form input.form-submit {
+#branding div.block form input[type=submit] {
   text-align: center;
   width: 80px;
 }
@@ -606,15 +606,16 @@ div.teaser-checkbox .form-item,
   vertical-align: middle;
 }
 .form-disabled input.form-autocomplete,
-.form-disabled input.form-text,
-.form-disabled input.form-tel,
-.form-disabled input.form-email,
-.form-disabled input.form-url,
-.form-disabled input.form-search,
-.form-disabled input.form-number,
-.form-disabled input.form-file,
-.form-disabled textarea.form-textarea,
-.form-disabled select.form-select {
+.form-disabled input[type=text],
+.form-disabled input[type=password],
+.form-disabled input[type=tel],
+.form-disabled input[type=email],
+.form-disabled input[type=url],
+.form-disabled input[type=search],
+.form-disabled input[type=number],
+.form-disabled input[type=file],
+.form-disabled textarea,
+.form-disabled select {
   background-color: #eee;
   color: #777;
 }
@@ -648,7 +649,7 @@ body div.form-type-radio div.description,
 body div.form-type-checkbox div.description {
   margin-left: 1.5em; /* LTR */
 }
-input.form-submit,
+input[type=submit],
 a.button {
   cursor: pointer;
   padding: 4px 17px;
@@ -683,7 +684,7 @@ a.button:active {
   background: url(images/buttons.png) 0 -40px repeat-x;
   color: #133B54;
 }
-input.form-submit:active {
+input[type=submit]:active {
   background: #666;
   color: #fff;
   border-color: #555;
@@ -697,15 +698,16 @@ input.form-button-disabled:active {
   color: #999;
 }
 input.form-autocomplete,
-input.form-text,
-input.form-tel,
-input.form-email,
-input.form-url,
-input.form-search,
-input.form-number,
-input.form-file,
-textarea.form-textarea,
-select.form-select {
+input[type=text],
+input[type=password],
+input[type=tel],
+input[type=email],
+input[type=url],
+input[type=search],
+input[type=number],
+input[type=file],
+textarea,
+select {
   padding: 2px;
   border: 1px solid #ccc;
   border-top-color: #999;
@@ -715,15 +717,16 @@ select.form-select {
   -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
   transition: border linear 0.2s, box-shadow linear 0.2s;
 }
-input.form-text:focus,
-input.form-tel:focus,
-input.form-email:focus,
-input.form-url:focus,
-input.form-search:focus,
-input.form-number:focus,
-input.form-file:focus,
-textarea.form-textarea:focus,
-select.form-select:focus {
+input[type=text]:focus,
+input[type=password]:focus,
+input[type=tel]:focus,
+input[type=email]:focus,
+input[type=url]:focus,
+input[type=search]:focus,
+input[type=number]:focus,
+input[type=file]:focus,
+textarea:focus,
+select:focus {
   color: #000;
   border-color: rgba(0, 116, 189, 0.8);
   -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(220, 220, 220, 0.4);
@@ -860,7 +863,7 @@ body.in-maintenance div.form-item:after {
   display: none;
   clear: none;
 }
-body.in-maintenance .form-submit {
+body.in-maintenance input[type=submit] {
   display: block;
 }
 body.in-maintenance #logo {
@@ -970,7 +973,7 @@ div.add-or-remove-shortcuts {
 #field-display-overview .field-formatter-settings-edit-form .form-item {
   margin: 10px 0;
 }
-#field-display-overview .field-formatter-settings-edit-form .form-submit {
+#field-display-overview .field-formatter-settings-edit-form input[type=submit] {
   margin-bottom: 0;
 }
 
diff --git a/core/update.php b/core/update.php
index 9797833..0b31db5 100644
--- a/core/update.php
+++ b/core/update.php
@@ -267,7 +267,7 @@ function update_info_page() {
   $output .= "</ol>\n";
   $output .= "<p>When you have performed the steps above, you may proceed.</p>\n";
   $form_action = check_url(drupal_current_script_url(array('op' => 'selection', 'token' => $token)));
-  $output .= '<form method="post" action="' . $form_action . '"><p><input type="submit" value="Continue" class="form-submit" /></p></form>';
+  $output .= '<form method="post" action="' . $form_action . '"><p><input type="submit" value="Continue" /></p></form>';
   $output .= "\n";
   return $output;
 }
