diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 144882b..2f0c972 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -152,7 +152,7 @@ function _drupal_theme_initialize($theme, $base_theme = array()) {
   // CSS file basenames to remove.
   $theme->stylesheets_remove = array();
 
-  // Grab stylesheets from base theme
+  // Grab stylesheets from base theme.
   foreach ($base_theme as $base) {
     if (!empty($base->stylesheets)) {
       foreach ($base->stylesheets as $media => $stylesheets) {
@@ -216,10 +216,10 @@ function _drupal_theme_initialize($theme, $base_theme = array()) {
   }
   drupal_render($css);
 
-  // Do basically the same as the above for scripts
+  // Do basically the same as the above for scripts.
   $final_scripts = array();
 
-  // Grab scripts from base theme
+  // Grab scripts from base theme.
   foreach ($base_theme as $base) {
     if (!empty($base->scripts)) {
       foreach ($base->scripts as $name => $script) {
@@ -262,7 +262,7 @@ function _drupal_theme_initialize($theme, $base_theme = array()) {
     }
   }
   else {
-    // include non-engine theme files
+    // Include non-engine theme files.
     foreach ($base_theme as $base) {
       // Include the theme file or the engine.
       if (!empty($base->owner)) {
@@ -566,7 +566,7 @@ function theme($hook, $variables = array()) {
   $info = $theme_registry->get($hook);
   global $theme_path;
   $temp = $theme_path;
-  // point path_to_theme() to the currently used theme path:
+  // Point path_to_theme() to the currently used theme path:
   $theme_path = $info['theme path'];
 
   // Include a file if the theme function or variable preprocessor is held
@@ -748,7 +748,7 @@ function theme($hook, $variables = array()) {
     $output = $render_function($template_file, $variables);
   }
 
-  // restore path_to_theme()
+  // Restore path_to_theme().
   $theme_path = $temp;
   return (string) $output;
 }
@@ -1608,7 +1608,7 @@ function theme_table($variables) {
     foreach ($colgroups as $colgroup) {
       $attributes = array();
 
-      // Check if we're dealing with a simple or complex column
+      // Check if we're dealing with a simple or complex column.
       if (isset($colgroup['data'])) {
         foreach ($colgroup as $key => $value) {
           if ($key == 'data') {
@@ -1623,7 +1623,7 @@ function theme_table($variables) {
         $cols = $colgroup;
       }
 
-      // Build colgroup
+      // Build colgroup.
       if (is_array($cols) && count($cols)) {
         $output .= ' <colgroup' . new Attribute($attributes) . '>';
         foreach ($cols as $col) {
@@ -1676,7 +1676,7 @@ function theme_table($variables) {
       $cell = tablesort_header($cell, $header, $ts);
       $output .= _theme_table_cell($cell, TRUE);
     }
-    // Using ternary operator to close the tags based on whether or not there are rows
+    // Using ternary operator to close the tags based on whether or not there are rows.
     $output .= (count($rows) ? " </tr></thead>\n" : "</tr>\n");
   }
   else {
@@ -1689,7 +1689,7 @@ function theme_table($variables) {
     $flip = array('even' => 'odd', 'odd' => 'even');
     $class = 'even';
     foreach ($rows as $row) {
-      // Check if we're dealing with a simple or complex row
+      // Check if we're dealing with a simple or complex row.
       if (isset($row['data'])) {
         $cells = $row['data'];
         $no_striping = isset($row['no_striping']) ? $row['no_striping'] : FALSE;
@@ -1705,13 +1705,13 @@ function theme_table($variables) {
         $no_striping = FALSE;
       }
       if (count($cells)) {
-        // Add odd/even class
+        // Add odd/even class.
         if (!$no_striping) {
           $class = $flip[$class];
           $attributes['class'][] = $class;
         }
 
-        // Build row
+        // Build row.
         $output .= ' <tr' . new Attribute($attributes) . '>';
         $i = 0;
         foreach ($cells as $cell) {
@@ -1913,21 +1913,18 @@ function theme_indentation($variables) {
   return $output;
 }
 
+
 /**
- * Returns HTML to wrap child elements in a container.
+ * Prepares variables for container templates.
  *
- * Used for grouped form items. Can also be used as a #theme_wrapper for any
- * renderable element, to surround it with a <div> and add attributes such as
- * classes or an HTML id.
+ * Default template: container.html.twig.
  *
- * @param $variables
+ * @param array $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
  *     Properties used: #id, #attributes, #children.
- *
- * @ingroup themeable
  */
-function theme_container($variables) {
+function template_preprocess_container(&$variables) {
   $element = $variables['element'];
   // Ensure #attributes is set.
   $element += array('#attributes' => array());
@@ -1942,7 +1939,8 @@ function theme_container($variables) {
     $element['#attributes']['class'][] = 'form-wrapper';
   }
 
-  return '<div' . new Attribute($element['#attributes']) . '>' . $element['#children'] . '</div>';
+  $variables['children'] = $element['#children'];
+  $variables['attributes'] = $element['#attributes'];
 }
 
 /**
@@ -2744,6 +2742,7 @@ function drupal_common_theme() {
     ),
     'container' => array(
       'render element' => 'element',
+      'template' => 'container',
     ),
   );
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php
index 9ba4bf4..2f8b2ef 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php
@@ -50,7 +50,7 @@ function testContainer() {
           '#type' => 'container',
           '#markup' => 'foo',
         ),
-        'expected' => '<div>foo</div>',
+        'expected' => "<div>foo</div>\n",
       ),
       // Container with a class.
       array(
@@ -62,7 +62,7 @@ function testContainer() {
             'class' => 'bar',
           ),
         ),
-        'expected' => '<div class="bar">foo</div>',
+        'expected' => '<div class="bar">foo</div>' . "\n",
       ),
       // Container with children.
       array(
@@ -73,7 +73,7 @@ function testContainer() {
             '#markup' => 'foo',
           ),
         ),
-        'expected' => '<div>foo</div>',
+        'expected' => "<div>foo</div>\n",
       ),
     );
 
@@ -106,11 +106,10 @@ function testHtmlTag() {
           '#tag' => 'title',
           '#value' => 'title test',
         ),
-        'expected' => '<title>title test</title>' . "\n",
+        'expected' => "<title>title test</title>\n",
       ),
     );
 
     $this->assertElements($elements);
   }
-
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
index 750250d..f868257 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
@@ -90,7 +90,7 @@ function testDrupalRenderBasics() {
           '#theme_wrappers' => array('container'),
           '#attributes' => array('class' => 'baz'),
         ),
-        'expected' => '<div class="baz">foobar</div>',
+        'expected' => '<div class="baz">foobar</div>' . "\n",
       ),
       // Test that #theme_wrappers can disambiguate element attributes shared
       // with rendering methods that build #children by using the alternate
@@ -108,7 +108,7 @@ function testDrupalRenderBasics() {
           '#href' => 'http://drupal.org',
           '#title' => 'bar',
         ),
-        'expected' => '<div class="baz"><a href="http://drupal.org" id="foo">bar</a></div>',
+        'expected' => '<div class="baz"><a href="http://drupal.org" id="foo">bar</a></div>' . "\n",
       ),
       // Test that #theme_wrappers can disambiguate element attributes when the
       // "base" attribute is not set for #theme.
@@ -124,7 +124,7 @@ function testDrupalRenderBasics() {
             ),
           ),
         ),
-        'expected' => '<div class="baz"><a href="http://drupal.org">foo</a></div>',
+        'expected' => '<div class="baz"><a href="http://drupal.org">foo</a></div>' . "\n",
       ),
       // Two 'container' #theme_wrappers, one using the "base" attributes and
       // one using an override.
@@ -139,7 +139,7 @@ function testDrupalRenderBasics() {
             'container',
           ),
         ),
-        'expected' => '<div class="foo"><div class="bar"></div></div>',
+        'expected' => '<div class="foo"><div class="bar"></div>' . "\n</div>\n",
       ),
       // Array syntax theme hook suggestion in #theme_wrappers.
       array(
@@ -148,7 +148,7 @@ function testDrupalRenderBasics() {
           '#theme_wrappers' => array(array('container')),
           '#attributes' => array('class' => 'foo'),
         ),
-        'expected' => '<div class="foo"></div>',
+        'expected' => '<div class="foo"></div>' . "\n",
       ),
 
       // Test handling of #markup as a fallback for #theme hooks.
diff --git a/core/modules/system/templates/container.html.twig b/core/modules/system/templates/container.html.twig
new file mode 100644
index 0000000..933a201
--- /dev/null
+++ b/core/modules/system/templates/container.html.twig
@@ -0,0 +1,15 @@
+{#
+/**
+ * @file
+ * Default theme implementation of a container used to wrap child elements.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the containing element.
+ * - children: The rendered child elements of the container.
+ *
+ * @see template_preprocess_container()
+ *
+ * @ingroup themeable
+ */
+#}
+<div{{ attributes }}>{{ children }}</div>
