diff --git a/core/includes/form.inc b/core/includes/form.inc
index a855434e31fd9b66117d498b953965e40ca1a66f..75072346624df2f402b24930a9fe1417f6c22348 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -3994,6 +3994,14 @@ function form_process_vertical_tabs($element, &$form_state) {
     '#parents' => $element['#parents'],
   );
 
+  // Add an invisible label for accessibility.
+  if (!isset($element['#title'])) {
+    $element['#title'] = t('Vertical Tabs');
+    $element['#title_display'] = 'invisible';
+  }
+
+  $element['#attached']['library'][] = array('system', 'drupal.vertical-tabs');
+
   // The JavaScript stores the currently selected tab in this hidden
   // field so that the active tab can be restored the next time the
   // form is rendered, e.g. on preview pages or when form validation
@@ -4011,6 +4019,25 @@ function form_process_vertical_tabs($element, &$form_state) {
   return $element;
 }
 
+/**
+ * Prepares a vertical_tabs element for rendering.
+ *
+ * @param array $element
+ *   An associative array containing the properties and children of the
+ *   vertical tabs element.
+ *
+ * @return array
+ *   The modified element.
+ */
+function form_pre_render_vertical_tabs($element) {
+  // Do not render the vertical tabs element if it is empty.
+  $group = implode('][', $element['#parents']);
+  if (!element_get_visible_children($element['group']['#groups'][$group])) {
+    $element['#printed'] = TRUE;
+  }
+  return $element;
+}
+
 /**
  * Returns HTML for an element's children details as vertical tabs.
  *
@@ -4023,26 +4050,7 @@ function form_process_vertical_tabs($element, &$form_state) {
  */
 function theme_vertical_tabs($variables) {
   $element = $variables['element'];
-  // Even if there are no tabs the element will still have a child element for
-  // the active tab. We need to iterate over the tabs to ascertain if any
-  // are visible before showing the wrapper and h2.
-  $visible_tab = FALSE;
-  $output = '';
-  foreach (element_children($element['group']) as $tab_index) {
-    if (!isset($element['group'][$tab_index]['#access']) ||
-        !empty($element['group'][$tab_index]['#access'])) {
-      $visible_tab = TRUE;
-      break;
-    }
-  }
-  if ($visible_tab) {
-    // Add required JavaScript and Stylesheet.
-    drupal_add_library('system', 'drupal.vertical-tabs');
-
-    $output = '<h2 class="element-invisible">' . t('Vertical Tabs') . '</h2>';
-    $output .= '<div class="vertical-tabs-panes">' . $element['#children'] . '</div>';
-  }
-  return $output;
+  return '<div class="vertical-tabs-panes">' . $element['#children'] . '</div>';
 }
 
 /**
diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php
index b8f770d242ee96b4639d643502d162e6b578d2b2..7d1356bcd54acbbd7c6d94f8a9cb80d0902001ba 100644
--- a/core/modules/block/lib/Drupal/block/BlockBase.php
+++ b/core/modules/block/lib/Drupal/block/BlockBase.php
@@ -287,18 +287,14 @@ public function form($form, &$form_state) {
 
 
     // Visibility settings.
-    $form['visibility_title'] = array(
-      '#type' => 'item',
-      '#title' => t('Visibility settings'),
-      '#weight' => 10,
-    );
     $form['visibility'] = array(
       '#type' => 'vertical_tabs',
+      '#title' => t('Visibility settings'),
       '#attached' => array(
         'js' => array(drupal_get_path('module', 'block') . '/block.js'),
       ),
       '#tree' => TRUE,
-      '#weight' => 15,
+      '#weight' => 10,
     );
 
     // Per-path visibility.
diff --git a/core/modules/filter/filter.admin.inc b/core/modules/filter/filter.admin.inc
index e06719952dc169c43f0f54f03a39373891b489f8..3c01ac2ed22bffa9e4167c0aedc5185a5b563492 100644
--- a/core/modules/filter/filter.admin.inc
+++ b/core/modules/filter/filter.admin.inc
@@ -247,12 +247,9 @@ function filter_admin_format_form($form, &$form_state, $format) {
   }
 
   // Filter settings.
-  $form['filter_settings_title'] = array(
-    '#type' => 'item',
-    '#title' => t('Filter settings'),
-  );
   $form['filter_settings'] = array(
     '#type' => 'vertical_tabs',
+    '#title' => t('Filter settings'),
   );
 
   foreach ($filter_info as $name => $filter) {
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 2d665bba66e1d50cb42b68016205dcac857988b1..e80a7df46bdbfe4183dfbb432c84f9d307ed5cba 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -557,7 +557,8 @@ function system_element_info() {
   $types['vertical_tabs'] = array(
     '#default_tab' => '',
     '#process' => array('form_process_vertical_tabs'),
-    '#theme_wrappers' => array('vertical_tabs'),
+    '#pre_render' => array('form_pre_render_vertical_tabs'),
+    '#theme_wrappers' => array('vertical_tabs', 'form_element'),
   );
   $types['dropbutton'] = array(
     '#pre_render' => array('drupal_pre_render_dropbutton'),
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index dcd76d7898802e9b70e4219a79f5ca5735eb94e8..1689f6210b0f3709a182f3621060eb85b42d9ec3 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -389,12 +389,9 @@ function user_admin_settings($form, &$form_state) {
     '#default_value' => $config->get('signatures'),
   );
 
-  $form['email_title'] = array(
-    '#type' => 'item',
-    '#title' => t('E-mails'),
-  );
   $form['email'] = array(
     '#type' => 'vertical_tabs',
+    '#title' => t('E-mails'),
   );
   // These email tokens are shared for all settings, so just define
   // the list once to help ensure they stay in sync.