diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index 6bccc054bc..13c19005ce 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -122,6 +122,7 @@ drupal.checkbox:
 drupal.collapse:
   version: VERSION
   js:
+    misc/details.js: {}
     misc/details-aria.js: {}
     misc/collapse.js: {}
   dependencies:
diff --git a/core/misc/collapse.es6.js b/core/misc/collapse.es6.js
index 52fd244bc1..a0eb2edae8 100644
--- a/core/misc/collapse.es6.js
+++ b/core/misc/collapse.es6.js
@@ -24,10 +24,8 @@
     if (this.$node.find(`.error${anchor}`).length) {
       this.$node.attr('open', true);
     }
-    // Initialize and setup the summary,
-    this.setupSummary();
-    // Initialize and setup the legend.
-    this.setupLegend();
+    // Initialize and set up the summary polyfill.
+    this.setupSummaryPolyfill();
   }
 
   $.extend(
@@ -46,61 +44,39 @@
     CollapsibleDetails.prototype,
     /** @lends Drupal.CollapsibleDetails# */ {
       /**
-       * Initialize and setup summary events and markup.
-       *
-       * @fires event:summaryUpdated
-       *
-       * @listens event:summaryUpdated
-       */
-      setupSummary() {
-        this.$summary = $('<span class="summary"></span>');
-        this.$node
-          .on('summaryUpdated', $.proxy(this.onSummaryUpdated, this))
-          .trigger('summaryUpdated');
-      },
-
-      /**
-       * Initialize and setup legend markup.
+       * Initialize and setup summary markup.
        */
-      setupLegend() {
+      setupSummaryPolyfill() {
         // Turn the summary into a clickable link.
-        const $legend = this.$node.find('> summary');
+        const $summary = this.$node.find('> summary');
 
         $('<span class="details-summary-prefix visually-hidden"></span>')
           .append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show'))
-          .prependTo($legend)
+          .prependTo($summary)
           .after(document.createTextNode(' '));
 
         // .wrapInner() does not retain bound events.
         $('<a class="details-title"></a>')
           .attr('href', `#${this.$node.attr('id')}`)
-          .prepend($legend.contents())
-          .appendTo($legend);
+          .prepend($summary.contents())
+          .appendTo($summary);
 
-        $legend
+        $summary
           .append(this.$summary)
-          .on('click', $.proxy(this.onLegendClick, this));
+          .on('click', $.proxy(this.onSummaryClick, this));
       },
 
       /**
-       * Handle legend clicks.
+       * Handle summary clicks.
        *
        * @param {jQuery.Event} e
        *   The event triggered.
        */
-      onLegendClick(e) {
+      onSummaryClick(e) {
         this.toggle();
         e.preventDefault();
       },
 
-      /**
-       * Update summary.
-       */
-      onSummaryUpdated() {
-        const text = $.trim(this.$node.drupalGetSummary());
-        this.$summary.html(text ? ` (${text})` : '');
-      },
-
       /**
        * Toggle the visibility of a details element using smooth animations.
        */
diff --git a/core/misc/collapse.js b/core/misc/collapse.js
index bf312b97ce..c2cddeef54 100644
--- a/core/misc/collapse.js
+++ b/core/misc/collapse.js
@@ -15,32 +15,23 @@
       this.$node.attr('open', true);
     }
 
-    this.setupSummary();
-    this.setupLegend();
+    this.setupSummaryPolyfill();
   }
 
   $.extend(CollapsibleDetails, {
     instances: []
   });
   $.extend(CollapsibleDetails.prototype, {
-    setupSummary: function setupSummary() {
-      this.$summary = $('<span class="summary"></span>');
-      this.$node.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)).trigger('summaryUpdated');
+    setupSummaryPolyfill: function setupSummaryPolyfill() {
+      var $summary = this.$node.find('> summary');
+      $('<span class="details-summary-prefix visually-hidden"></span>').append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show')).prependTo($summary).after(document.createTextNode(' '));
+      $('<a class="details-title"></a>').attr('href', "#".concat(this.$node.attr('id'))).prepend($summary.contents()).appendTo($summary);
+      $summary.append(this.$summary).on('click', $.proxy(this.onSummaryClick, this));
     },
-    setupLegend: function setupLegend() {
-      var $legend = this.$node.find('> summary');
-      $('<span class="details-summary-prefix visually-hidden"></span>').append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show')).prependTo($legend).after(document.createTextNode(' '));
-      $('<a class="details-title"></a>').attr('href', "#".concat(this.$node.attr('id'))).prepend($legend.contents()).appendTo($legend);
-      $legend.append(this.$summary).on('click', $.proxy(this.onLegendClick, this));
-    },
-    onLegendClick: function onLegendClick(e) {
+    onSummaryClick: function onSummaryClick(e) {
       this.toggle();
       e.preventDefault();
     },
-    onSummaryUpdated: function onSummaryUpdated() {
-      var text = $.trim(this.$node.drupalGetSummary());
-      this.$summary.html(text ? " (".concat(text, ")") : '');
-    },
     toggle: function toggle() {
       var _this = this;
 
diff --git a/core/misc/details.es6.js b/core/misc/details.es6.js
new file mode 100644
index 0000000000..3dafad664c
--- /dev/null
+++ b/core/misc/details.es6.js
@@ -0,0 +1,109 @@
+/**
+ * @file
+ * Additional functionality for details elements.
+ */
+(($, Drupal) => {
+  /**
+   * The DetailsEnhanced object represents a single details element.
+   *
+   * @constructor Drupal.DetailsEnhanced
+   *
+   * @param {HTMLElement} node
+   *   The details element with enhanced functionality.
+   */
+  function DetailsEnhanced(node) {
+    this.$node = $(node);
+    this.setupSummary();
+  }
+
+  $.extend(
+    DetailsEnhanced,
+    /** @lends Drupal.DetailsEnhanced */ {
+      /**
+       * Holds references to instantiated DetailsEnhanced objects.
+       *
+       * @type {Array.<Drupal.DetailsEnhanced>}
+       */
+      instances: [],
+    },
+  );
+
+  $.extend(
+    DetailsEnhanced.prototype,
+    /** @lends Drupal.DetailsEnhanced# */ {
+      /**
+       * Initialize and setup summary events and markup.
+       *
+       * @fires event:summaryUpdated
+       *
+       * @listens event:summaryUpdated
+       */
+      setupSummary() {
+        this.$summarySupplementalContent = $(
+          Drupal.theme('summarySupplementalContent'),
+        );
+        this.$node
+          .on('summaryUpdated', $.proxy(this.onSummaryUpdated, this))
+          .trigger('summaryUpdated')
+          .find('> summary')
+          .append(this.$summarySupplementalContent);
+      },
+
+      /**
+       * Update summary.
+       */
+      onSummaryUpdated() {
+        const text = $.trim(this.$node.drupalGetSummary());
+        this.$summarySupplementalContent.html(
+          Drupal.theme('summarySupplementalContentText', text),
+        );
+      },
+    },
+  );
+
+  /**
+   * Extends functionality of a details element.
+   *
+   * @type {Drupal~behavior}
+   *
+   * @prop {Drupal~behaviorAttach} attach
+   *   Attaches behavior for the details element.
+   */
+  Drupal.behaviors.detailsSummary = {
+    attach(context) {
+      const $detailsElements = $(context)
+        .find('details')
+        .once('details');
+      if ($detailsElements.length) {
+        for (let i = 0; i < $detailsElements.length; i++) {
+          Drupal.EnhancedDetailsElements.instances.push(
+            new DetailsEnhanced($detailsElements[i]),
+          );
+        }
+      }
+    },
+  };
+
+  /**
+   * The element containing a summary's supplemental text.
+   *
+   * @return {string}
+   *   The markup for the element that will contain supplemental summary text.
+   */
+  Drupal.theme.summarySupplementalContent = () =>
+    `<span class="summary"></span>`;
+
+  /**
+   * Formats a summary's supplemental text.
+   *
+   * @param {string|null} [text]
+   *   (optional) The additional text displayed by the summary.
+   * @return {string}
+   *   The formatted text that will be appended to the summary element.
+   */
+  Drupal.theme.summarySupplementalContentText = text =>
+    text ? ` (${text})` : '';
+
+  // Expose constructor in the public space.
+  Drupal.EnhancedDetailsElements = DetailsEnhanced;
+})(jQuery, Drupal);
diff --git a/core/misc/details.js b/core/misc/details.js
new file mode 100644
index 0000000000..a080141a4c
--- /dev/null
+++ b/core/misc/details.js
@@ -0,0 +1,48 @@
+/**
+* DO NOT EDIT THIS FILE.
+* See the following change record for more information,
+* https://www.drupal.org/node/2815083
+* @preserve
+**/
+
+(function ($, Drupal) {
+  function DetailsEnhanced(node) {
+    this.$node = $(node);
+    this.setupSummary();
+  }
+
+  $.extend(DetailsEnhanced, {
+    instances: []
+  });
+  $.extend(DetailsEnhanced.prototype, {
+    setupSummary: function setupSummary() {
+      this.$summarySupplementalContent = $(Drupal.theme('summarySupplementalContent'));
+      this.$node.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)).trigger('summaryUpdated').find('> summary').append(this.$summarySupplementalContent);
+    },
+    onSummaryUpdated: function onSummaryUpdated() {
+      var text = $.trim(this.$node.drupalGetSummary());
+      this.$summarySupplementalContent.html(Drupal.theme('summarySupplementalContentText', text));
+    }
+  });
+  Drupal.behaviors.detailsSummary = {
+    attach: function attach(context) {
+      var $detailsElements = $(context).find('details').once('details');
+
+      if ($detailsElements.length) {
+        for (var i = 0; i < $detailsElements.length; i++) {
+          Drupal.EnhancedDetailsElements.instances.push(new DetailsEnhanced($detailsElements[i]));
+        }
+      }
+    }
+  };
+
+  Drupal.theme.summarySupplementalContent = function () {
+    return "<span class=\"summary\"></span>";
+  };
+
+  Drupal.theme.summarySupplementalContentText = function (text) {
+    return text ? " (".concat(text, ")") : '';
+  };
+
+  Drupal.EnhancedDetailsElements = DetailsEnhanced;
+})(jQuery, Drupal);
\ No newline at end of file
diff --git a/core/modules/node/tests/src/FunctionalJavascript/CollapsedSummariesTest.php b/core/modules/node/tests/src/FunctionalJavascript/CollapsedSummariesTest.php
new file mode 100644
index 0000000000..1b1b743833
--- /dev/null
+++ b/core/modules/node/tests/src/FunctionalJavascript/CollapsedSummariesTest.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Drupal\Tests\node\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+
+/**
+ * Tests that summaries of form values are displayed on meta details elements.
+ *
+ * @group node
+ */
+class CollapsedSummariesTest extends WebDriverTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->drupalCreateContentType([
+      'type' => 'page',
+      'name' => 'Basic page',
+    ]);
+
+    $this->drupalCreateNode([
+      'title' => $this->randomMachineName(),
+      'type' => 'page',
+    ]);
+
+    $this->drupalLogin($this->createUser(['edit any page content']));
+  }
+
+  /**
+   * Confirm that summaries are provided for node meta at all widths.
+   */
+  public function testSummaries() {
+    $page = $this->getSession()->getPage();
+    $assert_session = $this->assertSession();
+
+    // At a wider width, vertical tabs are used for the meta section of the node
+    // form.
+    $this->getSession()->resizeWindow(1200, 1200);
+    $this->drupalGet('node/1/edit');
+
+    $assert_session->waitForText("New revision");
+    $summary = $assert_session->waitForElement('css', '.vertical-tabs__menu-item-summary');
+    $this->assertNotNull($summary);
+    $this->assertTrue($summary->isVisible());
+    $this->assertEquals('New revision', $summary->getText());
+    $page->uncheckField('revision');
+    $assert_session->waitForText('No revision');
+    $this->assertEquals('No revision', $summary->getText());
+
+    // At a narrower width, details are used for the meta section of the node
+    // form.
+    $this->getSession()->resizeWindow(600, 1200);
+    $this->drupalGet('node/1/edit');
+
+    $summary = $assert_session->waitForElement('css', 'span.summary');
+    $this->assertNotNull($summary);
+    $this->assertTrue($summary->isVisible());
+    $page->uncheckField('revision');
+    $assert_session->waitForText('No revision');
+    $this->assertEquals('(No revision)', $summary->getText());
+  }
+
+}
diff --git a/core/themes/claro/css/components/accordion.css b/core/themes/claro/css/components/accordion.css
index 80d41e2d0b..3a069534dc 100644
--- a/core/themes/claro/css/components/accordion.css
+++ b/core/themes/claro/css/components/accordion.css
@@ -89,14 +89,8 @@ rgba(0, 0, 0, 0.1);
   border-bottom-left-radius: 2px;
 }
 
