diff --git a/core/lib/Drupal/Core/Datetime/Element/Datetime.php b/core/lib/Drupal/Core/Datetime/Element/Datetime.php
index 46fb63e1eb..3ac5b2301a 100644
--- a/core/lib/Drupal/Core/Datetime/Element/Datetime.php
+++ b/core/lib/Drupal/Core/Datetime/Element/Datetime.php
@@ -232,19 +232,6 @@ public static function processDatetime(&$element, FormStateInterface $form_state
 
     $element['#tree'] = TRUE;
 
-    // Visibility states need to be applied to the element as a whole, but the
-    // other states apply to the individual parts.
-    if (isset($element['#states']) && is_array($element['#states'])) {
-      $wrapper_states = array_filter($element['#states'], function ($key) {
-        return in_array($key, ['visible', 'invisible']);
-      }, ARRAY_FILTER_USE_KEY);
-      $children_states = array_diff_key($element['#states'], $wrapper_states);
-    }
-    else {
-      $wrapper_states = $children_states = [];
-    }
-    $element['#states'] = $wrapper_states;
-
     if ($element['#date_date_element'] != 'none') {
 
       $date_format = $element['#date_date_element'] != 'none' ? static::getHtml5DateFormat($element) : '';
@@ -282,7 +269,7 @@ public static function processDatetime(&$element, FormStateInterface $form_state
         '#size' => max(12, strlen($element['#value']['date'])),
         '#error_no_message' => TRUE,
         '#date_date_format' => $element['#date_date_format'],
-        '#states' => $children_states,
+        '#states' => empty($element['#states']) ? [] : $element['#states'],
       ];
 
       // Allows custom callbacks to alter the element.
@@ -315,7 +302,7 @@ public static function processDatetime(&$element, FormStateInterface $form_state
         '#required' => $element['#required'],
         '#size' => 12,
         '#error_no_message' => TRUE,
-        '#states' => $children_states,
+        '#states' => empty($element['#states']) ? [] : $element['#states'],
       ];
 
       // Allows custom callbacks to alter the element.
diff --git a/core/misc/states.es6.js b/core/misc/states.es6.js
index dd2c315539..6caeafd8b3 100644
--- a/core/misc/states.es6.js
+++ b/core/misc/states.es6.js
@@ -658,7 +658,11 @@
         .toggleClass('form-disabled', e.value)
         .find('select, input, textarea')
         .prop('disabled', e.value);
-
+       // A complex form element, like 'datetime' (one made up of multiple
+       // sub-elements) may have a label for the element as a whole.
+       $(e.target)
+        .closest('.js-complex-form-item')
+        .toggleClass('form-disabled', e.value);
       // Note: WebKit nightlies don't reflect that change correctly.
       // See https://bugs.webkit.org/show_bug.cgi?id=23789
     }
@@ -672,16 +676,28 @@
           .attr({ required: 'required', 'aria-required': 'aria-required' })
           .closest('.js-form-item, .js-form-wrapper')
           .find(label);
+        // A complex form element, like 'datetime' (one made up of multiple
+        // sub-elements) may have a label for the element as a whole.
+        const $complexLabel = $(e.target)
+          .closest('.js-complex-form-item')
+          .children('label');
         // Avoids duplicate required markers on initialization.
         if (!$label.hasClass('js-form-required').length) {
           $label.addClass('js-form-required form-required');
         }
+        if (!$complexLabel.hasClass('js-form-required').length) {
+          $complexLabel.addClass('js-form-required form-required');
+        }
       } else {
-        $(e.target)
-          .removeAttr('required aria-required')
-          .closest('.js-form-item, .js-form-wrapper')
-          .find('label.js-form-required')
-          .removeClass('js-form-required form-required');
+          $(e.target)
+              .removeAttr('required aria-required')
+              .closest('.js-form-item, .js-form-wrapper')
+              .find('label.js-form-required')
+              .removeClass('js-form-required form-required');
+          $(e.target)
+              .closest('.js-complex-form-item')
+              .children('label')
+              .removeClass('js-form-required form-required');
       }
     }
   });
@@ -691,6 +707,22 @@
       $(e.target)
         .closest('.js-form-item, .js-form-submit, .js-form-wrapper')
         .toggle(e.value);
+      // A complex form element, like 'datetime' (one made up of multiple
+      // sub-elements) may have a label for the element as a whole.
+      const $complexLabel = $(e.target)
+        .closest('.js-complex-form-item')
+        .children('label');
+      // If there is a label, toggle the visibility of the label too.
+      if ($complexLabel.length) {
+        $complexLabel.toggle(e.value);
+      }
+      const $complexDescription = $(e.target)
+        .closest('.js-complex-form-item')
+        .children('div.description');
+      // If there is a description, toggle the visibility of the description too.
+      if ($complexDescription.length) {
+        $complexDescription.toggle(e.value);
+      }
     }
   });
 
diff --git a/core/misc/states.js b/core/misc/states.js
index 39ce05f488..975c0d75ff 100644
--- a/core/misc/states.js
+++ b/core/misc/states.js
@@ -332,8 +332,7 @@
   $document.on('state:disabled', function (e) {
     if (e.trigger) {
       $(e.target).prop('disabled', e.value).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value).find('select, input, textarea').prop('disabled', e.value);
-      // A complex form element, like 'datetime' (one made up of multiple
-      // sub-elements) may have a label for the element as a whole.
+
       $(e.target).closest('.js-complex-form-item').toggleClass('form-disabled', e.value);
     }
   });
@@ -343,8 +342,7 @@
       if (e.value) {
         var label = 'label' + (e.target.id ? '[for=' + e.target.id + ']' : '');
         var $label = $(e.target).attr({ required: 'required', 'aria-required': 'aria-required' }).closest('.js-form-item, .js-form-wrapper').find(label);
-        // A complex form element, like 'datetime' (one made up of multiple
-        // sub-elements) may have a label for the element as a whole.
+
         var $complexLabel = $(e.target).closest('.js-complex-form-item').children('label');
 
         if (!$label.hasClass('js-form-required').length) {
@@ -363,6 +361,17 @@
   $document.on('state:visible', function (e) {
     if (e.trigger) {
       $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value);
+
+      var $complexLabel = $(e.target).closest('.js-complex-form-item').children('label');
+
+      if ($complexLabel.length) {
+        $complexLabel.toggle(e.value);
+      }
+      var $complexDescription = $(e.target).closest('.js-complex-form-item').children('div.description');
+
+      if ($complexDescription.length) {
+        $complexDescription.toggle(e.value);
+      }
     }
   });
 
