diff --git a/core/includes/form.inc b/core/includes/form.inc
index daf75cd..cef19bc 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -207,13 +207,19 @@ function template_preprocess_fieldset(&$variables) {
   $variables['legend_span']['attributes'] = new Attribute();
 
   if (!empty($element['#description'])) {
-    $description_id = $element['#attributes']['id'] . '--description';
-    $description_attributes['id'] = $description_id;
+    $variables['description_display'] = $element['#description_display'];
+    $description_attributes = [];
+    if ($element['#description_display'] === 'invisible') {
+      $description_attributes['class'][] = 'visually-hidden';
+    }
+    if (!empty($element['#id'])) {
+      $description_attributes['id'] = $element['#attributes']['id'] . '--description';
+    }
     $variables['description']['attributes'] = new Attribute($description_attributes);
     $variables['description']['content'] = $element['#description'];
 
     // Add the description's id to the fieldset aria attributes.
-    $variables['attributes']['aria-describedby'] = $description_id;
+    $variables['attributes']['aria-describedby'] = $description_attributes['id'];
   }
 
   // Suppress error messages.
diff --git a/core/modules/system/templates/fieldset.html.twig b/core/modules/system/templates/fieldset.html.twig
index b67ec85..54247e4 100644
--- a/core/modules/system/templates/fieldset.html.twig
+++ b/core/modules/system/templates/fieldset.html.twig
@@ -13,6 +13,12 @@
  * - description: The description element containing the following properties:
  *   - content: The description content of the fieldset.
  *   - attributes: HTML attributes to apply to the description container.
+ * - description_display: Description display setting. It can have these values:
+ *   - before: The description is output before the element.
+ *   - after: The description is output after the element. This is the default
+ *     value.
+ *   - invisible: The description is output after the element, hidden visually
+ *     but available to screen readers.
  * - children: The rendered child elements of the fieldset.
  * - prefix: The content to add before the fieldset children.
  * - suffix: The content to add after the fieldset children.
@@ -43,6 +49,11 @@
     <span{{ legend_span.attributes.addClass(legend_span_classes) }}>{{ legend.title }}</span>
   </legend>
   <div class="fieldset-wrapper">
+    {% if description_display == 'before' and description.content %}
+      <div{{ description.attributes }}>
+        {{ description.content }}
+      </div>
+    {% endif %}
     {% if errors %}
       <div>
         {{ errors }}
@@ -55,8 +66,10 @@
     {% if suffix %}
       <span class="field-suffix">{{ suffix }}</span>
     {% endif %}
-    {% if description.content %}
-      <div{{ description.attributes.addClass('description') }}>{{ description.content }}</div>
+    {% if description_display in ['after', 'invisible'] and description.content %}
+      <div{{ description.attributes.addClass(description_classes) }}>
+        {{ description.content }}
+      </div>
     {% endif %}
   </div>
 </fieldset>
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupFieldsetForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupFieldsetForm.php
index e55b1af..58d6136 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupFieldsetForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupFieldsetForm.php
@@ -26,19 +26,67 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $form['fieldset'] = array(
+    $form['fieldset'] = [
       '#type' => 'fieldset',
       '#title' => 'Fieldset',
-    );
-    $form['meta'] = array(
+    ];
+    $form['meta'] = [
       '#type' => 'container',
       '#title' => 'Group element',
       '#group' => 'fieldset',
-    );
-    $form['meta']['element'] = array(
+    ];
+    $form['meta']['element'] = [
       '#type' => 'textfield',
       '#title' => 'Nest in container element',
-    );
+    ];
+
+    $form['fieldset_before'] = [
+      '#type' => 'fieldset',
+      '#title' => 'Fieldset test for description before element',
+      '#description' => 'Fieldset test for description before element.',
+      '#description_display' => 'before',
+    ];
+    $form['meta_before'] = [
+      '#type' => 'container',
+      '#title' => 'Group element',
+      '#group' => 'fieldset_before',
+    ];
+    $form['meta_before']['element'] = [
+      '#type' => 'textfield',
+      '#title' => 'Nest in container element',
+    ];
+
+    $form['fieldset_after'] = [
+      '#type' => 'fieldset',
+      '#title' => 'Fieldset test for description after element',
+      '#description' => 'Fieldset test for description after element.',
+      '#description_display' => 'after',
+    ];
+    $form['meta_after'] = [
+      '#type' => 'container',
+      '#title' => 'Group element',
+      '#group' => 'fieldset_after',
+    ];
+    $form['meta_after']['element'] = [
+      '#type' => 'textfield',
+      '#title' => 'Nest in container element',
+    ];
+
+    $form['fieldset_invisible'] = [
+      '#type' => 'fieldset',
+      '#title' => 'Fieldset test for visually-hidden description',
+      '#description' => 'Fieldset test for visually-hidden description.',
+      '#description_display' => 'invisible',
+    ];
+    $form['meta_invisible'] = [
+      '#type' => 'container',
+      '#title' => 'Group element',
+      '#group' => 'fieldset_invisible',
+    ];
+    $form['meta_invisible']['element'] = [
+      '#type' => 'textfield',
+      '#title' => 'Nest in container element',
+    ];
     return $form;
   }
 
diff --git a/core/themes/classy/templates/form/fieldset.html.twig b/core/themes/classy/templates/form/fieldset.html.twig
index 4bd7d0a..85f5228 100644
--- a/core/themes/classy/templates/form/fieldset.html.twig
+++ b/core/themes/classy/templates/form/fieldset.html.twig
@@ -13,6 +13,12 @@
  * - description: The description element containing the following properties:
  *   - content: The description content of the fieldset.
  *   - attributes: HTML attributes to apply to the description container.
+ * - description_display: Description display setting. It can have these values:
+ *   - before: The description is output before the element.
+ *   - after: The description is output after the element. This is the default
+ *     value.
+ *   - invisible: The description is output after the element, hidden visually
+ *     but available to screen readers.
  * - children: The rendered child elements of the fieldset.
  * - prefix: The content to add before the fieldset children.
  * - suffix: The content to add after the fieldset children.
@@ -41,6 +47,11 @@
     <span{{ legend_span.attributes.addClass(legend_span_classes) }}>{{ legend.title }}</span>
   </legend>
   <div class="fieldset-wrapper">
+    {% if description_display == 'before' and description.content %}
+      <div{{ description.attributes }}>
+        {{ description.content }}
+      </div>
+    {% endif %}
     {% if errors %}
       <div class="form-item--error-message">
         <strong>{{ errors }}</strong>
@@ -53,8 +64,10 @@
     {% if suffix %}
       <span class="field-suffix">{{ suffix }}</span>
     {% endif %}
-    {% if description.content %}
-      <div{{ description.attributes.addClass('description') }}>{{ description.content }}</div>
+    {% if description_display in ['after', 'invisible'] and description.content %}
+      <div{{ description.attributes.addClass(description_classes) }}>
+        {{ description.content }}
+      </div>
     {% endif %}
   </div>
 </fieldset>
