diff --git a/core/lib/Drupal/Core/Render/Element/File.php b/core/lib/Drupal/Core/Render/Element/File.php
index 5f72c8d..c8b3c7f 100644
--- a/core/lib/Drupal/Core/Render/Element/File.php
+++ b/core/lib/Drupal/Core/Render/Element/File.php
@@ -65,7 +65,7 @@ public static function processFile(&$element, FormStateInterface $form_state, &$
   public static function preRenderFile($element) {
     $element['#attributes']['type'] = 'file';
     Element::setAttributes($element, array('id', 'name', 'size'));
-    static::setAttributes($element, array('form-file'));
+    static::setAttributes($element, array('js-form-file', 'form-file'));
 
     return $element;
   }
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index 2578844..782ae70 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -27,8 +27,8 @@ function template_preprocess_file_widget(&$variables) {
     $element['file_' . $file->id()]['filename']['#suffix'] = ' <span class="file-size">(' . format_size($file->getSize()) . ')</span> ';
   }
   $variables['element'] = $element;
-  // The "form-managed-file" class is required for proper Ajax functionality.
-  $variables['attributes'] = array('class' => array('file-widget', 'form-managed-file', 'clearfix'));
+  // The "js-form-managed-file" class is required for proper Ajax functionality.
+  $variables['attributes'] = array('class' => array('file-widget', 'js-form-managed-file', 'form-managed-file', 'clearfix'));
 }
 
 /**
diff --git a/core/modules/file/file.js b/core/modules/file/file.js
index b704542..6cade5e 100644
--- a/core/modules/file/file.js
+++ b/core/modules/file/file.js
@@ -68,12 +68,12 @@
     attach: function (context) {
       var $context = $(context);
       $context.find('.form-submit').on('mousedown', Drupal.file.disableFields);
-      $context.find('.form-managed-file .form-submit').on('mousedown', Drupal.file.progressBar);
+      $context.find('.js-form-managed-file .form-submit').on('mousedown', Drupal.file.progressBar);
     },
     detach: function (context) {
       var $context = $(context);
       $context.find('.form-submit').off('mousedown', Drupal.file.disableFields);
-      $context.find('.form-managed-file .form-submit').off('mousedown', Drupal.file.progressBar);
+      $context.find('.js-form-managed-file .form-submit').off('mousedown', Drupal.file.progressBar);
     }
   };
 
@@ -82,10 +82,10 @@
    */
   Drupal.behaviors.filePreviewLinks = {
     attach: function (context) {
-      $(context).find('div.form-managed-file .file a, .file-widget .file a').on('click', Drupal.file.openInNewWindow);
+      $(context).find('div.js-form-managed-file .file a, .file-widget .file a').on('click', Drupal.file.openInNewWindow);
     },
     detach: function (context) {
-      $(context).find('div.form-managed-file .file a, .file-widget .file a').off('click', Drupal.file.openInNewWindow);
+      $(context).find('div.js-form-managed-file .file a, .file-widget .file a').off('click', Drupal.file.openInNewWindow);
     }
   };
 
@@ -117,7 +117,7 @@
             '%filename': this.value.replace('C:\\fakepath\\', ''),
             '%extensions': extensionPattern.replace(/\|/g, ', ')
           });
-          $(this).closest('div.form-managed-file').prepend('<div class="messages messages--error file-upload-js-error" aria-live="polite">' + error + '</div>');
+          $(this).closest('div.js-form-managed-file').prepend('<div class="messages messages--error file-upload-js-error" aria-live="polite">' + error + '</div>');
           this.value = '';
           // Cancel all other change event handlers.
           event.stopImmediatePropagation();
