diff --git a/core/lib/Drupal/Core/Render/Element/Container.php b/core/lib/Drupal/Core/Render/Element/Container.php
index 212000d..7989ba4 100644
--- a/core/lib/Drupal/Core/Render/Element/Container.php
+++ b/core/lib/Drupal/Core/Render/Element/Container.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Utility\Html as HtmlUtility;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
 
 /**
  * Provides a render element that wraps child elements in a container.
@@ -52,6 +53,7 @@ public function getInfo() {
       ],
       '#pre_render' => [
         [$class, 'preRenderGroup'],
+        [$class, 'preRenderContainer'],
       ],
       '#theme_wrappers' => ['container'],
     ];
@@ -79,4 +81,25 @@ public static function processContainer(&$element, FormStateInterface $form_stat
     return $element;
   }
 
+  /**
+   * Prevents optional containers from rendering if they have no children.
+   *
+   * @param $element
+   *   An associative array containing the properties and children of the
+   *   container.
+   *
+   * @return
+   *   The modified element.
+   */
+  public static function preRenderContainer($element) {
+    // Do not render optional container elements if there are no children.
+    if (isset($element['#parents'])) {
+      $group = implode('][', $element['#parents']);
+      if (!empty($element['#optional']) && !Element::getVisibleChildren($element['#groups'][$group])) {
+        $element['#printed'] = TRUE;
+      }
+    }
+    return $element;
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/Render/Element/ContainerTest.php b/core/tests/Drupal/Tests/Core/Render/Element/ContainerTest.php
new file mode 100644
index 0000000..3f71cdc
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Render/Element/ContainerTest.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Drupal\Tests\Core\Render\Element;
+
+use Drupal\Tests\Core\Render\RendererTestBase;
+use Drupal\Core\Render\Element\Container;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Render\Element\Container
+ * @group Render
+ */
+class ContainerTest extends RendererTestBase {
+
+  /**
+   * @covers ::preRenderContainer
+   * @dataProvider providerPreRenderContainer
+   */
+  public function testPreRenderContainer($element, $expected) {
+    $result = Container::preRenderContainer($element);
+    $this->assertEquals($expected, (string) $this->renderer->renderRoot($result));
+  }
+
+  /**
+   * Data provider for preRenderContainer test.
+   */
+  public function providerPreRenderContainer() {
+    $containers = [];
+
+    // Empty optional container.
+    $element = [
+      '#type' => 'container',
+      '#optional' => TRUE,
+    ];
+    $element['child1'] = ['#markup' => ''];
+    $containers['empty-optional'] = [$element, ''];
+
+    // Non-empty optional container.
+    $element = [
+      '#optional' => TRUE,
+    ];
+    $element['child1'] = ['#markup' => '<b>nested value</b>'];
+    $containers['non-empty-optional'] = [$element, '<div><b>nested value</b></div>'];
+
+    // Empty non-optional container.
+    $element = [
+      '#type' => 'container',
+      '#optional' => FALSE,
+    ];
+    $element['child1'] = ['#markup' => ''];
+    $containers['empty-non-optional'] = [$element, '<div></div>'];
+
+    // Non-empty non-optional container.
+    $element = [
+      '#type' => 'container',
+      '#optional' => FALSE,
+    ];
+    $element['child1'] = ['#markup' => '<b>nested value</b>'];
+    $containers['non-empty-non-optional'] = [$element, '<div><b>nested value</b></div>'];
+
+    return $containers;
+  }
+
+}