-/**
- * Hide JS summary from the details polyfill to make it consistent with native
- * details elements.
- *
- * @todo Consider removing this after https://www.drupal.org/node/2493957 has
- *   been solved.
- */
-
 .accordion__item .claro-details__summary .summary {
-  display: none;
+  display: block;
+  color: var(--color-davysgrey);
+  font-weight: normal;
 }
diff --git a/core/themes/claro/css/components/accordion.pcss.css b/core/themes/claro/css/components/accordion.pcss.css
index 57961a20db..9e43fdd2d2 100644
--- a/core/themes/claro/css/components/accordion.pcss.css
+++ b/core/themes/claro/css/components/accordion.pcss.css
@@ -34,13 +34,8 @@
   border-bottom-left-radius: var(--details-accordion-border-size-radius);
 }
 
-/**
- * Hide JS summary from the details polyfill to make it consistent with native
- * details elements.
- *
- * @todo Consider removing this after https://www.drupal.org/node/2493957 has
- *   been solved.
- */
 .accordion__item .claro-details__summary .summary {
-  display: none;
+  display: block;
+  color: var(--color-davysgrey);
+  font-weight: normal;
 }
diff --git a/core/themes/claro/css/components/details.css b/core/themes/claro/css/components/details.css
index 844fa7b870..61d37232ee 100644
--- a/core/themes/claro/css/components/details.css
+++ b/core/themes/claro/css/components/details.css
@@ -597,18 +597,11 @@ rgba(0, 0, 0, 0.1);
   border-bottom-left-radius: 0;
 }
 
