diff --git a/core/includes/form.inc b/core/includes/form.inc
index c110c5b..f6b9f1b 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -213,13 +213,19 @@ function template_preprocess_fieldset(&$variables) {
}
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 @@
{{ legend.title }}
+ {% if description_display == 'before' and description.content %}
+
+ {{ description.content }}
+
+ {% endif %}
{% if errors %}
{{ errors }}
@@ -55,8 +66,10 @@
{% if suffix %}
{{ suffix }}
{% endif %}
- {% if description.content %}
-
{{ description.content }}
+ {% if description_display in ['after', 'invisible'] and description.content %}
+
+ {{ description.content }}
+
{% endif %}
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 c9fb026..0d0e6a3 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
@@ -21,19 +21,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 @@
{{ legend.title }}
+ {% if description_display == 'before' and description.content %}
+
+ {{ description.content }}
+
+ {% endif %}
{% if errors %}