diff --git a/src/Element/HorizontalTabs.php b/src/Element/HorizontalTabs.php
index f1ee96f..a44f9dd 100644
--- a/src/Element/HorizontalTabs.php
+++ b/src/Element/HorizontalTabs.php
@@ -2,6 +2,7 @@

 namespace Drupal\field_group\Element;

+use Drupal\Component\Utility\Html;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element\RenderElement;

@@ -68,6 +69,21 @@ class HorizontalTabs extends RenderElement {
       $element['#attached']['library'][] = 'core/drupal.form';
     }

+    // Enforce ids on groups if missing and determine displayed tab.
+    $displayed_tab = $element['#default_tab'];
+    foreach ($element as $key => $group) {
+      if (strpos($key, 'group_') !== 0) {
+        continue;
+      }
+      if (empty($group['#attributes']['id'])) {
+        $element[$key]['#attributes']['id'] = Html::getUniqueId('field-' . $key);
+      }
+      if (!empty($group['#open']) || empty($displayed_tab)) {
+        // Use the last open group or the first group if none are open.
+        $displayed_tab = $element[$key]['#attributes']['id'];
+      }
+    }
+
     // The JavaScript stores the currently selected tab in this hidden
     // field so that the active tab can be restored the next time the
     // form is rendered, e.g. on preview pages or when form validation
@@ -76,6 +92,9 @@ class HorizontalTabs extends RenderElement {
     if ($form_state->hasValue($name . '__active_tab')){
       $element['#default_tab'] = $form_state->getValue($name . '__active_tab');
     }
+    else {
+      $element['#default_tab'] = $displayed_tab;
+    }
     $element[$name . '__active_tab'] = array(
       '#type' => 'hidden',
       '#default_value' => $element['#default_tab'],
