diff --git a/core/misc/collapse.js b/core/misc/collapse.js
index 77eb9ff..e504315 100644
--- a/core/misc/collapse.js
+++ b/core/misc/collapse.js
@@ -171,9 +171,10 @@ $.extend(CollapsibleDetails.prototype, {
 
 Drupal.behaviors.collapse = {
   attach: function (context, settings) {
-    if (isDetailsSupported) {
+    // Details element does not support summaries.
+    /*if (isDetailsSupported) {
       return;
-    }
+    }*/
     var $collapsibleDetails = $(context).find('details').once('collapse');
     if ($collapsibleDetails.length) {
       for (var i = 0; i < $collapsibleDetails.length; i++) {
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorCategoryBlock.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorCategoryBlock.php
index 2f17216..e8527fe 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorCategoryBlock.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorCategoryBlock.php
@@ -44,14 +44,13 @@ public function blockAccess() {
   /**
    * Overrides \Drupal\block\BlockBase::blockForm().
    */
-  public function blockForm($form, &$form_state) {
-    $form['block_count'] = array(
+  public function blockForm(&$form, &$form_state) {
+    $form['basic']['block_count'] = array(
       '#type' => 'select',
       '#title' => t('Number of news items in block'),
       '#default_value' => $this->configuration['block_count'],
       '#options' => drupal_map_assoc(range(2, 20)),
     );
-    return $form;
   }
 
   /**
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorFeedBlock.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorFeedBlock.php
index e5d125d..d9b8059 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorFeedBlock.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/block/block/AggregatorFeedBlock.php
@@ -44,14 +44,13 @@ public function blockAccess() {
   /**
    * Overrides \Drupal\block\BlockBase::blockForm().
    */
-  public function blockForm($form, &$form_state) {
-    $form['block_count'] = array(
+  public function blockForm(&$form, &$form_state) {
+    $form['basic'['block_count'] = array(
       '#type' => 'select',
       '#title' => t('Number of news items in block'),
       '#default_value' => $this->configuration['block_count'],
       '#options' => drupal_map_assoc(range(2, 20)),
     );
-    return $form;
   }
 
   /**
diff --git a/core/modules/block/block.js b/core/modules/block/block.js
index a37c07d..b0ef46d 100644
--- a/core/modules/block/block.js
+++ b/core/modules/block/block.js
@@ -39,6 +39,23 @@ Drupal.behaviors.blockSettingsSummary = {
         return Drupal.t('Restricted to certain pages');
       }
     });
+
+    // Meta summeries for higher level form structure.
+    $('#edit-basic').drupalSetSummary(function (context) {
+      var title = $(context).find('#edit-label').val();
+      return Drupal.t('Title: @title', {'@title' : title ? title : Drupal.t('Empty') });
+    });
+    $('#edit-location').drupalSetSummary(function (context) {
+      return Drupal.t('Region: @region', {'@region' : $(context).find('#edit-region option:selected').text() });
+    });
+    $('#edit-display').drupalSetSummary(function (context) {
+      var visibility = [];
+      var panes = $(context).find('.vertical-tab-button');
+      for (var i = 0, il = panes.length; i < il; i += 1) {
+        visibility.push($(panes[i]).find('a strong').text() + ': ' + $(panes[i]).find('a .summary').text());
+      }
+      return visibility.join(', ');
+    });
   }
 };
 
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/block/block/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/block/block/CustomBlock.php
index 84cd757..69b740a 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/block/block/CustomBlock.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/block/block/CustomBlock.php
@@ -46,10 +46,10 @@ public function getConfig() {
    *
    * Adds body and description fields to the block configuration form.
    */
-  public function blockForm($form, &$form_state) {
+  public function blockForm(&$form, &$form_state) {
     // @todo Disable this field when editing an existing block and provide a
     //   separate interface for administering custom blocks.
-    $form['info'] = array(
+    $form['basic']['info'] = array(
       '#type' => 'textfield',
       '#title' => t('Description'),
       '#required' => TRUE,
@@ -58,7 +58,7 @@ public function blockForm($form, &$form_state) {
     );
     // @todo Disable this field when editing an existing block and provide a
     //   separate interface for administering custom blocks.
-    $form['body'] = array(
+    $form['basic']['body'] = array(
       '#type' => 'text_format',
       '#title' => t('Body'),
       '#default_value' => $this->configuration['body'],
@@ -67,8 +67,7 @@ public function blockForm($form, &$form_state) {
       '#rows' => 15,
       '#required' => TRUE,
     );
-    $form['title']['#description'] = t('The title of the block as shown to the user.');
-    return $form;
+    $form['basic']['title']['#description'] = t('The title of the block as shown to the user.');
   }
 
   /**
diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php
index 9e5bf6c..546d1cb 100644
--- a/core/modules/block/lib/Drupal/block/BlockBase.php
+++ b/core/modules/block/lib/Drupal/block/BlockBase.php
@@ -234,13 +234,19 @@ public function form($form, &$form_state) {
       '#value' => $definition['module'],
     );
 
-    $form['label'] = array(
+    $form['basic'] = array(
+      '#type' => 'details',
+      '#title' => t('Basic information'),
+      '#group' => 'sections',
+      '#tree' => FALSE,
+    );
+    $form['basic']['label'] = array(
       '#type' => 'textfield',
       '#title' => t('Title'),
       '#maxlength' => 255,
       '#default_value' => !$entity->isNew() ? $entity->label() : $definition['subject'],
     );
-    $form['machine_name'] = array(
+    $form['basic']['machine_name'] = array(
       '#type' => 'machine_name',
       '#title' => t('Machine name'),
       '#maxlength' => 64,
@@ -249,13 +255,21 @@ public function form($form, &$form_state) {
       '#machine_name' => array(
         'exists' => 'block_load',
         'replace_pattern' => '[^a-z0-9_.]+',
+        'source' => array('basic', 'label'),
       ),
       '#required' => TRUE,
       '#disabled' => !$entity->isNew(),
     );
 
     // Region settings.
-    $form['region'] = array(
+    $form['location'] = array(
+      '#type' => 'details',
+      '#title' => t('Block location'),
+      '#group' => 'sections',
+      '#tree' => FALSE,
+      '#collapsed' => TRUE,
+    );
+    $form['location']['region'] = array(
       '#type' => 'select',
       '#title' => t('Region'),
       '#description' => t('Select the region where this block should be displayed.'),
@@ -265,7 +279,14 @@ public function form($form, &$form_state) {
     );
 
     // Visibility settings.
-    $form['visibility'] = array(
+    $form['display'] = array(
+      '#type' => 'details',
+      '#title' => t('Block visibility'),
+      '#group' => 'sections',
+      '#tree' => FALSE,
+      '#collapsed' => TRUE,
+    );
+    $form['display']['visibility'] = array(
       '#type' => 'vertical_tabs',
       '#title' => t('Visibility settings'),
       '#attached' => array(
@@ -276,7 +297,7 @@ public function form($form, &$form_state) {
     );
 
     // Per-path visibility.
-    $form['visibility']['path'] = array(
+    $form['display']['visibility']['path'] = array(
       '#type' => 'details',
       '#title' => t('Pages'),
       '#collapsed' => TRUE,
@@ -290,11 +311,11 @@ public function form($form, &$form_state) {
     $visibility = $entity->get('visibility');
     $access = user_access('use PHP for settings');
     if (!empty($visibility['path']['visibility']) && $visibility['path']['visibility'] == BLOCK_VISIBILITY_PHP && !$access) {
-      $form['visibility']['path']['visibility'] = array(
+      $form['display']['visibility']['path']['visibility'] = array(
         '#type' => 'value',
         '#value' => BLOCK_VISIBILITY_PHP,
       );
-      $form['visibility']['path']['pages'] = array(
+      $form['display']['visibility']['path']['pages'] = array(
         '#type' => 'value',
         '#value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '',
       );
@@ -314,13 +335,13 @@ public function form($form, &$form_state) {
       else {
         $title = t('Pages');
       }
-      $form['visibility']['path']['visibility'] = array(
+      $form['display']['visibility']['path']['visibility'] = array(
         '#type' => 'radios',
         '#title' => t('Show block on specific pages'),
         '#options' => $options,
         '#default_value' => !empty($visibility['path']['visibility']) ? $visibility['path']['visibility'] : BLOCK_VISIBILITY_NOTLISTED,
       );
-      $form['visibility']['path']['pages'] = array(
+      $form['display']['visibility']['path']['pages'] = array(
         '#type' => 'textarea',
         '#title' => '<span class="element-invisible">' . $title . '</span>',
         '#default_value' => !empty($visibility['path']['pages']) ? $visibility['path']['pages'] : '',
@@ -339,7 +360,7 @@ public function form($form, &$form_state) {
         //   by CMI translation implementation.
         $langcodes_options[$language->langcode] = $language->name;
       }
-      $form['visibility']['language'] = array(
+      $form['display']['visibility']['language'] = array(
         '#type' => 'details',
         '#title' => t('Languages'),
         '#collapsed' => TRUE,
@@ -354,14 +375,14 @@ public function form($form, &$form_state) {
       foreach ($configurable_language_types as $type_key) {
         $language_type_options[$type_key] = $language_types[$type_key]['name'];
       }
-      $form['visibility']['language']['language_type'] = array(
+      $form['display']['visibility']['language']['language_type'] = array(
         '#type' => 'radios',
         '#title' => t('Language type'),
         '#options' => $language_type_options,
         '#default_value' => !empty($visibility['language']['language_type']) ? $visibility['language']['language_type'] : $configurable_language_types[0],
         '#access' => count($language_type_options) > 1,
       );
-      $form['visibility']['language']['langcodes'] = array(
+      $form['display']['visibility']['language']['langcodes'] = array(
         '#type' => 'checkboxes',
         '#title' => t('Show this block only for specific languages'),
         '#default_value' => !empty($visibility['language']['langcodes']) ? $visibility['language']['langcodes'] : array(),
@@ -372,14 +393,14 @@ public function form($form, &$form_state) {
 
     // Per-role visibility.
     $role_options = array_map('check_plain', user_role_names());
-    $form['visibility']['role'] = array(
+    $form['display']['visibility']['role'] = array(
       '#type' => 'details',
       '#title' => t('Roles'),
       '#collapsed' => TRUE,
       '#group' => 'visibility',
       '#weight' => 10,
     );
-    $form['visibility']['role']['roles'] = array(
+    $form['display']['visibility']['role']['roles'] = array(
       '#type' => 'checkboxes',
       '#title' => t('Show block for specific roles'),
       '#default_value' => !empty($visibility['role']['roles']) ? $visibility['role']['roles'] : array(),
@@ -388,7 +409,7 @@ public function form($form, &$form_state) {
     );
 
     // Add plugin-specific settings for this block type.
-    $form['settings'] = $this->blockForm(array(), $form_state);
+    $this->blockForm($form, $form_state);
     return $form;
   }
 
@@ -403,14 +424,9 @@ public function form($form, &$form_state) {
    * @param array $form_state
    *   An array containing the current state of the configuration form.
    *
-   * @return array $form
-   *   The renderable form array representing the entire configuration form.
-   *
    * @see \Drupal\block\BlockBase::form()
    */
-  public function blockForm($form, &$form_state) {
-    return array();
-  }
+  public function blockForm(&$form, &$form_state) {}
 
   /**
    * Implements \Drupal\block\BlockInterface::validate().
diff --git a/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php b/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php
index bbce85c..f0cb782 100644
--- a/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php
+++ b/core/modules/book/lib/Drupal/book/Plugin/block/block/BookNavigationBlock.php
@@ -35,20 +35,18 @@ public function settings() {
   /**
    * Overrides \Drupal\block\BlockBase::blockForm()
    */
-  function blockForm($form, &$form_state) {
+  function blockForm(&$form, &$form_state) {
     $options = array(
       'all pages' => t('Show block on all pages'),
       'book pages' => t('Show block only on book pages'),
     );
-    $form['book_block_mode'] = array(
+    $form['basic']['book_block_mode'] = array(
       '#type' => 'radios',
       '#title' => t('Book navigation block display'),
       '#options' => $options,
       '#default_value' => $this->configuration['block_mode'],
       '#description' => t("If <em>Show block on all pages</em> is selected, the block will contain the automatically generated menus for all of the site's books. If <em>Show block only on book pages</em> is selected, the block will contain only the one menu corresponding to the current page's book. In this case, if the current page is not in a book, no block will be displayed. The <em>Page specific visibility settings</em> or other visibility settings can be used in addition to selectively display this block."),
-      );
-
-    return $form;
+    );
   }
 
   /**
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/block/block/RecentCommentsBlock.php b/core/modules/comment/lib/Drupal/comment/Plugin/block/block/RecentCommentsBlock.php
index 7920a68..4be715b 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/block/block/RecentCommentsBlock.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/block/block/RecentCommentsBlock.php
@@ -41,14 +41,13 @@ public function blockAccess() {
   /**
    * Overrides \Drupal\block\BlockBase::blockForm().
    */
-  public function blockForm($form, &$form_state) {
-    $form['block_count'] = array(
+  public function blockForm(&$form, &$form_state) {
+    $form['basic']['block_count'] = array(
       '#type' => 'select',
       '#title' => t('Number of recent comments'),
       '#default_value' => $this->configuration['block_count'],
       '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30)),
     );
-    return $form;
   }
 
   /**
diff --git a/core/modules/forum/lib/Drupal/forum/Plugin/block/block/ForumBlockBase.php b/core/modules/forum/lib/Drupal/forum/Plugin/block/block/ForumBlockBase.php
index 1ff05f3..335f39a 100644
--- a/core/modules/forum/lib/Drupal/forum/Plugin/block/block/ForumBlockBase.php
+++ b/core/modules/forum/lib/Drupal/forum/Plugin/block/block/ForumBlockBase.php
@@ -37,14 +37,13 @@ public function blockAccess() {
   /**
    * Overrides \Drupal\block\BlockBase::blockForm().
    */
-  public function blockForm($form, &$form_state) {
-    $form['block_count'] = array(
+  public function blockForm(&$form, &$form_state) {
+    $form['basic']['block_count'] = array(
       '#type' => 'select',
       '#title' => t('Number of topics'),
       '#default_value' => $this->configuration['block_count'],
       '#options' => drupal_map_assoc(range(2, 20)),
     );
-    return $form;
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Plugin/block/block/RecentContentBlock.php b/core/modules/node/lib/Drupal/node/Plugin/block/block/RecentContentBlock.php
index 03c3c43..56f7ace 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/block/block/RecentContentBlock.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/block/block/RecentContentBlock.php
@@ -41,14 +41,13 @@ public function blockAccess() {
   /**
    * Overrides \Drupal\block\BlockBase::blockForm().
    */
-  public function blockForm($form, &$form_state) {
-    $form['block_count'] = array(
+  public function blockForm(&$form, &$form_state) {
+    $form['basic']]'block_count'] = array(
       '#type' => 'select',
       '#title' => t('Number of recent content items to display'),
       '#default_value' => $this->configuration['block_count'],
       '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30)),
     );
-    return $form;
   }
 
   /**
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 4be9596..a24b9e2 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -2011,14 +2011,14 @@ function theme_node_recent_content($variables) {
 function node_form_block_form_alter(&$form, &$form_state) {
   $block = $form_state['entity'];
   $visibility = $block->get('visibility');
-  $form['visibility']['node_type'] = array(
+  $form['display']['visibility']['node_type'] = array(
     '#type' => 'details',
     '#title' => t('Content types'),
     '#collapsed' => TRUE,
     '#group' => 'visibility',
     '#weight' => 5,
   );
-  $form['visibility']['node_type']['types'] = array(
+  $form['display']['visibility']['node_type']['types'] = array(
     '#type' => 'checkboxes',
     '#title' => t('Show block for specific content types'),
     '#default_value' => !empty($visibility['node_type']['types']) ? $visibility['node_type']['types'] : array(),
diff --git a/core/modules/statistics/lib/Drupal/statistics/Plugin/block/block/StatisticsPopularBlock.php b/core/modules/statistics/lib/Drupal/statistics/Plugin/block/block/StatisticsPopularBlock.php
index a10f45c..dce77ea 100644
--- a/core/modules/statistics/lib/Drupal/statistics/Plugin/block/block/StatisticsPopularBlock.php
+++ b/core/modules/statistics/lib/Drupal/statistics/Plugin/block/block/StatisticsPopularBlock.php
@@ -79,31 +79,30 @@ public function blockAccess() {
   /**
    * Overrides \Drupal\block\BlockBase::blockForm().
    */
-  public function blockForm($form, &$form_state) {
+  public function blockForm(&$form, &$form_state) {
     // Popular content block settings.
     $numbers = array('0' => t('Disabled')) + drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40));
-    $form['statistics_block_top_day_num'] = array(
+    $form['basic']['statistics_block_top_day_num'] = array(
      '#type' => 'select',
      '#title' => t("Number of day's top views to display"),
      '#default_value' => $this->configuration['top_day_num'],
      '#options' => $numbers,
      '#description' => t('How many content items to display in "day" list.'),
     );
-    $form['statistics_block_top_all_num'] = array(
+    $form['basic']['statistics_block_top_all_num'] = array(
       '#type' => 'select',
       '#title' => t('Number of all time views to display'),
       '#default_value' => $this->configuration['top_all_num'],
       '#options' => $numbers,
       '#description' => t('How many content items to display in "all time" list.'),
     );
-    $form['statistics_block_top_last_num'] = array(
+    $form['basic']['statistics_block_top_last_num'] = array(
       '#type' => 'select',
       '#title' => t('Number of most recent views to display'),
       '#default_value' => $this->configuration['top_last_num'],
       '#options' => $numbers,
       '#description' => t('How many content items to display in "recently viewed" list.'),
     );
-    return $form;
   }
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/Plugin/block/block/UserOnlineBlock.php b/core/modules/user/lib/Drupal/user/Plugin/block/block/UserOnlineBlock.php
index 6a9fb68..ea71031 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/block/block/UserOnlineBlock.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/block/block/UserOnlineBlock.php
@@ -48,23 +48,22 @@ public function blockAccess() {
   /**
    * Overrides \Drupal\block\BlockBase::blockForm().
    */
-  public function blockForm($form, &$form_state) {
+  public function blockForm(&$form, &$form_state) {
     $period = drupal_map_assoc(array(30, 60, 120, 180, 300, 600, 900, 1800, 2700, 3600, 5400, 7200, 10800, 21600, 43200, 86400), 'format_interval');
-    $form['user_block_seconds_online'] = array(
+    $form['basic']['user_block_seconds_online'] = array(
       '#type' => 'select',
       '#title' => t('User activity'),
       '#default_value' => $this->configuration['seconds_online'],
       '#options' => $period,
       '#description' => t('A user is considered online for this long after they have last viewed a page.')
     );
-    $form['user_block_max_list_count'] = array(
+    $form['basic']['user_block_max_list_count'] = array(
       '#type' => 'select',
       '#title' => t('User list length'),
       '#default_value' => $this->configuration['max_list_count'],
       '#options' => drupal_map_assoc(array(0, 5, 10, 15, 20, 25, 30, 40, 50, 75, 100)),
       '#description' => t('Maximum number of currently online users to display.')
     );
-    return $form;
   }
 
   /**
diff --git a/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php
index 7cac4f6..42a336b 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php
@@ -66,8 +66,8 @@ public function form($form, &$form_state) {
     $form = parent::form($form, $form_state);
 
     // Set the default label to '' so the views internal title is used.
-    $form['label']['#default_value'] = '';
-    $form['label']['#access'] = FALSE;
+    $form['basic']['label']['#default_value'] = '';
+    $form['basic']['label']['#access'] = FALSE;
     return $form;
   }
 