-/**
- * Hide JS summary from the details polyfill to make it consistent with native
- * details elements.
- *
- * @todo Consider removing this after https://www.drupal.org/node/2493957 has
- * been solved.
- */
-
-.claro-details__summary--accordion .summary,
-.claro-details__summary--accordion-item .summary,
-.claro-details__summary--vertical-tabs-item .summary {
-  display: none;
+.claro-details__summary-summary {
+  display: block;
+  color: var(--color-davysgrey);
+  font-size: 0.889rem;
+  font-weight: normal;
 }
 
 @media screen and (-ms-high-contrast: active) {
diff --git a/core/themes/claro/css/components/details.pcss.css b/core/themes/claro/css/components/details.pcss.css
index 2dcd6df22a..5fc2324fc8 100644
--- a/core/themes/claro/css/components/details.pcss.css
+++ b/core/themes/claro/css/components/details.pcss.css
@@ -523,17 +523,11 @@
   border-bottom-left-radius: 0;
 }
 
-/**
- * Hide JS summary from the details polyfill to make it consistent with native
- * details elements.
- *
- * @todo Consider removing this after https://www.drupal.org/node/2493957 has
- * been solved.
- */
-.claro-details__summary--accordion .summary,
-.claro-details__summary--accordion-item .summary,
-.claro-details__summary--vertical-tabs-item .summary {
-  display: none;
+.claro-details__summary-summary {
+  display: block;
+  color: var(--color-davysgrey);
+  font-size: var(--font-size-s);
+  font-weight: normal;
 }
 
 @media screen and (-ms-high-contrast: active) {
diff --git a/core/themes/claro/css/components/vertical-tabs.css b/core/themes/claro/css/components/vertical-tabs.css
index 7e939da826..2e46e8942a 100644
--- a/core/themes/claro/css/components/vertical-tabs.css
+++ b/core/themes/claro/css/components/vertical-tabs.css
@@ -313,8 +313,7 @@ rgba(0, 0, 0, 0.1);
  * Details summary in vertical tabs menu link and in the summary of the details.
  */
 
-.vertical-tabs__menu-link-summary,
-.vertical-tabs__details-summary-summary {
+.vertical-tabs__menu-link-summary {
   display: block;
   color: #545560;
   font-size: 0.889rem;
diff --git a/core/themes/claro/css/components/vertical-tabs.pcss.css b/core/themes/claro/css/components/vertical-tabs.pcss.css
index 12ed6a8647..283cafaf6e 100644
--- a/core/themes/claro/css/components/vertical-tabs.pcss.css
+++ b/core/themes/claro/css/components/vertical-tabs.pcss.css
@@ -256,8 +256,7 @@
 /**
  * Details summary in vertical tabs menu link and in the summary of the details.
  */
-.vertical-tabs__menu-link-summary,
-.vertical-tabs__details-summary-summary {
+.vertical-tabs__menu-link-summary {
   display: block;
   color: var(--color-davysgray);
   font-size: var(--font-size-s);
diff --git a/core/themes/claro/js/details.es6.js b/core/themes/claro/js/details.es6.js
index f7ad00e25e..ff25f0453c 100644
--- a/core/themes/claro/js/details.es6.js
+++ b/core/themes/claro/js/details.es6.js
@@ -55,4 +55,23 @@
         });
     },
   };
+
+  /**
+   * Theme override of element containing supplemental summary text.
+   *
+   * @return {string}
+   *   The markup for the element that will contain supplemental summary text.
+   */
+  Drupal.theme.detailsSummarySummary = () =>
+    `<span class="claro-details__summary-summary"></span>`;
+
+  /**
+   * Theme override of supplemental summary text.
+   *
+   * @param {string|null} [text]
+   *   (optional) The additional text displayed by the summary.
+   * @return {string}
+   *   The formatted text that will be appended to the summary element.
+   */
+  Drupal.theme.detailsSummarySummaryText = text => text || '';
 })(jQuery, Modernizr, Drupal);
diff --git a/core/themes/claro/js/details.js b/core/themes/claro/js/details.js
index 24630f200a..bb9462446c 100644
--- a/core/themes/claro/js/details.js
+++ b/core/themes/claro/js/details.js
@@ -31,4 +31,12 @@
       });
     }
   };
