diff --git a/core/misc/vertical-tabs.js b/core/misc/vertical-tabs.js
index 3b628bf2fba20b333c41373db3c0ee9965eb014c..9d2e955fc828e04bc7f655bddcbbbaa308171d82 100644
--- a/core/misc/vertical-tabs.js
+++ b/core/misc/vertical-tabs.js
@@ -85,8 +85,13 @@
           $details.each(function () {
             const $that = $(this);
             const $summary = $that.find('> summary');
+            // Summary elements often have 2 child nodes: a text title and a
+            // dynamic summary wrapped in <span>. To set the vertical tab title,
+            // we only want to copy the summary title, which is the first child
+            // node.
+            const title = $summary[0]?.firstChild?.textContent || '';
             const verticalTab = new Drupal.verticalTab({
-              title: $summary.length ? $summary[0].textContent : '',
+              title,
               details: $that,
             });
             tabList.append(verticalTab.item);
diff --git a/core/modules/system/tests/modules/form_test/form_test.libraries.yml b/core/modules/system/tests/modules/form_test/form_test.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9c0d8d756b4182165a6f724cfd59a93cf51daa25
--- /dev/null
+++ b/core/modules/system/tests/modules/form_test/form_test.libraries.yml
@@ -0,0 +1,10 @@
+form_test:
+  version: VERSION
+  js:
+    # Weight is set to a negative number to ensure that details summaries
+    # are loaded before vertical-tabs.js to simulate what happens on
+    # entity forms.
+    js/form_test.js: { weight: -1 }
+  dependencies:
+    - core/jquery
+    - core/drupal
diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml
index 3aa58524b7126382a7229067c92b1284a093cb17..b4ead833a4d1ac725bd01ad01eada4b8581eecc0 100644
--- a/core/modules/system/tests/modules/form_test/form_test.routing.yml
+++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml
@@ -180,6 +180,14 @@ form_test.vertical_tabs:
   requirements:
     _access: 'TRUE'
 
+form_test.vertical_tabs_with_summary:
+  path: '/form_test/vertical-tabs-with-summary'
+  defaults:
+    _form: '\Drupal\form_test\Form\FormTestVerticalTabsWithSummaryForm'
+    _title: 'Vertical tabs with Summary tests'
+  requirements:
+    _access: 'TRUE'
+
 form_test.storage:
   path: '/form_test/form-storage'
   defaults:
diff --git a/core/modules/system/tests/modules/form_test/js/form_test.js b/core/modules/system/tests/modules/form_test/js/form_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..08fab640b33f4eff42d05fb0c2217a9275a8e1c6
--- /dev/null
+++ b/core/modules/system/tests/modules/form_test/js/form_test.js
@@ -0,0 +1,28 @@
+/**
+ * @file
+ * Attaches behaviors for the form_test module.
+ */
+(function ($, Drupal) {
+  /**
+   * Behavior for setting dynamic summaries.
+   *
+   * @type {Drupal~behavior}
+   *
+   * @prop {Drupal~behaviorAttach} attach
+   *   Attaches summary behavior on path edit forms.
+   */
+  Drupal.behaviors.formTestVerticalTabsSummary = {
+    attach(context) {
+      $(context)
+        .find('[data-drupal-selector="edit-tab1"]')
+        .drupalSetSummary((context) => {
+          return 'Summary 1';
+        });
+      $(context)
+        .find('[data-drupal-selector="edit-tab2"]')
+        .drupalSetSummary((context) => {
+          return 'Summary 2';
+        });
+    },
+  };
+})(jQuery, Drupal);
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsWithSummaryForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsWithSummaryForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..30080340fad6b3b73201dbdd14dc6316d84cc987
--- /dev/null
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsWithSummaryForm.php
@@ -0,0 +1,72 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\form_test\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Builds a simple form to test vertical-tabs form element with tab summaries.
+ *
+ * @internal
+ */
+class FormTestVerticalTabsWithSummaryForm extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return '_form_test_vertical_tabs_with_summary_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+
+    $form['information'] = [
+      '#type' => 'vertical_tabs',
+      '#default_tab' => 'edit-tab1',
+    ];
+    $form['tab1'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Tab 1'),
+      '#group' => 'information',
+    ];
+    $form['tab1']['field1'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Field 1'),
+    ];
+    $form['tab2'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Tab 2'),
+      '#group' => 'information',
+    ];
+    $form['tab2']['field2'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Field 2'),
+    ];
+
+    $form['actions']['#type'] = 'actions';
+    $form['actions']['submit'] = [
+      '#type' => 'submit',
+      '#value' => $this->t('Save'),
+      '#button_type' => 'primary',
+    ];
+
+    // Attach the library that sets the vertical tab summaries.
+    $form['#attached']['library'][] = 'form_test/form_test';
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state): void {
+    $this->messenger()->addStatus($this->t('Form submitted.'));
+  }
+
+}
diff --git a/core/modules/system/tests/src/FunctionalJavascript/Form/ElementsVerticalTabsWithSummaryTest.php b/core/modules/system/tests/src/FunctionalJavascript/Form/ElementsVerticalTabsWithSummaryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..376a9f96170cb895857c43f90b60130ec85e0149
--- /dev/null
+++ b/core/modules/system/tests/src/FunctionalJavascript/Form/ElementsVerticalTabsWithSummaryTest.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\system\FunctionalJavascript\Form;
+
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+
+/**
+ * Tests that titles and summaries in vertical-tabs form elements are set correctly.
+ *
+ * @group Form
+ */
+class ElementsVerticalTabsWithSummaryTest extends WebDriverTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['form_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * Check that vertical tabs title and summaries are set correctly.
+   */
+  public function testDynamicSummary(): void {
+    $this->drupalGet('form_test/vertical-tabs-with-summary');
+    $this->assertSession()->elementTextEquals('css', '.vertical-tabs__menu-item.first .vertical-tabs__menu-item-title', 'Tab 1');
+    $this->assertSession()->elementTextEquals('css', '.vertical-tabs__menu-item.first .vertical-tabs__menu-item-summary', 'Summary 1');
+    $this->assertSession()->elementTextEquals('css', '.vertical-tabs__menu-item.last .vertical-tabs__menu-item-title', 'Tab 2');
+    $this->assertSession()->elementTextEquals('css', '.vertical-tabs__menu-item.last .vertical-tabs__menu-item-summary', 'Summary 2');
+  }
+
+}