diff --git a/core/misc/collapse.js b/core/misc/collapse.js
index 55402c35b3d324cfe76c5fdc4fc90581cf989a79..c26ab55e9727ac1489ee8cde0338a1dfe2921cea 100644
--- a/core/misc/collapse.js
+++ b/core/misc/collapse.js
@@ -5,15 +5,9 @@
 /**
  * The collapsible details object represents a single collapsible details element.
  */
-function CollapsibleDetails(node, settings) {
+function CollapsibleDetails (node) {
   this.$node = $(node);
   this.$node.data('details', this);
-  this.settings = $.extend({
-      duration:'fast',
-      easing:'linear'
-    },
-    settings
-  );
   // Expand details if there are errors inside, or if it contains an
   // element that is targeted by the URI fragment identifier.
   var anchor = location.hash && location.hash !== '#' ? ', ' + location.hash : '';
@@ -40,10 +34,6 @@ $.extend(CollapsibleDetails, {
  * Extend CollapsibleDetails prototype.
  */
 $.extend(CollapsibleDetails.prototype, {
-  /**
-   * Flag preventing multiple simultaneous animations.
-   */
-  animating: false,
   /**
    * Initialize and setup summary events and markup.
    */
@@ -77,8 +67,8 @@ $.extend(CollapsibleDetails.prototype, {
    * Handle legend clicks
    */
   onLegendClick: function (e) {
-    e.preventDefault();
     this.toggle();
+    e.preventDefault();
   },
   /**
    * Update summary
@@ -91,59 +81,27 @@ $.extend(CollapsibleDetails.prototype, {
    * Toggle the visibility of a details element using smooth animations.
    */
   toggle: function () {
-    // Don't animate multiple times.
-    if (this.animating) {
-      return;
-    }
-    if (!this.$node.attr('open')) {
-      var $content = this.$node.find('> .details-wrapper').hide();
-      this.$node
-        .trigger({ type:'collapsed', value:false })
-        .find('> summary span.details-summary-prefix').html(Drupal.t('Hide'));
-      $content.slideDown(
-        $.extend(this.settings, {
-          complete:$.proxy(this.onCompleteSlideDown, this)
-        })
-      );
+    var isOpen = !!this.$node.attr('open');
+    var $summaryPrefix = this.$node.find('> summary span.details-summary-prefix');
+    if (isOpen) {
+      $summaryPrefix.html(Drupal.t('Show'));
     }
     else {
-      this.$node.trigger({ type:'collapsed', value:true });
-      this.$node.find('> .details-wrapper').slideUp(
-        $.extend(this.settings, {
-          complete:$.proxy(this.onCompleteSlideUp, this)
-        })
-      );
+      $summaryPrefix.html(Drupal.t('Hide'));
     }
-  },
-  /**
-   * Completed opening details element.
-   */
-  onCompleteSlideDown: function () {
-    this.$node.attr('open', true);
-    this.$node.trigger('completeSlideDown');
-    this.animating = false;
-  },
-  /**
-   * Completed closing details element.
-   */
-  onCompleteSlideUp: function () {
-    this.$node.attr('open', false);
-    this.$node
-      .find('> summary span.details-summary-prefix').html(Drupal.t('Show'));
-    this.$node.trigger('completeSlideUp');
-    this.animating = false;
+    this.$node.attr('open', !isOpen);
   }
 });
 
 Drupal.behaviors.collapse = {
-  attach: function (context, settings) {
+  attach: function (context) {
     if (Modernizr.details) {
       return;
     }
     var $collapsibleDetails = $(context).find('details').once('collapse');
     if ($collapsibleDetails.length) {
       for (var i = 0; i < $collapsibleDetails.length; i++) {
-        CollapsibleDetails.instances.push(new CollapsibleDetails($collapsibleDetails[i], settings.collapsibleDetails));
+        CollapsibleDetails.instances.push(new CollapsibleDetails($collapsibleDetails[i]));
       }
     }
   }
diff --git a/core/misc/dialog.ajax.js b/core/misc/dialog.ajax.js
index 072971dd462dc83a9f8b653e596b670c967b441b..791e6b124f89c16d7a7bde53e92fbe61e29930c1 100644
--- a/core/misc/dialog.ajax.js
+++ b/core/misc/dialog.ajax.js
@@ -24,9 +24,10 @@
       if ($dialog.length) {
         // Remove and replace the dialog buttons with those from the new form.
         if ($dialog.dialog('option', 'drupalAutoButtons')) {
-          var buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
-          $dialog.dialog('option', 'buttons', buttons);
+          // Trigger an event to detect/sync changes to buttons.
+          $dialog.trigger('dialogButtonsChange');
         }
+
         // Refocus the first input element after validation errors.
         if ($context.find('form').length) {
           $context.find('input:first').focus();
@@ -61,7 +62,7 @@
           'text': $originalButton.html() || $originalButton.attr('value'),
           'class': $originalButton.attr('class'),
           'click': function (e) {
-            $originalButton.trigger('click');
+            $originalButton.trigger('mousedown').trigger('click').trigger('mouseup');
             e.preventDefault();
           }
         });
@@ -98,6 +99,12 @@
       response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
     }
 
+    // Bind dialogButtonsChange
+    $dialog.on('dialogButtonsChange', function() {
+      var buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
+      $dialog.dialog('option', 'buttons', buttons);
+    });
+
     // Open the dialog itself.
     response.dialogOptions = response.dialogOptions || {};
     var dialog = Drupal.dialog($dialog, response.dialogOptions);
@@ -107,6 +114,9 @@
     else {
       dialog.show();
     }
+
+    // Add the standard Drupal class for buttons for style consistency.
+    $dialog.parent().find('.ui-dialog-buttonset').addClass('form-actions');
   };
 
   /**
@@ -122,6 +132,9 @@
         $dialog.remove();
       }
     }
+
+    // Unbind dialogButtonsChange
+    $dialog.off('dialogButtonsChange');
   };
 
   /**
diff --git a/core/misc/dialog.js b/core/misc/dialog.js
index ab4c5a35eb0bc80d5faef01de102a835f2e96261..2bb3a3293ecca709b3b411345437a13fcbc157d1 100644
--- a/core/misc/dialog.js
+++ b/core/misc/dialog.js
@@ -10,9 +10,6 @@
 
 drupalSettings.dialog = {
   autoOpen: true,
-  // This option will turn off resizable and draggable.
-  autoResize: true,
-  maxHeight: '95%',
   dialogClass: '',
   // When using this API directly (when generating dialogs on the client side),
   // you may want to override this method and do
@@ -32,14 +29,6 @@ Drupal.dialog = function (element, options) {
     // Trigger a global event to allow scripts to bind events to the dialog.
     $(window).trigger('dialog:beforecreate', [dialog, $element, settings]);
     $element.dialog(settings);
-    if (settings.autoResize === true || settings.autoResize === 'true') {
-      $element
-        .dialog('option', { resizable: false, draggable: false })
-        .dialog('widget').css('position', 'fixed');
-      $(window)
-        .on('resize.dialogResize scroll.dialogResize', settings, autoResize)
-        .trigger('resize.dialogResize');
-    }
     dialog.open = true;
     $(window).trigger('dialog:aftercreate', [dialog, $element, settings]);
   }
@@ -49,44 +38,11 @@ Drupal.dialog = function (element, options) {
     $element.dialog('close');
     dialog.returnValue = value;
     dialog.open = false;
-    $(window).off('.dialogResize');
     $(window).trigger('dialog:afterclose', [dialog, $element]);
   }
 
-  /**
-   * Resets the current options for positioning.
-   *
-   * This is used as a window resize and scroll callback to reposition the
-   * jQuery UI dialog. Although not a built-in jQuery UI option, this can
-   * be disabled by setting autoResize: false in the options array when creating
-   * a new Drupal.dialog().
-   */
-  function resetPosition (event) {
-    var positionOptions = ['width', 'height', 'minWidth', 'minHeight', 'maxHeight', 'maxWidth', 'position'];
-    var windowHeight = $(window).height();
-    var adjustedOptions = {};
-    var option, optionValue, adjustedValue;
-    for (var n = 0; n < positionOptions.length; n++) {
-      option = positionOptions[n];
-      optionValue = event.data[option];
-      if (optionValue) {
-        // jQuery UI does not support percentages on heights, convert to pixels.
-        if (typeof optionValue === 'string' && /%$/.test(optionValue) && /height/i.test(option)) {
-          adjustedValue = parseInt(0.01 * parseInt(optionValue, 10) * windowHeight, 10);
-          // Don't force the dialog to be bigger vertically than needed.
-          if (option === 'height' && $element.parent().outerHeight() < adjustedValue) {
-            adjustedValue = 'auto';
-          }
-          adjustedOptions[option] = adjustedValue;
-        }
-      }
-    }
-    $element.dialog('option', adjustedOptions);
-  }
-
   var undef;
   var $element = $(element);
-  var autoResize = Drupal.debounce(resetPosition, 50);
   var dialog = {
     open: false,
     returnValue: undef,
diff --git a/core/misc/dialog.position.js b/core/misc/dialog.position.js
new file mode 100644
index 0000000000000000000000000000000000000000..ec4fb3104aa62e18b90a7899ec06c5aeeed59574
--- /dev/null
+++ b/core/misc/dialog.position.js
@@ -0,0 +1,81 @@
+(function ($, Drupal, drupalSettings, debounce, displace) {
+
+  "use strict";
+
+  // autoResize option will turn off resizable and draggable.
+  drupalSettings.dialog = $.extend({ autoResize: true, maxHeight: '95%' }, drupalSettings.dialog);
+
+  /**
+   * Resets the current options for positioning.
+   *
+   * This is used as a window resize and scroll callback to reposition the
+   * jQuery UI dialog. Although not a built-in jQuery UI option, this can
+   * be disabled by setting autoResize: false in the options array when creating
+   * a new Drupal.dialog().
+   */
+  function resetSize (event) {
+    var positionOptions = ['width', 'height', 'minWidth', 'minHeight', 'maxHeight', 'maxWidth', 'position'];
+    var adjustedOptions = {};
+    var windowHeight = $(window).height();
+    var option, optionValue, adjustedValue;
+    for (var n = 0; n < positionOptions.length; n++) {
+      option = positionOptions[n];
+      optionValue = event.data.settings[option];
+      if (optionValue) {
+        // jQuery UI does not support percentages on heights, convert to pixels.
+        if (typeof optionValue === 'string' && /%$/.test(optionValue) && /height/i.test(option)) {
+          // Take offsets in account.
+          windowHeight -= displace.offsets.top + displace.offsets.bottom;
+          adjustedValue = parseInt(0.01 * parseInt(optionValue, 10) * windowHeight, 10);
+          // Don't force the dialog to be bigger vertically than needed.
+          if (option === 'height' && event.data.$element.parent().outerHeight() < adjustedValue) {
+            adjustedValue = 'auto';
+          }
+          adjustedOptions[option] = adjustedValue;
+        }
+      }
+    }
+    // Offset the dialog center to be at the center of Drupal.displace.offsets.
+    adjustedOptions = resetPosition(adjustedOptions);
+    event.data.$element
+      .dialog('option', adjustedOptions)
+      .trigger('dialogContentResize');
+  }
+
+  /**
+   * Position the dialog's center at the center of displace.offsets boundaries.
+   */
+  function resetPosition (options) {
+    var offsets = displace.offsets;
+    var left = offsets.left - offsets.right;
+    var top = offsets.top - offsets.bottom;
+
+    var leftString = (left > 0 ? '+' : '-') + Math.abs(Math.round(left/2)) + 'px';
+    var topString = (top > 0 ? '+' : '-') + Math.abs(Math.round(top/2)) + 'px';
+    options.position = {
+      my: 'center' + (left !== 0 ? leftString : '') + ' center' + (top !== 0 ? topString : '')
+    };
+    return options;
+  }
+
+  $(window).on({
+    'dialog:aftercreate': function (event, dialog, $element, settings) {
+      var autoResize = debounce(resetSize, 20);
+      var eventData = { settings: settings, $element: $element };
+      if (settings.autoResize === true || settings.autoResize === 'true') {
+        $element
+          .dialog('option', { resizable: false, draggable: false })
+          .dialog('widget').css('position', 'fixed');
+        $(window)
+          .on('resize.dialogResize scroll.dialogResize', eventData, autoResize)
+          .trigger('resize.dialogResize');
+        $(document).on('drupalViewportOffsetChange', eventData, autoResize);
+      }
+    },
+    'dialog:beforeclose': function (event, dialog, $element) {
+      $(window).off('.dialogResize');
+    }
+  });
+
+// @todo remove window.parent once overlay is removed from core.
+})(jQuery, Drupal, drupalSettings, Drupal.debounce,  window.parent.Drupal.displace);
diff --git a/core/misc/dialog.theme.css b/core/misc/dialog.theme.css
index 360e6ae3d4afd189e78ca8b4704294617434179c..581c03bf17ac19efe9a95503909323e65f96808d 100644
--- a/core/misc/dialog.theme.css
+++ b/core/misc/dialog.theme.css
@@ -38,43 +38,6 @@
   padding: 0;
 }
 
-.ui-dialog .ui-dialog-buttonpane button {
-  background: #fefefe;
-  background-image: -webkit-linear-gradient(top, #fefefe, #e0e0e0);
-  background-image: -moz-linear-gradient(top, #fefefe, #e0e0e0);
-  background-image: -o-linear-gradient(top, #fefefe, #e0e0e0);
-  background-image: linear-gradient(to bottom, #fefefe, #e0e0e0);
-  border: 1px solid #c8c8c8;
-  border-radius: 3px;
-  text-decoration: none;
-  padding: 6px 17px 6px 17px;
-}
-.ui-dialog .ui-dialog-buttonpane button:hover,
-.ui-dialog .ui-dialog-buttonpane button:focus {
-  background: #fefefe;
-  background-image: -webkit-linear-gradient(top, #fefefe, #eaeaea);
-  background-image: -moz-linear-gradient(top, #fefefe, #eaeaea);
-  background-image: -o-linear-gradient(top, #fefefe, #eaeaea);
-  background-image: linear-gradient(to bottom, #fefefe, #eaeaea);
-  -webkit-box-shadow: 1px 1px 3px rgba(50, 50, 50, 0.1);
-  box-shadow: 1px 1px 3px rgba(50, 50, 50, 0.1);
-  color: #2e2e2e;
-  text-decoration: none;
-}
-.ui-dialog .ui-dialog-buttonpane button:active {
-  border: 1px solid #c8c8c8;
-  background: #fefefe;
-  background-image: -webkit-linear-gradient(top, #eaeaea, #fefefe);
-  background-image: -moz-linear-gradient(top, #eaeaea, #fefefe);
-  background-image: -o-linear-gradient(top, #eaeaea, #fefefe);
-  background-image: linear-gradient(to bottom, #eaeaea, #fefefe);
-  -webkit-box-shadow: 1px 1px 3px rgba(50, 50, 50, 0.1);
-  box-shadow: 1px 1px 3px rgba(50, 50, 50, 0.1);
-  color: #2e2e2e;
-  text-decoration: none;
-  text-shadow: none;
-}
-
 /* Form action buttons are moved in dialogs. Remove empty space. */
 .ui-dialog .ui-dialog-content .form-actions {
   padding: 0;
diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
index 97797333e3c20a1d60cc40c00bf9589ca41f9eca..014647b3398b10e0fb5864434eef2a709133a0f3 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php
@@ -419,7 +419,7 @@ public function buildOptionsForm(&$form, &$form_state) {
       '#options' => $formatters,
       '#default_value' => $this->options['type'],
       '#ajax' => array(
-        'path' => views_ui_build_form_url($form_state),
+        'path' => views_ui_build_form_path($form_state),
       ),
       '#submit' => array(array($this, 'submitTemporaryForm')),
       '#executes_submit_callback' => TRUE,
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index acdf63953f269dc5b302f980f4ca25ed9a40d8a2..80b02f87bcba6870dce2cbb86dceeff889e992d8 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -1079,6 +1079,7 @@ function system_library_info() {
     'version' => \Drupal::VERSION,
     'js' => array(
       'core/misc/dialog.js' => array('group' => JS_LIBRARY),
+      'core/misc/dialog.position.js' => array('group' => JS_LIBRARY),
     ),
     'css' => array(
       'core/misc/dialog.theme.css' => array('weight' => 1),
@@ -1086,9 +1087,10 @@ function system_library_info() {
     'dependencies' => array(
       array('system', 'jquery'),
       array('system', 'drupal'),
-      array('system', 'drupal.debounce'),
       array('system', 'drupalSettings'),
-      array('system', 'jquery.ui.dialog')
+      array('system', 'drupal.debounce'),
+      array('system', 'drupal.displace'),
+      array('system', 'jquery.ui.dialog'),
     ),
   );
 
diff --git a/core/modules/views/includes/ajax.inc b/core/modules/views/includes/ajax.inc
index 788d1c1da2ff309a56db5b959631bde9aed9cc64..a2832a755d62670f5c77663a5f299f37cdbffb19 100644
--- a/core/modules/views/includes/ajax.inc
+++ b/core/modules/views/includes/ajax.inc
@@ -6,7 +6,7 @@
  */
 
 use Drupal\views\Ajax\HighlightCommand;
-use Drupal\views\Ajax\SetFormCommand;
+use Drupal\Core\Ajax\OpenModalDialogCommand;
 use Drupal\Core\Ajax\AjaxResponse;
 
 /**
@@ -52,10 +52,12 @@ function views_ajax_form_wrapper($form_id, &$form_state) {
     $display .= $output;
 
     $title = empty($form_state['title']) ? '' : $form_state['title'];
+    $options = array(
+      'dialogClass' => 'views-ui-dialog',
+      'width' => '50%',
+    );
 
-    $url = empty($form_state['url']) ? url(current_path(), array('absolute' => TRUE)) : $form_state['url'];
-
-    $response->addCommand(new SetFormCommand($display, $title, $url));
+    $response->addCommand(new OpenModalDialogCommand($title, $display, $options));
 
     if (!empty($form_state['#section'])) {
       $response->addCommand(new HighlightCommand('.' . drupal_clean_css_identifier($form_state['#section'])));
diff --git a/core/modules/views/js/jquery.ui.dialog.patch.js b/core/modules/views/js/jquery.ui.dialog.patch.js
deleted file mode 100644
index 1fb9b0b397e7baf1bf7fd6b2d0e2795278c4124f..0000000000000000000000000000000000000000
--- a/core/modules/views/js/jquery.ui.dialog.patch.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * This is part of a patch to address a jQueryUI bug.  The bug is responsible
- * for the inability to scroll a page when a modal dialog is active. If the content
- * of the dialog extends beyond the bottom of the viewport, the user is only able
- * to scroll with a mousewheel or up/down keyboard keys.
- *
- * @see http://bugs.jqueryui.com/ticket/4671
- * @see https://bugs.webkit.org/show_bug.cgi?id=19033
- * @see views_ui.module
- * @see js/jquery.ui.dialog.min.js
- *
- * This javascript patch overwrites the $.ui.dialog.overlay.events object to remove
- * the mousedown, mouseup and click events from the list of events that are bound
- * in $.ui.dialog.overlay.create
- *
- * The original code for this object:
- * $.ui.dialog.overlay.events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
- *  function(event) { return event + '.dialog-overlay'; }).join(' '),
- *
- */
-
-(function ($, undefined) {
-
-  "use strict";
-
-  if ($.ui && $.ui.dialog) {
-    $.ui.dialog.overlay.events = $.map('focus,keydown,keypress'.split(','),
-                                 function(event) { return event + '.dialog-overlay'; }).join(' ');
-  }
-}(jQuery));
diff --git a/core/modules/views/lib/Drupal/views/Ajax/DismissFormCommand.php b/core/modules/views/lib/Drupal/views/Ajax/DismissFormCommand.php
deleted file mode 100644
index a32b7fe8b11626c834131ad1d065692597c45641..0000000000000000000000000000000000000000
--- a/core/modules/views/lib/Drupal/views/Ajax/DismissFormCommand.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views\Ajax\DismissFormCommand.
- */
-
-namespace Drupal\views\Ajax;
-
-use Drupal\Core\Ajax\CommandInterface;
-
-/**
- * Provides an AJAX command for closing the views form modal.
- *
- * This command is implemented in Drupal.AjaxCommands.prototype.viewsDismissForm.
- */
-class DismissFormCommand implements CommandInterface {
-
-  /**
-   * Implements \Drupal\Core\Ajax\CommandInterface::render().
-   */
-  public function render() {
-    return array(
-      'command' => 'viewsDismissForm',
-    );
-  }
-
-}
diff --git a/core/modules/views/lib/Drupal/views/Ajax/SetFormCommand.php b/core/modules/views/lib/Drupal/views/Ajax/SetFormCommand.php
deleted file mode 100644
index e3c4ffa0f94143efcd02f6613b42d633dc913c48..0000000000000000000000000000000000000000
--- a/core/modules/views/lib/Drupal/views/Ajax/SetFormCommand.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views\Ajax\SetFormCommand.
- */
-
-namespace Drupal\views\Ajax;
-
-use Drupal\Core\Ajax\CommandInterface;
-
-/**
- * Provides an AJAX command for setting a form in the views edit modal.
- *
- * This command is implemented in Drupal.AjaxCommands.prototype.viewsSetForm.
- */
-class SetFormCommand implements CommandInterface {
-
-  /**
-   * The rendered output of the form.
-   *
-   * @var string
-   */
-  protected $output;
-
-  /**
-   * The title of the form.
-   *
-   * @var string
-   */
-  protected $title;
-
-  /**
-   * The URL of the form.
-   *
-   * @var string
-   */
-  protected $url;
-
-  /**
-   * Constructs a \Drupal\views\Ajax\ReplaceTitleCommand object.
-   *
-   * @param string $output
-   *   The form to display in the modal.
-   * @param string $title
-   *   The title of the form.
-   * @param string $url
-   *   (optional) An optional URL of the form.
-   */
-  public function __construct($output, $title, $url = NULL) {
-    $this->output = $output;
-    $this->title = $title;
-    $this->url = $url;
-  }
-
-  /**
-   * Implements \Drupal\Core\Ajax\CommandInterface::render().
-   */
-  public function render() {
-    $command = array(
-      'command' => 'viewsSetForm',
-      'output' => $this->output,
-      'title' => $this->title,
-    );
-    if (isset($this->url)) {
-      $command['url'] = $this->url;
-    }
-    return $command;
-  }
-
-}
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index 471b0bd32419b9c9e80912ae7b5e1945ba1a8e04..8631f25231e0b53c07cc17f869ddd4ac21816d66 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -352,7 +352,7 @@ function views_ui_standard_display_dropdown(&$form, &$form_state, $section) {
   // @todo Move this to a separate function if it's needed on any forms that
   // don't have the display dropdown.
   $form['override'] = array(
-    '#prefix' => '<div class="views-override clearfix container-inline">',
+    '#prefix' => '<div class="views-override clearfix container-inline" data-drupal-views-offset="top">',
     '#suffix' => '</div>',
     '#weight' => -1000,
     '#tree' => TRUE,
@@ -402,20 +402,20 @@ function views_ui_standard_display_dropdown(&$form, &$form_state, $section) {
 }
 
 /**
- * Create the URL for one of our standard AJAX forms based upon known
+ * Create the menu path for one of our standard AJAX forms based upon known
  * information about the form.
  */
-function views_ui_build_form_url($form_state) {
+function views_ui_build_form_path($form_state) {
   $ajax = empty($form_state['ajax']) ? 'nojs' : 'ajax';
   $name = $form_state['view']->id();
-  $url = "admin/structure/views/$ajax/$form_state[form_key]/$name/$form_state[display_id]";
+  $path = "admin/structure/views/$ajax/$form_state[form_key]/$name/$form_state[display_id]";
   if (isset($form_state['type'])) {
-    $url .= '/' . $form_state['type'];
+    $path .= '/' . $form_state['type'];
   }
   if (isset($form_state['id'])) {
-    $url .= '/' . $form_state['id'];
+    $path .= '/' . $form_state['id'];
   }
-  return $url;
+  return $path;
 }
 
 /**
diff --git a/core/modules/views_ui/css/views_ui.admin.css b/core/modules/views_ui/css/views_ui.admin.css
index 893a34dc6fd0dc3bc1c0b1f1b899553fd49e2298..a438859e79a66b7b3fe2f9e7a01d6638ba4f6671 100644
--- a/core/modules/views_ui/css/views_ui.admin.css
+++ b/core/modules/views_ui/css/views_ui.admin.css
@@ -209,35 +209,6 @@
 
 /* @end */
 
-/* @group Modal dialog box */
-
-.views-ui-dialog {
-  /* We need this so the button is visible. */
-  overflow: visible;
-  position: fixed;
-}
-
-.views-ui-dialog .ui-dialog-titlebar-close {
-  border: 1px solid transparent;
-  display: block;
-  margin: 0;
-  padding: 0;
-  position: absolute;
-  right: 0;
-  top: 2px;
-  /* Make sure this is in front of the modal backdrop. */
-  z-index: 1002;
-}
-
-.views-ui-dialog .ui-dialog-titlebar {
-  padding: 0;
-  margin: 0;
-}
-
-.views-ui-dialog .ui-dialog-title {
-  display: none;
-}
-
 .views-ui-dialog #views-ajax-popup {
   padding: 0;
   overflow: hidden;
@@ -253,8 +224,8 @@
 }
 
 .views-ui-dialog .scroll {
-  max-height: 400px;
   overflow: auto;
+  padding: 1em;
 }
 
 #views-filterable-options-controls {
diff --git a/core/modules/views_ui/css/views_ui.admin.theme.css b/core/modules/views_ui/css/views_ui.admin.theme.css
index bbc7d16a1b33fb20bf279ebbfe0f54c1921fddca..9a7119626a601d5b258d615702c717a9ed465446 100644
--- a/core/modules/views_ui/css/views_ui.admin.theme.css
+++ b/core/modules/views_ui/css/views_ui.admin.theme.css
@@ -401,15 +401,6 @@ td.group-title {
   padding-right: 10px;
 }
 
-/* This keeps the collapsible details of options from crashing into the bottom
- * of the edit option columns. Because the edit option columns are floated, the collapsible
- * details need to be floated as well so that the margin above the details interacts with
- * the float edit option columns.
- */
-#edit-options details {
-  width: 100%;
-}
-
 #edit-options-more {
   clear: both;
 }
@@ -783,28 +774,6 @@ ul#views-display-menu-tabs li.add ul.action-list li{
  * The contents of the popup dialog on the views edit form.
  */
 
-.views-ui-dialog {
-  font-size: small;
-  padding: 0;
-}
-
-.views-ui-dialog .ui-dialog-titlebar-close {
-  background: url("../images/close.png") no-repeat scroll 6px 3px #f3f4ee;
-  border-color: #aaa;
-  border-radius: 0 10px 12px 0;
-  border-style: solid;
-  border-width: 1px 1px 1px 0;
-  box-shadow: 0 -2px 0 rgba(0, 0, 0, 0.1);
-  height: 22px;
-  right: -28px;
-  top: 0;
-  width: 26px;
-}
-
-.views-ui-dialog .ui-dialog-titlebar-close span {
-  display: none;
-}
-
 .views-filterable-options .form-type-checkbox {
   border: 1px solid #ccc;
   padding: 5px 8px;
@@ -847,6 +816,10 @@ ul#views-display-menu-tabs li.add ul.action-list li{
   width: 200px;
 }
 
+.views-ui-dialog .ui-dialog-content {
+  padding: 0;
+}
+
 .views-ui-dialog .views-filterable-options {
   margin-bottom: 10px;
 }
@@ -869,8 +842,24 @@ ul#views-display-menu-tabs li.add ul.action-list li{
   background-color: #f3f4ee;
 }
 
+.views-ui-dialog.views-ui-dialog-scroll .ui-dialog-titlebar {
+  border: none;
+}
+
 .views-ui-dialog .views-override {
-  padding: 0 13px 8px;
+  padding: 8px 13px;
+}
+
+.views-ui-dialog [data-drupal-views-offset] {
+  border: 1px solid #ccc;
+}
+
+.views-ui-dialog [data-drupal-views-offset="top"] {
+  border-width: 0 0 1px;
+}
+
+.views-ui-dialog [data-drupal-views-offset="bottom"] {
+  border-width: 1px 0 0;
 }
 
 .views-ui-dialog .views-override > * {
@@ -902,25 +891,9 @@ ul#views-display-menu-tabs li.add ul.action-list li{
   content: "\00A0\003E";
 }
 
-.views-ui-dialog .scroll {
-  border: 1px solid #ccc;
-  border-width: 1px 0;
-  padding: 8px 13px;
-}
-
 .views-ui-dialog details .item-list {
   padding-left: 2em;
 }
-
-.views-ui-dialog .form-buttons {
-  background-color: #f3f4ee;
-  padding: 8px 13px;
-}
-.views-ui-dialog .form-buttons input {
-  margin-bottom: 0;
-  margin-right: 0;
-}
-
 /* @end */
 
 /* @group Configure filter criteria */
diff --git a/core/modules/views_ui/js/ajax.js b/core/modules/views_ui/js/ajax.js
index dc327ee4e9fe4b624a5f4da20adb003cceccfb55..0b416c95d7ada6627a26aa5f4a13ddba115804c8 100644
--- a/core/modules/views_ui/js/ajax.js
+++ b/core/modules/views_ui/js/ajax.js
@@ -6,42 +6,6 @@
 
   "use strict";
 
-  Drupal.AjaxCommands.prototype.viewsSetForm = function (ajax, response, status) {
-    var ajax_title = drupalSettings.views.ajax.title;
-    var ajax_body = drupalSettings.views.ajax.id;
-    var ajax_popup = drupalSettings.views.ajax.popup;
-    $(ajax_title).html('<h2>' + response.title + '</h2>');
-    $(ajax_body).html(response.output);
-    $(ajax_popup).dialog('open');
-    Drupal.attachBehaviors($(ajax_popup), ajax.settings);
-    if (response.url) {
-      // Identify the button that was clicked so that .ajaxSubmit() can use it.
-      // We need to do this for both .click() and .mousedown() since JavaScript
-      // code might trigger either behavior.
-      var $submit_buttons = $('input[type=submit], button', ajax_body);
-      $submit_buttons.click(function(event) {
-        this.form.clk = this;
-      });
-      $submit_buttons.mousedown(function(event) {
-        this.form.clk = this;
-      });
-
-      $('form', ajax_body).once('views-ajax-submit-processed').each(function() {
-        var element_settings = { 'url': response.url, 'event': 'submit', 'progress': { 'type': 'throbber' } };
-        var $form = $(this);
-        var id = $form.attr('id');
-        Drupal.ajax[id] = new Drupal.ajax(id, this, element_settings);
-        Drupal.ajax[id].form = $form;
-      });
-    }
-    Drupal.viewsUi.resizeModal();
-  };
-
-  Drupal.AjaxCommands.prototype.viewsDismissForm = function (ajax, response, status) {
-    Drupal.AjaxCommands.prototype.viewsSetForm({}, {'title': '', 'output': drupalSettings.views.ajax.defaultForm});
-    $(drupalSettings.views.ajax.popup).dialog('close');
-  };
-
   Drupal.AjaxCommands.prototype.viewsHighlight = function (ajax, response, status) {
     $('.hilited').removeClass('hilited');
     $(response.selector).addClass('hilited');
@@ -113,20 +77,6 @@
   Drupal.behaviors.viewsAjax = {
     collapseReplaced: false,
     attach: function (context, settings) {
-      if (!settings.views) {
-        return;
-      }
-      // Create a jQuery UI dialog, but leave it closed.
-      var dialog_area = $(settings.views.ajax.popup, context);
-      dialog_area.dialog({
-        'autoOpen': false,
-        'dialogClass': 'views-ui-dialog',
-        'modal': true,
-        'position': 'center',
-        'resizable': false,
-        'width': 750
-      });
-
       var base_element_settings = {
         'event': 'click',
         'progress': { 'type': 'throbber' }
@@ -187,36 +137,6 @@
         Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
       });
 
-      if (!this.collapseReplaced && Drupal.collapseScrollIntoView) {
-        this.collapseReplaced = true;
-        Drupal.collapseScrollIntoView = function (node) {
-          for (var $parent = $(node); $parent.get(0) !== document && $parent.size() !== 0; $parent = $parent.parent()) {
-            if ($parent.css('overflow') === 'scroll' || $parent.css('overflow') === 'auto') {
-              if (Drupal.viewsUi.resizeModal) {
-                // If the modal is already at the max height, don't bother with
-                // this since the only reason to do it is to grow the modal.
-                if ($('.views-ui-dialog').height() < parseInt($(window).height() * 0.8, 10)) {
-                  Drupal.viewsUi.resizeModal('', true);
-                }
-              }
-              return;
-            }
-          }
-
-          var h = document.documentElement.clientHeight || document.body.clientHeight || 0;
-          var offset = document.documentElement.scrollTop || document.body.scrollTop || 0;
-          var posY = $(node).offset().top;
-          var fudge = 55;
-          if (posY + node.offsetHeight + fudge > h + offset) {
-            if (node.offsetHeight > h) {
-              window.scrollTo(0, posY);
-            }
-            else {
-              window.scrollTo(0, posY + node.offsetHeight - h + fudge);
-            }
-          }
-        };
-      }
     }
   };
 
diff --git a/core/modules/views_ui/js/dialog.views.js b/core/modules/views_ui/js/dialog.views.js
new file mode 100644
index 0000000000000000000000000000000000000000..818d2d55c8dd0f1e663baff8a3abdaa8312ca160
--- /dev/null
+++ b/core/modules/views_ui/js/dialog.views.js
@@ -0,0 +1,43 @@
+(function ($, Drupal, drupalSettings) {
+
+  "use strict";
+
+  function handleDialogResize (e) {
+    var $modal = $(e.currentTarget);
+    var $viewsOverride = $modal.find('[data-drupal-views-offset]');
+    var $scroll = $modal.find('[data-drupal-views-scroll]');
+    var offset = 0;
+    var modalHeight;
+    if ($viewsOverride.length && $scroll.length) {
+      // Add a class to do some styles adjustments.
+      $modal.closest('.views-ui-dialog').addClass('views-ui-dialog-scroll');
+      // Let scroll element take all the height available.
+      $scroll.css({ overflow: 'visible', height: 'auto' });
+      modalHeight = $modal.height();
+      $viewsOverride.each(function () { offset += $(this).outerHeight(); });
+
+      // Take internal padding into account.
+      var scrollOffset = $scroll.outerHeight() - $scroll.height();
+      $scroll.height(modalHeight - offset - scrollOffset);
+      // Reset scrolling properties.
+      $modal.css('overflow', 'hidden');
+      $scroll.css('overflow', 'auto');
+    }
+  }
+
+  Drupal.behaviors.viewsModalContent = {
+    attach: function (context) {
+      $('body').once('viewsDialog').on('dialogContentResize.viewsDialog', '.ui-dialog-content', handleDialogResize);
+      // When expanding details, make sure the modal is resized.
+      $(context).find('.scroll').once('detailsUpdate').on('click', 'summary', function (e) {
+        $(e.currentTarget).trigger('dialogContentResize');
+      });
+    },
+    detach: function (context, settings, trigger) {
+      if (trigger === 'unload') {
+        $('body').removeOnce('viewsDialog').off('.viewsDialog');
+      }
+    }
+  };
+
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/views_ui/js/views-admin.js b/core/modules/views_ui/js/views-admin.js
index bc5c6f0c380d845f218b023b3705bb7327efef9d..ee70f1fd180e12f0679f463ea23e69b542cd5285 100644
--- a/core/modules/views_ui/js/views-admin.js
+++ b/core/modules/views_ui/js/views-admin.js
@@ -2,7 +2,7 @@
  * @file
  * Some basic behaviors and utility functions for Views UI.
  */
-(function ($, Drupal, drupalSettings, debounce) {
+(function ($, Drupal, drupalSettings) {
 
 "use strict";
 
@@ -162,11 +162,14 @@ $.extend(Drupal.viewsUi.FormFieldFiller.prototype, {
 
 Drupal.behaviors.addItemForm = {
   attach: function (context) {
+    var $context = $(context);
+    var $form = $context;
     // The add item form may have an id of views-ui-add-item-form--n.
-    var $form = $(context).find('form[id^="views-ui-add-item-form"]').first();
-    // Make sure we don't add more than one event handler to the same form.
-    $form = $form.once('views-ui-add-item-form');
-    if ($form.length) {
+    if (!$context.is('form[id^="views-ui-add-item-form"]')) {
+      $form = $context.find('form[id^="views-ui-add-item-form"]');
+    }
+    if ($form.once('views-ui-add-item-form').length) {
+      // If we we have an unprocessed views-ui-add-item-form, let's instantiate.
       new Drupal.viewsUi.AddItemForm($form);
     }
   }
@@ -186,7 +189,7 @@ Drupal.viewsUi.AddItemForm.prototype.handleCheck = function (event) {
   var label = $.trim($target.next().text());
   // Add/remove the checked item to the list.
   if ($target.is(':checked')) {
-    this.$selected_div.show();
+    this.$selected_div.show().css('display', 'block');
     this.checkedItems.push(label);
   }
   else {
@@ -212,8 +215,9 @@ Drupal.viewsUi.AddItemForm.prototype.handleCheck = function (event) {
  */
 Drupal.viewsUi.AddItemForm.prototype.refreshCheckedItems = function () {
   // Perhaps we should precache the text div, too.
-  this.$selected_div.find('.views-selected-options').html(this.checkedItems.join(', '));
-  Drupal.viewsUi.resizeModal('', true);
+  this.$selected_div.find('.views-selected-options')
+    .html(this.checkedItems.join(', '))
+    .trigger('dialogContentResize');
 };
 
 /**
@@ -279,11 +283,14 @@ Drupal.behaviors.viewsUiRenderAddViewButton.toggleMenu = function ($trigger) {
 
 Drupal.behaviors.viewsUiSearchOptions = {
   attach: function (context) {
+    var $context = $(context);
+    var $form = $context;
     // The add item form may have an id of views-ui-add-item-form--n.
-    var $form = $(context).find('form[id^="views-ui-add-item-form"]').first();
+    if (!$context.is('form[id^="views-ui-add-item-form"]')) {
+      $form = $context.find('form[id^="views-ui-add-item-form"]');
+    }
     // Make sure we don't add more than one event handler to the same form.
-    $form = $form.once('views-ui-filter-options');
-    if ($form.length) {
+    if ($form.once('views-ui-filter-options').length) {
       new Drupal.viewsUi.OptionsSearch($form);
     }
   }
@@ -868,7 +875,8 @@ Drupal.behaviors.viewsUiOverrideSelect = {
   attach: function (context) {
     $(context).find('#edit-override-dropdown').once('views-ui-override-button-text', function () {
       // Closures! :(
-      var $submit = $('#edit-submit');
+      var $context = $(context);
+      var $submit = $context.find('[id^=edit-submit]');
       var old_value = $submit.val();
 
       $submit.once('views-ui-override-button-text')
@@ -888,6 +896,8 @@ Drupal.behaviors.viewsUiOverrideSelect = {
         else {
           $submit.val(Drupal.t('Apply (this display)'));
         }
+        var $dialog = $context.closest('.ui-dialog-content');
+        $dialog.trigger('dialogButtonsChange');
       })
         .trigger('change');
     });
@@ -895,98 +905,6 @@ Drupal.behaviors.viewsUiOverrideSelect = {
   }
 };
 
-Drupal.viewsUi.resizeModal = function (e, no_shrink) {
-  var $modal = $('.views-ui-dialog');
-  var $window = $(window);
-  var windowWidth = $window.width();
-  var $scroll = $modal.find('.scroll');
-  if ($modal.size() === 0 || $modal.css('display') === 'none') {
-    return;
-  }
-
-  var maxWidth = parseInt(windowWidth * 0.85, 10); // 85% of window
-  var minWidth = parseInt(windowWidth * 0.6, 10); // 60% of window
-
-  // Set the modal to the minwidth so that our width calculation of
-  // children works.
-  $modal.css('width', minWidth);
-  var width = minWidth;
-
-  // Don't let the window get more than 80% of the display high.
-  var maxHeight = parseInt($window.height() * 0.8, 10);
-  var minHeight = 200;
-  if (no_shrink) {
-    minHeight = $modal.height();
-  }
-
-  if (minHeight > maxHeight) {
-    minHeight = maxHeight;
-  }
-
-  var height = 0;
-
-  // Calculate the height of the 'scroll' region.
-  var scrollHeight = 0;
-
-  scrollHeight += parseInt($scroll.css('padding-top'), 10);
-  scrollHeight += parseInt($scroll.css('padding-bottom'), 10);
-
-  $scroll.children().each(function () {
-    var w = $(this).innerWidth();
-    if (w > width) {
-      width = w;
-    }
-    scrollHeight += $(this).outerHeight(true);
-  });
-
-  // Now, calculate what the difference between the scroll and the modal
-  // will be.
-
-  var difference = 0;
-  difference += parseInt($scroll.css('padding-top'), 10);
-  difference += parseInt($scroll.css('padding-bottom'), 10);
-  difference += $('.views-override').outerHeight(true);
-  difference += $('.views-messages').outerHeight(true);
-  difference += $('#views-ajax-title').outerHeight(true);
-  difference += $('.views-add-form-selected').outerHeight(true);
-  difference += $('.form-buttons', $modal).outerHeight(true);
-
-  height = scrollHeight + difference;
-
-  if (height > maxHeight) {
-    height = maxHeight;
-    scrollHeight = maxHeight - difference;
-  }
-  else if (height < minHeight) {
-    height = minHeight;
-    scrollHeight = minHeight - difference;
-  }
-
-  if (width > maxWidth) {
-    width = maxWidth;
-  }
-
-  // Get where we should move content to
-  var top = ($(window).height() / 2) - (height / 2);
-  var left = ($(window).width() / 2) - (width / 2);
-
-  $modal.css({
-    'top': top + 'px',
-    'left': left + 'px',
-    'width': width + 'px',
-    'height': height + 'px'
-  });
-
-  // Ensure inner popup height matches.
-  $(drupalSettings.views.ajax.popup).css('height', height + 'px');
-
-  $scroll.css({
-    'height': scrollHeight + 'px',
-    'max-height': scrollHeight + 'px'
-  });
-
-};
-
 Drupal.behaviors.viewsUiHandlerRemoveLink = {
   attach: function (context) {
     var $context = $(context);
@@ -1010,6 +928,4 @@ Drupal.behaviors.viewsUiHandlerRemoveLink = {
   }
 };
 
-$(window).on('resize scroll', debounce(Drupal.viewsUi.resizeModal, 100));
-
-})(jQuery, Drupal, drupalSettings, Drupal.debounce);
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/AddItem.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/AddItem.php
index 9ebae511c242acf9b09694cb0a7c1b9c9d549b27..ed6c1e21976cec7ae8d34430801fa11fbf43dbf1 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/AddItem.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/AddItem.php
@@ -56,7 +56,7 @@ public function buildForm(array $form, array &$form_state) {
     $form = array(
       'options' => array(
         '#theme_wrappers' => array('container'),
-        '#attributes' => array('class' => array('scroll')),
+        '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE),
       ),
     );
 
@@ -169,15 +169,18 @@ public function buildForm(array $form, array &$form_state) {
       '#type' => 'item',
       '#markup' => '<span class="views-ui-view-title">' . $this->t('Selected:') . '</span> ' . '<div class="views-selected-options"></div>',
       '#theme_wrappers' => array('form_element', 'views_ui_container'),
-      '#attributes' => array('class' => array('container-inline', 'views-add-form-selected')),
+      '#attributes' => array(
+        'class' => array('container-inline', 'views-add-form-selected'),
+        'data-drupal-views-offset' => 'bottom',
+      ),
     );
     $view->getStandardButtons($form, $form_state, 'views_ui_add_item_form', $this->t('Add and configure @types', array('@types' => $ltitle)));
 
     // Remove the default submit function.
-    $form['buttons']['submit']['#submit'] = array_filter($form['buttons']['submit']['#submit'], function($var) {
+    $form['actions']['submit']['#submit'] = array_filter($form['actions']['submit']['#submit'], function($var) {
       return !(is_array($var) && isset($var[1]) && $var[1] == 'standardSubmit');
     });
-    $form['buttons']['submit']['#submit'][] = array($view, 'submitItemAdd');
+    $form['actions']['submit']['#submit'][] = array($view, 'submitItemAdd');
 
     return $form;
   }
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
index 3229167a9cd641d8db40f7593f0a4d0f4036c880..6728002c16519d51e2b8e660153d45bdc1c7c40d 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItem.php
@@ -60,7 +60,7 @@ public function buildForm(array $form, array &$form_state) {
       'options' => array(
         '#tree' => TRUE,
         '#theme_wrappers' => array('container'),
-        '#attributes' => array('class' => array('scroll')),
+        '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE),
       ),
     );
     $executable = $view->getExecutable();
@@ -168,11 +168,14 @@ public function buildForm(array $form, array &$form_state) {
 
       $view->getStandardButtons($form, $form_state, 'views_ui_config_item_form', $name);
       // Add a 'remove' button.
-      $form['buttons']['remove'] = array(
+      $form['actions']['remove'] = array(
         '#type' => 'submit',
         '#value' => $this->t('Remove'),
         '#submit' => array(array($this, 'remove')),
         '#limit_validation_errors' => array(array('override')),
+        '#ajax' => array(
+          'path' => current_path(),
+        ),
       );
     }
 
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemExtra.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemExtra.php
index e66a24e2f36c4a38b0d6f33a0721b85c5703bdb4..f097a262b87e2ad5f122112591e7067c6c590ca9 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemExtra.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemExtra.php
@@ -59,7 +59,7 @@ public function buildForm(array $form, array &$form_state) {
       'options' => array(
         '#tree' => true,
         '#theme_wrappers' => array('container'),
-        '#attributes' => array('class' => array('scroll')),
+        '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE),
       ),
     );
     $executable = $view->getExecutable();
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemGroup.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemGroup.php
index 976a8ecebe0def364dda92febd37bd89821b3b51..c4ddbf2435d039ddd870accac202a048c2d6d263 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemGroup.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ConfigItemGroup.php
@@ -60,7 +60,7 @@ public function buildForm(array $form, array &$form_state) {
       'options' => array(
         '#tree' => TRUE,
         '#theme_wrappers' => array('container'),
-        '#attributes' => array('class' => array('scroll')),
+        '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE),
       ),
     );
     $executable = $view->getExecutable();
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Display.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Display.php
index 01ba7392d7c1cfea070324be430c75428f124256..9bafab13ef83c6b53508852c444ab67db8688871 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Display.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Display.php
@@ -70,7 +70,7 @@ public function buildForm(array $form, array &$form_state) {
     // Get form from the handler.
     $form['options'] = array(
       '#theme_wrappers' => array('container'),
-      '#attributes' => array('class' => array('scroll')),
+      '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE),
     );
     $executable->display_handler->buildOptionsForm($form['options'], $form_state);
 
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/EditDetails.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/EditDetails.php
index ce9d9d114242343fb6a5c09718a851d30484ff78..ba41b62b9506bb70d9e75c00f6205a206fefbee8 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/EditDetails.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/EditDetails.php
@@ -40,7 +40,7 @@ public function buildForm(array $form, array &$form_state) {
 
     $form['details'] = array(
       '#theme_wrappers' => array('container'),
-      '#attributes' => array('class' => array('scroll')),
+      '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE),
     );
     $form['details']['label'] = array(
       '#type' => 'textfield',
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Rearrange.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Rearrange.php
index d5e713dc73b1d85795f42b984a4dcaed8e755c2b..6beed551f6fb6d97a67f5eb0df5b8595016e58d5 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Rearrange.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Rearrange.php
@@ -80,7 +80,7 @@ public function buildForm(array $form, array &$form_state) {
         array('order', 'sibling', 'weight'),
       ),
       '#tree' => TRUE,
-      '#prefix' => '<div class="scroll">',
+      '#prefix' => '<div class="scroll" data-drupal-views-scroll>',
       '#suffix' => '</div>',
     );
 
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/RearrangeFilter.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/RearrangeFilter.php
index 3eea26527fe4a8ae2a73bbe47aa30c2bda3356ed..71b0694087f7d7315b181c7c152416639fba3216 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/RearrangeFilter.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/RearrangeFilter.php
@@ -204,7 +204,7 @@ public function buildForm(array $form, array &$form_state) {
     }
 
     $view->getStandardButtons($form, $form_state, 'views_ui_rearrange_filter_form');
-    $form['buttons']['add_group'] = array(
+    $form['actions']['add_group'] = array(
       '#type' => 'submit',
       '#value' => $this->t('Create new filter group'),
       '#id' => 'views-add-group',
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php
index 595a77c353b8e7b9abc85ab517692c88f259da62..9b4bb38f9aeac65085aec42dae7836e816755c61 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php
@@ -63,7 +63,7 @@ public function buildForm(array $form, array &$form_state) {
         array('order', 'sibling', 'weight'),
       ),
       '#tree' => TRUE,
-      '#prefix' => '<div class="scroll">',
+      '#prefix' => '<div class="scroll" data-drupal-views-scroll>',
       '#suffix' => '</div>',
     );
 
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ViewsFormBase.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ViewsFormBase.php
index 3123c9d563d3b1e075cf244b1a6bb7cacb4795b0..f3aa6ee15446b6bc72e86bef74755d9cd28e0855 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ViewsFormBase.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ViewsFormBase.php
@@ -11,6 +11,7 @@
 use Drupal\views\ViewStorageInterface;
 use Drupal\views\Ajax;
 use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\CloseModalDialogCommand;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 
 /**
@@ -144,11 +145,11 @@ public function getForm(ViewStorageInterface $view, $display_id, $js) {
       $form_state = $reflection->newInstanceArgs(array_slice($top, 3, 2))->getFormState($view, $top[2], $form_state['ajax']);
 
       $form_state['input'] = array();
-      $form_url = views_ui_build_form_url($form_state);
+      $form_path = views_ui_build_form_path($form_state);
       if (!$form_state['ajax']) {
-        return new RedirectResponse(url($form_url, array('absolute' => TRUE)));
+        return new RedirectResponse(url($form_path, array('absolute' => TRUE)));
       }
-      $form_state['url'] = url($form_url);
+      $form_state['path'] = url($form_path);
       $response = views_ajax_form_wrapper($form_state['form_id'], $form_state);
     }
     elseif (!$form_state['ajax']) {
@@ -157,7 +158,7 @@ public function getForm(ViewStorageInterface $view, $display_id, $js) {
     }
     else {
       $response = new AjaxResponse();
-      $response->addCommand(new Ajax\DismissFormCommand());
+      $response->addCommand(new CloseModalDialogCommand());
       $response->addCommand(new Ajax\ShowButtonsCommand());
       $response->addCommand(new Ajax\TriggerPreviewCommand());
       if (!empty($form_state['#page_title'])) {
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
index f126edede890ea46b3d5580cd79dccfe5c57e099..80d93a1926d3a89b24f05ba03f00788d75c760a2 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
@@ -267,9 +267,8 @@ public function standardCancel($form, &$form_state) {
    * docblock outdated?
    */
   public function getStandardButtons(&$form, &$form_state, $form_id, $name = NULL) {
-    $form['buttons'] = array(
-      '#prefix' => '<div class="clearfix"><div class="form-buttons">',
-      '#suffix' => '</div></div>',
+    $form['actions'] = array(
+      '#type' => 'actions',
     );
 
     if (empty($name)) {
@@ -280,12 +279,18 @@ public function getStandardButtons(&$form, &$form_state, $form_id, $name = NULL)
       $names = array(t('Apply'), t('Apply and continue'));
     }
 
+    // Views provides its own custom handling of AJAX form submissions. Usually
+    // this happens at the same path, but custom paths may be specified in
+    // $form_state.
+    $form_path = empty($form_state['path']) ? current_path() : $form_state['path'];
+
     // Forms that are purely informational set an ok_button flag, so we know not
     // to create an "Apply" button for them.
     if (empty($form_state['ok_button'])) {
-      $form['buttons']['submit'] = array(
+      $form['actions']['submit'] = array(
         '#type' => 'submit',
         '#value' => $name,
+        '#id' => 'edit-submit-' . drupal_html_id($form_id),
         // The regular submit handler ($form_id . '_submit') does not apply if
         // we're updating the default display. It does apply if we're updating
         // the current display. Since we have no way of knowing at this point
@@ -293,6 +298,9 @@ public function getStandardButtons(&$form, &$form_state, $form_id, $name = NULL)
         // take care of running the regular submit handler as appropriate.
         '#submit' => array(array($this, 'standardSubmit')),
         '#button_type' => 'primary',
+        '#ajax' => array(
+          'path' => $form_path,
+        ),
       );
       // Form API button click detection requires the button's #value to be the
       // same between the form build of the initial page request, and the
@@ -304,25 +312,28 @@ public function getStandardButtons(&$form, &$form_state, $form_id, $name = NULL)
       // extending button click detection code to support any of the possible
       // button labels.
       if (isset($names)) {
-        $form['buttons']['submit']['#values'] = $names;
-        $form['buttons']['submit']['#process'] = array_merge(array('views_ui_form_button_was_clicked'), element_info_property($form['buttons']['submit']['#type'], '#process', array()));
+        $form['actions']['submit']['#values'] = $names;
+        $form['actions']['submit']['#process'] = array_merge(array('views_ui_form_button_was_clicked'), element_info_property($form['actions']['submit']['#type'], '#process', array()));
       }
       // If a validation handler exists for the form, assign it to this button.
       if (isset($form_state['build_info']['callback_object'])) {
-        $form['buttons']['submit']['#validate'][] = array($form_state['build_info']['callback_object'], 'validateForm');
+        $form['actions']['submit']['#validate'][] = array($form_state['build_info']['callback_object'], 'validateForm');
       }
       if (function_exists($form_id . '_validate')) {
-        $form['buttons']['submit']['#validate'][] = $form_id . '_validate';
+        $form['actions']['submit']['#validate'][] = $form_id . '_validate';
       }
     }
 
     // Create a "Cancel" button. For purely informational forms, label it "OK".
     $cancel_submit = function_exists($form_id . '_cancel') ? $form_id . '_cancel' : array($this, 'standardCancel');
-    $form['buttons']['cancel'] = array(
+    $form['actions']['cancel'] = array(
       '#type' => 'submit',
       '#value' => empty($form_state['ok_button']) ? t('Cancel') : t('Ok'),
       '#submit' => array($cancel_submit),
       '#validate' => array(),
+      '#ajax' => array(
+        'path' => $form_path,
+      ),
       '#limit_validation_errors' => array(),
     );
 
@@ -331,9 +342,6 @@ public function getStandardButtons(&$form, &$form_state, $form_id, $name = NULL)
     if (isset($form['#title'])) {
       $form_state['title'] = $form['#title'];
     }
-    if (isset($form['#url'])) {
-      $form_state['url'] = $form['#url'];
-    }
     if (isset($form['#section'])) {
       $form_state['#section'] = $form['#section'];
     }
diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module
index 6da533995b8f28e2881b47f3dca1887978d32029..0f76cbd162f486f4e4cbb815644bb80210e7ba08 100644
--- a/core/modules/views_ui/views_ui.module
+++ b/core/modules/views_ui/views_ui.module
@@ -191,13 +191,13 @@ function views_ui_library_info() {
     'version' => \Drupal::VERSION,
     'js' => array(
       $path . 'ajax.js' => array('group' => JS_DEFAULT),
+      $path . 'dialog.views.js' => array('group' => JS_DEFAULT),
       $path . 'views-admin.js' => array('group' => JS_DEFAULT),
     ),
     'dependencies' => array(
       array('system', 'jquery'),
       array('system', 'drupal'),
       array('system', 'drupalSettings'),
-      array('system', 'drupal.debounce'),
       array('system', 'jquery.once'),
       array('system', 'jquery.form'),
       array('system', 'drupal.ajax'),
diff --git a/core/modules/views_ui/views_ui.theme.inc b/core/modules/views_ui/views_ui.theme.inc
index 38a8fe4f52c4d483d42152e66313f7948341693a..a13467e89c68a66b69d7f5cd2529af21b566e231 100644
--- a/core/modules/views_ui/views_ui.theme.inc
+++ b/core/modules/views_ui/views_ui.theme.inc
@@ -276,7 +276,7 @@ function theme_views_ui_rearrange_filter_form(&$variables) {
   }
 
   $output = drupal_render($form['override']);
-  $output .= '<div class="scroll">';
+  $output .= '<div class="scroll" data-drupal-views-scroll>';
   if ($grouping) {
     $output .= drupal_render($form['filter_groups']['operator']);
   }
@@ -315,7 +315,7 @@ function theme_views_ui_rearrange_filter_form(&$variables) {
 
   // When JavaScript is enabled, the button for adding a new group should be
   // hidden, since it will be replaced by a link on the client side.
-  $form['buttons']['add_group']['#attributes']['class'][] = 'js-hide';
+  $form['actions']['add_group']['#attributes']['class'][] = 'js-hide';
 
   // Render the rest of the form and return.
   $output .= drupal_render_children($form);
diff --git a/core/themes/bartik/css/style.css b/core/themes/bartik/css/style.css
index f74c1845d5ccb1ba30c1976096f8d71ec90a2dbc..eaa306186ed0ad4fc273261dc1fb3a59c6fa99e8 100644
--- a/core/themes/bartik/css/style.css
+++ b/core/themes/bartik/css/style.css
@@ -1992,22 +1992,6 @@ div.admin-panel .description {
   background-color: #F9F9F9;
 }
 
-.views-ui-dialog .ui-dialog-titlebar-close,
-.views-ui-dialog #views-ajax-title,
-.views-ui-dialog .views-override,
-.views-ui-dialog .form-buttons {
-  background-color: #f6f6f6;
-}
-
-.views-ui-dialog a {
-  color: #0071b3;
-}
-
-.views-ui-dialog a:hover,
-.views-ui-dialog a:focus {
-  color: #018fe2;
-}
-
 /* @end */
 
 .views-display-column .details-wrapper {
diff --git a/core/themes/seven/style.css b/core/themes/seven/style.css
index b52771c570b1c069ed793e4a4e7e70d5d195be26..69ef6ec5b24d96aae1bbb1754239618ee446b30a 100644
--- a/core/themes/seven/style.css
+++ b/core/themes/seven/style.css
@@ -1642,13 +1642,6 @@ details.fieldset-no-legend {
  * The contents of the popup dialog on the views edit form.
  */
 
-.views-ui-dialog .ui-dialog-titlebar-close {
-  box-shadow: none;
-  border-color: #cccccc;
-  right: -27px;
-  top: -1px;
-}
-
 .filterable-option .form-item.form-type-checkbox {
   /* This selector is aggressive because Seven's reset for .form-items is aggressive. */
   padding-bottom: 4px;