@@ -128,7 +128,7 @@
      * Trigger the upload_button mouse event to auto-upload as a managed file.
      */
     triggerUploadButton: function (event) {
-      $(event.target).closest('.form-managed-file').find('.form-submit').trigger('mousedown');
+      $(event.target).closest('.js-form-managed-file').find('.form-submit').trigger('mousedown');
     },
     /**
      * Prevent file uploads when using buttons not intended to upload.
@@ -143,8 +143,8 @@
 
       // Check if we're working with an "Upload" button.
       var $enabledFields = [];
-      if ($clickedButton.closest('div.form-managed-file').length > 0) {
-        $enabledFields = $clickedButton.closest('div.form-managed-file').find('input.form-file');
+      if ($clickedButton.closest('div.js-form-managed-file').length > 0) {
+        $enabledFields = $clickedButton.closest('div.js-form-managed-file').find('input.js-form-file');
       }
 
       // Temporarily disable upload fields other than the one we're currently
@@ -155,7 +155,7 @@
       // 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.js-form-managed-file input.js-form-file').not($enabledFields).not(':disabled');
       $fieldsToTemporarilyDisable.prop('disabled', true);
       setTimeout(function () {
         $fieldsToTemporarilyDisable.prop('disabled', false);
@@ -166,7 +166,7 @@
      */
     progressBar: function (event) {
       var $clickedButton = $(this);
-      var $progressId = $clickedButton.closest('div.form-managed-file').find('input.file-progress');
+      var $progressId = $clickedButton.closest('div.js-form-managed-file').find('input.file-progress');
       if ($progressId.length) {
         var originalName = $progressId.attr('name');
 
@@ -180,7 +180,7 @@
       }
       // Show the progress bar if the upload takes longer than half a second.
       setTimeout(function () {
-        $clickedButton.closest('div.form-managed-file').find('div.ajax-progress-bar').slideDown();
+        $clickedButton.closest('div.js-form-managed-file').find('div.ajax-progress-bar').slideDown();
       }, 500);
     },
     /**
diff --git a/core/modules/file/templates/file-managed-file.html.twig b/core/modules/file/templates/file-managed-file.html.twig
index 7a87511..fdd2b3c 100644
--- a/core/modules/file/templates/file-managed-file.html.twig
+++ b/core/modules/file/templates/file-managed-file.html.twig
@@ -12,6 +12,11 @@
  * @ingroup themeable
  */
 #}
-<div{{ attributes.addClass('form-managed-file') }}>
+{%
+  set classes = [
+    'js-form-managed-file',
+  ]
+%}
+<div{{ attributes.addClass(classes) }}>
   {{ element }}
 </div>
diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc
index dbdbcc8..49c6534 100644
--- a/core/modules/image/image.field.inc
+++ b/core/modules/image/image.field.inc
@@ -21,7 +21,7 @@
 function template_preprocess_image_widget(&$variables) {
   $element = $variables['element'];
 
-  $variables['attributes'] = array('class' => array('image-widget', 'form-managed-file', 'clearfix'));
+  $variables['attributes'] = array('class' => array('image-widget', 'js-form-managed-file', 'form-managed-file', 'clearfix'));
 
   if (!empty($element['fids']['#value'])) {
     $file = reset($element['#files']);
diff --git a/core/modules/image/src/Tests/ImageFieldDisplayTest.php b/core/modules/image/src/Tests/ImageFieldDisplayTest.php
index 2679328..6e13799 100644
--- a/core/modules/image/src/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/src/Tests/ImageFieldDisplayTest.php
@@ -317,8 +317,8 @@ function testImageFieldSettings() {
       'files[' . $field_name . '_2][]' => drupal_realpath($test_image->uri),
     );
     $this->drupalPostAjaxForm(NULL, $edit, $field_name . '_2_upload_button');
-    $this->assertNoRaw('<input multiple type="file" id="edit-' . strtr($field_name, '_', '-') . '-2-upload" name="files[' . $field_name . '_2][]" size="22" class="form-file">');
-    $this->assertRaw('<input multiple type="file" id="edit-' . strtr($field_name, '_', '-') . '-3-upload" name="files[' . $field_name . '_3][]" size="22" class="form-file">');
+    $this->assertNoRaw('<input multiple type="file" id="edit-' . strtr($field_name, '_', '-') . '-2-upload" name="files[' . $field_name . '_2][]" size="22" class="js-form-file form-file">');
+    $this->assertRaw('<input multiple type="file" id="edit-' . strtr($field_name, '_', '-') . '-3-upload" name="files[' . $field_name . '_3][]" size="22" class="js-form-file form-file">');
   }
 
   /**
diff --git a/core/themes/classy/templates/content-edit/file-managed-file.html.twig b/core/themes/classy/templates/content-edit/file-managed-file.html.twig
index 43739be..f639237 100644
--- a/core/themes/classy/templates/content-edit/file-managed-file.html.twig
+++ b/core/themes/classy/templates/content-edit/file-managed-file.html.twig
@@ -10,6 +10,12 @@
  * @see template_preprocess_file_managed_file()
  */
 #}
-<div{{ attributes.addClass('form-managed-file') }}>
+{%
+  set classes = [
+    'js-form-managed-file',
+    'form-managed-file',
+  ]
+%}
+<div{{ attributes.addClass(classes) }}>
   {{ element }}
 </div>