+
+  Drupal.theme.detailsSummarySummary = function () {
+    return "<span class=\"claro-details__summary-summary\"></span>";
+  };
+
+  Drupal.theme.detailsSummarySummaryText = function (text) {
+    return text || '';
+  };
 })(jQuery, Modernizr, Drupal);
\ No newline at end of file
diff --git a/core/themes/claro/js/vertical-tabs.es6.js b/core/themes/claro/js/vertical-tabs.es6.js
index 7547917152..adee64487d 100644
--- a/core/themes/claro/js/vertical-tabs.es6.js
+++ b/core/themes/claro/js/vertical-tabs.es6.js
@@ -194,10 +194,6 @@
 
     this.link.attr('href', `#${settings.details.attr('id')}`);
 
-    this.detailsSummaryDescription = $(
-      Drupal.theme.verticalTabDetailsDescription(),
-    ).appendTo(this.details.find('> summary'));
-
     this.link.on('click', event => {
       event.preventDefault();
       self.focus();
@@ -315,7 +311,6 @@
      */
     updateSummary() {
       const summary = this.details.drupalGetSummary();
-      this.detailsSummaryDescription.html(summary);
       this.summary.html(summary);
     },
 
@@ -450,15 +445,6 @@
   Drupal.theme.verticalTabListWrapper = () =>
     '<ul class="vertical-tabs__menu"></ul>';
 
-  /**
-   * The wrapper of the details summary message added to the summary element.
-   *
-   * @return {string}
-   *   A string representing the DOM fragment.
-   */
-  Drupal.theme.verticalTabDetailsDescription = () =>
-    '<span class="vertical-tabs__details-summary-summary"></span>';
-
   /**
    * Themes the active vertical tab menu item message.
    *
diff --git a/core/themes/claro/js/vertical-tabs.js b/core/themes/claro/js/vertical-tabs.js
index 57f420464d..8618af2d1e 100644
--- a/core/themes/claro/js/vertical-tabs.js
+++ b/core/themes/claro/js/vertical-tabs.js
@@ -63,7 +63,6 @@
     $.extend(this, settings, Drupal.theme('verticalTab', settings));
     this.item.addClass('js-vertical-tabs-menu-item');
     this.link.attr('href', "#".concat(settings.details.attr('id')));
-    this.detailsSummaryDescription = $(Drupal.theme.verticalTabDetailsDescription()).appendTo(this.details.find('> summary'));
     this.link.on('click', function (event) {
       event.preventDefault();
       self.focus();
@@ -133,7 +132,6 @@
     },
     updateSummary: function updateSummary() {
       var summary = this.details.drupalGetSummary();
-      this.detailsSummaryDescription.html(summary);
       this.summary.html(summary);
     },
     tabShow: function tabShow() {
@@ -176,10 +174,6 @@
     return '<ul class="vertical-tabs__menu"></ul>';
   };
 
-  Drupal.theme.verticalTabDetailsDescription = function () {
-    return '<span class="vertical-tabs__details-summary-summary"></span>';
-  };
-
   Drupal.theme.verticalTabActiveTabIndicator = function () {
     return "<span class=\"visually-hidden\">".concat(Drupal.t('(active tab)'), "</span>");
   };
diff --git a/core/themes/seven/css/base/elements.css b/core/themes/seven/css/base/elements.css
index 53cba224c6..4da963a391 100644
--- a/core/themes/seven/css/base/elements.css
+++ b/core/themes/seven/css/base/elements.css
@@ -161,16 +161,18 @@ details summary {
   padding: 0.95em 1.45em;
 }
 details summary:focus {
-  text-decoration: underline;
   outline: none;
 }
 /**
  * Unfortunately, text-decoration for details summary is not supported on all
  * browsers. So we add a span (which can handle text-decoration) in Seven's
  * templates/details.html.twig. In case there are other details templates that
- * don't have the span, we leave the text-decoration in the parent selector.
+ * don't have the span, we provide text-decoration in the parent selector.
  * This provides maximum compatibility and coverage with minimal disruption.
  */
+details summary:not(.seven-details__summary):focus {
+  text-decoration: underline;
+}
 details summary:focus span {
   text-decoration: underline;
 }
diff --git a/core/themes/seven/css/components/entity-meta.css b/core/themes/seven/css/components/entity-meta.css
index cf614fd729..696f46a521 100644
--- a/core/themes/seven/css/components/entity-meta.css
+++ b/core/themes/seven/css/components/entity-meta.css
@@ -59,14 +59,13 @@
   padding: 0.85em 1.25em;
   text-shadow: 0 1px 0 white;
 }
-
-/**
- * Hide JS summary from the details polyfill to make it consistent with native
- * details elements.
- *
- * @todo Consider removing this after https://www.drupal.org/node/2493957 has
- *   been solved.
- */
-.entity-meta .seven-details .summary {
-  display: none;
+.seven-details__summary > .summary {
+  text-transform: none;
+  color: #595959;
+  font-size: 0.95em;
+  font-weight: normal;
 }
+.seven-details__summary:focus > .summary {
+  text-decoration: none;
+}
+
