diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index bc44213..e33e133 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1973,13 +1973,11 @@ function template_preprocess_html(&$variables) {
 
   // Compile a list of classes that are going to be applied to the body element.
   // This allows advanced theming based on context (home page, node of certain type, etc.).
-  $body_classes = $variables['attributes']['class'];
-  $body_classes[] = 'html';
+  $variables['attributes']['class'][] = 'html';
   // Add a class that tells us whether we're on the front page or not.
-  $body_classes[] = $variables['is_front'] ? 'front' : 'not-front';
+  $variables['attributes']['class'][] = $variables['is_front'] ? 'front' : 'not-front';
   // Add a class that tells us whether the page is viewed by an authenticated user or not.
-  $body_classes[] = $variables['logged_in'] ? 'logged-in' : 'not-logged-in';
-  $variables['attributes']['class'] = $body_classes;
+  $variables['attributes']['class'][] = $variables['logged_in'] ? 'logged-in' : 'not-logged-in';
 
   // Populate the body classes.
   if ($suggestions = theme_get_suggestions(arg(), 'page', '-')) {
@@ -2254,14 +2252,12 @@ function template_preprocess_maintenance_page(&$variables) {
   template_preprocess_page($variables);
 
   $page_object = $variables['page']['#page'];
-  $attributes = $page_object->getBodyAttributes();
-  $classes = $attributes['class'];
-  $classes[] = 'maintenance-page';
-  $classes[] = 'in-maintenance';
+  $variables['attributes'] = $page_object->getBodyAttributes();
+  $variables['attributes']['class'][] = 'maintenance-page';
+  $variables['attributes']['class'][] = 'in-maintenance';
   if (isset($variables['db_is_active']) && !$variables['db_is_active']) {
-    $classes[] = 'db-offline';
+    $variables['attributes']['class'][] = 'db-offline';
   }
-  $attributes['class'] = $classes;
 
   // @see system_page_build()
   $attached = array(
@@ -2290,10 +2286,8 @@ function template_preprocess_install_page(&$variables) {
   template_preprocess_maintenance_page($variables);
 
   $page_object = $variables['page']['#page'];
-  $attributes = $page_object->getBodyAttributes();
-  $classes = $attributes['class'];
-  $classes[] = 'install-page';
-  $attributes['class'] = $classes;
+  $variables['attributes'] = $page_object->getBodyAttributes();
+  $variables['attributes']['class'][] = 'install-page';
 
   // Override the site name that is displayed on the page, since Drupal is
   // still in the process of being installed.
diff --git a/core/lib/Drupal/Core/Template/Attribute.php b/core/lib/Drupal/Core/Template/Attribute.php
index ead5d05..c3b3ad6 100644
--- a/core/lib/Drupal/Core/Template/Attribute.php
+++ b/core/lib/Drupal/Core/Template/Attribute.php
@@ -31,116 +31,32 @@
  *  // Produces <cat class="cat black-cat white-cat black-white-cat" id="socks">
  * @endcode
  */
-class Attribute implements \ArrayAccess, \IteratorAggregate {
-
-  /**
-   * Stores the attribute data.
-   *
-   * @var array
-   */
-  protected $storage = array();
-
-  /**
-   * Constructs a \Drupal\Core\Template\Attribute object.
-   *
-   * @param array $attributes
-   *   An associative array of key-value pairs to be converted to attributes.
-   */
-  public function __construct($attributes = array()) {
-    foreach ($attributes as $name => $value) {
-      $this->offsetSet($name, $value);
-    }
-  }
-
-  /**
-   * Implements ArrayAccess::offsetGet().
-   */
-  public function offsetGet($name) {
-    if (isset($this->storage[$name])) {
-      return $this->storage[$name];
-    }
-  }
-
-  /**
-   * Implements ArrayAccess::offsetSet().
-   */
-  public function offsetSet($name, $value) {
-    $this->storage[$name] = $this->createAttributeValue($name, $value);
-  }
-
-  /**
-   * Creates the different types of attribute values.
-   *
-   * @param string $name
-   *   The attribute name.
-   * @param mixed $value
-   *   The attribute value.
-   *
-   * @return \Drupal\Core\Template\AttributeValueBase
-   *   An AttributeValueBase representation of the attribute's value.
-   */
-  protected function createAttributeValue($name, $value) {
-    if (is_array($value)) {
-      $value = new AttributeArray($name, $value);
-    }
-    elseif (is_bool($value)) {
-      $value = new AttributeBoolean($name, $value);
-    }
-    elseif (!is_object($value)) {
-      $value = new AttributeString($name, $value);
-    }
-    return $value;
-  }
-
-  /**
-   * Implements ArrayAccess::offsetUnset().
-   */
-  public function offsetUnset($name) {
-    unset($this->storage[$name]);
-  }
-
-  /**
-   * Implements ArrayAccess::offsetExists().
-   */
-  public function offsetExists($name) {
-    return isset($this->storage[$name]);
-  }
+class Attribute extends \ArrayObject {
 
   /**
    * Implements the magic __toString() method.
    */
   public function __toString() {
     $return = '';
-    foreach ($this->storage as $name => $value) {
-      $rendered = $value->render();
+    foreach ($this as $name => $value) {
+      $rendered = NULL;
+      if ($value === NULL) {
+        continue;
+      }
+      $name = String::checkPlain($name);
+      if (is_array($value)) {
+        $rendered = $name . '="' . String::checkPlain(implode(' ', $value)) . '"';
+      }
+      elseif (is_bool($value)) {
+        $rendered = ($value === FALSE) ? NULL : $name;
+      }
+      else {
+        $rendered = $name . '="' . String::checkPlain($value) . '"';
+      }
       if ($rendered) {
         $return .= ' ' . $rendered;
       }
     }
     return $return;
   }
-
-  /**
-   * Implements the magic __clone() method.
-   */
-  public function  __clone() {
-    foreach ($this->storage as $name => $value) {
-      $this->storage[$name] = clone $value;
-    }
-  }
-
-  /**
-   * Implements IteratorAggregate::getIterator().
-   */
-  public function getIterator() {
-    return new \ArrayIterator($this->storage);
-  }
-
-  /**
-   * Returns the whole array.
-   */
-  public function storage() {
-    return $this->storage;
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Template/AttributeArray.php b/core/lib/Drupal/Core/Template/AttributeArray.php
deleted file mode 100644
index 95e0ef3..0000000
--- a/core/lib/Drupal/Core/Template/AttributeArray.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Template\AttributeArray.
- */
-
-namespace Drupal\Core\Template;
-
-use Drupal\Component\Utility\String;
-
-/**
- * A class that defines a type of Attribute that can be added to as an array.
- *
- * To use with Attribute, the array must be specified.
- * Correct:
- * @code
- *  $attributes = new Attribute();
- *  $attributes['class'] = array();
- *  $attributes['class'][] = 'cat';
- * @endcode
- * Incorrect:
- * @code
- *  $attributes = new Attribute();
- *  $attributes['class'][] = 'cat';
- * @endcode
- *
- * @see \Drupal\Core\Template\Attribute
- */
-class AttributeArray extends AttributeValueBase implements \ArrayAccess, \IteratorAggregate {
-
-  /**
-   * Implements ArrayAccess::offsetGet().
-   */
-  public function offsetGet($offset) {
-    return $this->value[$offset];
-  }
-
-  /**
-   * Implements ArrayAccess::offsetSet().
-   */
-  public function offsetSet($offset, $value) {
-    if (isset($offset)) {
-      $this->value[$offset] = $value;
-    }
-    else {
-      $this->value[] = $value;
-    }
-  }
-
-  /**
-   * Implements ArrayAccess::offsetUnset().
-   */
-  public function offsetUnset($offset) {
-    unset($this->value[$offset]);
-  }
-
-  /**
-   * Implements ArrayAccess::offsetExists().
-   */
-  public function offsetExists($offset) {
-    return isset($this->value[$offset]);
-  }
-
-  /**
-   * Implements the magic __toString() method.
-   */
-  public function __toString() {
-    return String::checkPlain(implode(' ', $this->value));
-  }
-
-  /**
-   * Implements IteratorAggregate::getIterator().
-   */
-  public function getIterator() {
-    return new \ArrayIterator($this->value);
-  }
-
-  /**
-   * Returns the whole array.
-   */
-  public function value() {
-    return $this->value;
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Template/AttributeBoolean.php b/core/lib/Drupal/Core/Template/AttributeBoolean.php
deleted file mode 100644
index 4e9ea67..0000000
--- a/core/lib/Drupal/Core/Template/AttributeBoolean.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Template\AttributeBoolean.
- */
-
-namespace Drupal\Core\Template;
-
-use Drupal\Component\Utility\String;
-
-/**
- * A class that defines a type of boolean HTML attribute.
- *
- * Boolean HTML attributes are not attributes with values of TRUE/FALSE.
- * They are attributes that if they exist in the tag, they are TRUE.
- * Examples include selected, disabled, checked, readonly.
- *
- * To set a boolean attribute on the Attribute class, set it to TRUE.
- * @code
- *  $attributes = new Attribute();
- *  $attributes['disabled'] = TRUE;
- *  echo '<select' . $attributes . '/>';
- *  // produces <select disabled>;
- *  $attributes['disabled'] = FALSE;
- *  echo '<select' . $attributes . '/>';
- *  // produces <select>;
- * @endcode
- *
- * @see \Drupal\Core\Template\Attribute
- */
-class AttributeBoolean extends AttributeValueBase {
-
-  /**
-   * Overrides AttributeValueBase::render().
-   */
-  public function render() {
-    return $this->__toString();
-  }
-
-  /**
-   * Implements the magic __toString() method.
-   */
-  public function __toString() {
-    return $this->value === FALSE ? '' : String::checkPlain($this->name);
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Template/AttributeString.php b/core/lib/Drupal/Core/Template/AttributeString.php
deleted file mode 100644
index 07211be..0000000
--- a/core/lib/Drupal/Core/Template/AttributeString.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Template\AttributeString.
- */
-
-namespace Drupal\Core\Template;
-
-use Drupal\Component\Utility\String;
-
-/**
- * A class that represents most standard HTML attributes.
- *
- * To use with the Attribute class, set the key to be the attribute name
- * and the value the attribute value.
- * @code
- *  $attributes = new Attribute(array());
- *  $attributes['id'] = 'socks';
- *  $attributes['style'] = 'background-color:white';
- *  echo '<cat ' . $attributes . '>';
- *  // Produces: <cat id="socks" style="background-color:white">.
- * @endcode
- *
- * @see \Drupal\Core\Template\Attribute
- */
-class AttributeString extends AttributeValueBase {
-
-  /**
-   * Implements the magic __toString() method.
-   */
-  public function __toString() {
-    return String::checkPlain($this->value);
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Template/AttributeValueBase.php b/core/lib/Drupal/Core/Template/AttributeValueBase.php
deleted file mode 100644
index 73e6bee..0000000
--- a/core/lib/Drupal/Core/Template/AttributeValueBase.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Template\AttributeValueBase.
- */
-
-namespace Drupal\Core\Template;
-
-use Drupal\Component\Utility\String;
-
-/**
- * Defines the base class for an attribute type.
- *
- * @see \Drupal\Core\Template\Attribute
- */
-abstract class AttributeValueBase {
-
-  /**
-   * The value itself.
-   *
-   * @var mixed
-   */
-  protected $value;
-
-  /**
-   * The name of the value.
-   *
-   * @var mixed
-   */
-  protected $name;
-
-  /**
-   * Constructs a \Drupal\Core\Template\AttributeValueBase object.
-   */
-  public function __construct($name, $value) {
-    $this->name = $name;
-    $this->value = $value;
-  }
-
-  /**
-   * Returns a string representation of the attribute.
-   *
-   * While __toString only returns the value in a string form, render()
-   * contains the name of the attribute as well.
-   *
-   * @return string
-   *   The string representation of the attribute.
-   */
-  public function render() {
-    if (isset($this->value)) {
-      return String::checkPlain($this->name) . '="' . $this . '"';
-    }
-  }
-
-  /**
-   * Implements the magic __toString() method.
-   */
-  abstract function __toString();
-
-}
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 9cc9a8b..2080fa4 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -437,7 +437,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array
                 'title' => '',
                 'href' => '',
                 'attributes' => array(
-                  'class' => 'hidden',
+                  'class' => array('hidden'),
                   'title' => t('Jump to the first new comment of this posting.'),
                   'data-history-node-last-comment-timestamp' => $node->get($field_name)->last_comment_timestamp,
                   'data-history-node-field-name' => $field_name,
diff --git a/core/modules/node/templates/node.html.twig b/core/modules/node/templates/node.html.twig
index ae1162e..c19db96 100644
--- a/core/modules/node/templates/node.html.twig
+++ b/core/modules/node/templates/node.html.twig
@@ -75,7 +75,7 @@
  * @ingroup themeable
  */
 #}
-<article id="node-{{ node.id }}" class="{{ attributes.class }} clearfix"{{ attributes|without('id', 'class') }}>
+<article id="node-{{ node.id }}" class="{{ attributes.class|merge(['clearfix'])|join(' ') }}"{{ attributes|without('id', 'class') }}>
 
   {{ title_prefix }}
   {% if not page %}
diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.filter.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.filter.html.twig
index 28e5c15..c292ca1 100644
--- a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.filter.html.twig
+++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.filter.html.twig
@@ -13,10 +13,10 @@
   </blockquote>
 </div>
 <div><span{{ attributes }}>All attributes:</span></div>
-<div><span class="{{ attributes.class }}"{{ attributes|without('class') }}>Class attributes in front, remainder at the back:</span></div>
-<div><span{{ attributes|without('class') }} data-class="{{ attributes.class }}">Class attributes in back, remainder at the front:</span></div>
-<div><span class="{{ attributes.class }}">Class attributes only:</span></div>
-<div><span {{ attributes.checked }}{{ attributes|without('checked') }}>Without boolean attribute.</span></div>
+<div><span class="{{ attributes.class|join(' ') }}"{{ attributes|without('class') }}>Class attributes in front, remainder at the back:</span></div>
+<div><span{{ attributes|without('class') }} data-class="{{ attributes.class|join(' ') }}">Class attributes in back, remainder at the front:</span></div>
+<div><span class="{{ attributes.class|join(' ') }}">Class attributes only:</span></div>
+<div><span{{ attributes.checked ? ' checked' }}{{ attributes|without('checked') }}>Without boolean attribute.</span></div>
 <div><span data-id="{{ attributes.id }}"{{ attributes|without('id') }}>Without string attribute.</span></div>
 <div><span{{ attributes|without('id', 'class') }}>Without either nor class attributes.</span></div>
 <div><span{{ attributes }}>All attributes again.</span></div>
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 216bc93..1f12ef4 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -15,7 +15,6 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Render\Element;
 use Drupal\views\Plugin\Derivative\ViewsLocalTask;
-use Drupal\Core\Template\AttributeArray;
 use Drupal\views\ViewExecutable;
 use Drupal\Component\Plugin\Exception\PluginException;
 use Drupal\views\Entity\View;
@@ -358,9 +357,9 @@ function views_preprocess_page(&$variables) {
     /** @var \Drupal\Core\Page\HtmlPage $page_object */
     $page_object = $variables['page']['#page'];
     $attributes = $page_object->getBodyAttributes();
-    $class = $attributes['class'] ?: array();
+    $class = isset($attributes['class']) ? $attributes['class'] : array();
 
-    $key = array_search('contextual-region', $variables['attributes']['class'] instanceof AttributeArray ? $variables['attributes']['class']->value() : $variables['attributes']['class']);
+    $key = array_search('contextual-region', $variables['attributes']['class']);
     if ($key !== FALSE) {
       /** @var \Drupal\Core\Page\HtmlPage $page_object */
       unset($class[$key]);
diff --git a/core/tests/Drupal/Tests/Core/Template/AttributeTest.php b/core/tests/Drupal/Tests/Core/Template/AttributeTest.php
index af5e332..af15f03 100644
--- a/core/tests/Drupal/Tests/Core/Template/AttributeTest.php
+++ b/core/tests/Drupal/Tests/Core/Template/AttributeTest.php
@@ -8,8 +8,6 @@
 namespace Drupal\Tests\Core\Template;
 
 use Drupal\Core\Template\Attribute;
-use Drupal\Core\Template\AttributeArray;
-use Drupal\Core\Template\AttributeString;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -33,7 +31,7 @@ public static function getInfo() {
   public function testConstructor() {
     $attribute = new Attribute(array('class' => array('example-class')));
     $this->assertTrue(isset($attribute['class']));
-    $this->assertEquals(new AttributeArray('class', array('example-class')), $attribute['class']);
+    $this->assertEquals(array('example-class'), $attribute['class']);
   }
 
   /**
@@ -44,7 +42,7 @@ public function testSet() {
     $attribute['class'] = array('example-class');
 
     $this->assertTrue(isset($attribute['class']));
-    $this->assertEquals(new AttributeArray('class', array('example-class')), $attribute['class']);
+    $this->assertEquals(array('example-class'), $attribute['class']);
   }
 
   /**
@@ -54,7 +52,7 @@ public function testAdd() {
     $attribute = new Attribute(array('class' => array('example-class')));
 
     $attribute['class'][] = 'other-class';
-    $this->assertEquals(new AttributeArray('class', array('example-class', 'other-class')), $attribute['class']);
+    $this->assertEquals(array('example-class', 'other-class'), $attribute['class']);
   }
 
   /**
@@ -76,11 +74,11 @@ public function testIterate() {
     foreach ($attribute as $key => $value) {
       if ($counter == 0) {
         $this->assertEquals('class', $key);
-        $this->assertEquals(new AttributeArray('class', array('example-class')), $value);
+        $this->assertEquals(array('example-class'), $value);
       }
       if ($counter == 1) {
         $this->assertEquals('id', $key);
-        $this->assertEquals(new AttributeString('id', 'example-id'), $value);
+        $this->assertEquals('example-id', $value);
       }
       $counter++;
     }
@@ -104,12 +102,12 @@ public function testPrint() {
   }
 
   /**
-   * Tests the storage method.
+   * Tests the getArrayCopy method.
    */
   public function testStorage() {
     $attribute = new Attribute(array('class' => array('example-class')));
 
-    $this->assertEquals(array('class' => new AttributeArray('class', array('example-class'))), $attribute->storage());
+    $this->assertEquals(array('class' => array('example-class')), $attribute->getArrayCopy());
   }
 
 }
diff --git a/core/themes/bartik/bartik.theme b/core/themes/bartik/bartik.theme
index 1532b9f..47ef080 100644
--- a/core/themes/bartik/bartik.theme
+++ b/core/themes/bartik/bartik.theme
@@ -19,42 +19,38 @@ function bartik_preprocess_page(&$variables) {
   /** @var \Drupal\Core\Page\HtmlPage $page_object */
   $page_object = $variables['page']['#page'];
   $attributes = $page_object->getBodyAttributes();
-  $classes = $attributes['class'];
   if (!empty($variables['page']['sidebar_first']) && !empty($variables['page']['sidebar_second'])) {
-    $classes[] = 'two-sidebars';
+    $attributes['class'][] = 'two-sidebars';
   }
   elseif (!empty($variables['page']['sidebar_first'])) {
-    $classes[] = 'one-sidebar';
-    $classes[] = 'sidebar-first';
+    $attributes['class'][] = 'one-sidebar';
+    $attributes['class'][] = 'sidebar-first';
   }
   elseif (!empty($variables['page']['sidebar_second'])) {
-    $classes[] = 'one-sidebar';
-    $classes[] = 'sidebar-second';
+    $attributes['class'][] = 'one-sidebar';
+    $attributes['class'][] = 'sidebar-second';
   }
   else {
-    $classes[] = 'no-sidebars';
+    $attributes['class'][] = 'no-sidebars';
   }
 
   if (!empty($variables['page']['featured'])) {
-    $classes[] = 'featured';
+    $attributes['class'][] = 'featured';
   }
 
   if (!empty($variables['page']['triptych_first'])
     || !empty($variables['page']['triptych_middle'])
     || !empty($variables['page']['triptych_last'])) {
-    $classes[] = 'triptych';
+    $attributes['class'][] = 'triptych';
   }
 
   if (!empty($variables['page']['footer_firstcolumn'])
     || !empty($variables['page']['footer_secondcolumn'])
     || !empty($variables['page']['footer_thirdcolumn'])
     || !empty($variables['page']['footer_fourthcolumn'])) {
-    $classes[] = 'footer-columns';
+    $attributes['class'][] = 'footer-columns';
   }
 
-  // Store back the classes to the htmlpage object.
-  $attributes['class'] = $classes;
-
   // Pass the main menu and secondary menu to the template as render arrays.
   if (!empty($variables['main_menu'])) {
     $variables['main_menu']['#attributes']['id'] = 'main-menu-links';
diff --git a/core/themes/bartik/templates/comment.html.twig b/core/themes/bartik/templates/comment.html.twig
index d2c4584..b034351 100644
--- a/core/themes/bartik/templates/comment.html.twig
+++ b/core/themes/bartik/templates/comment.html.twig
@@ -62,7 +62,7 @@
  * @see template_preprocess_comment()
  */
 #}
-<article class="{{ attributes.class }} clearfix" role="article"{{ attributes|without('class', 'role') }}>
+<article class="{{ attributes.class|merge(['clearfix'])|join(' ') }}" role="article"{{ attributes|without('class', 'role') }}>
 
   <header class="comment-header">
     <div class="attribution">
diff --git a/core/themes/bartik/templates/field--taxonomy-term-reference.html.twig b/core/themes/bartik/templates/field--taxonomy-term-reference.html.twig
index fad1ed7..40545cc 100644
--- a/core/themes/bartik/templates/field--taxonomy-term-reference.html.twig
+++ b/core/themes/bartik/templates/field--taxonomy-term-reference.html.twig
@@ -16,7 +16,7 @@
  * @see bartik_preprocess_field()
  */
 #}
-<div class="{{ attributes.class }} clearfix"{{ attributes|without('class') }}>
+<div class="{{ attributes.class|merge(['clearfix'])|join(' ') }}"{{ attributes|without('class') }}>
   <h3{{ label_attributes }}>{{ label }}: </h3>
   <ul class="links">
     {% for delta, item in items %}
diff --git a/core/themes/bartik/templates/node.html.twig b/core/themes/bartik/templates/node.html.twig
index 2848899..214c222 100644
--- a/core/themes/bartik/templates/node.html.twig
+++ b/core/themes/bartik/templates/node.html.twig
@@ -69,7 +69,7 @@
  * @see template_preprocess_node()
  */
 #}
-<article id="node-{{ node.id }}" class="{{ attributes.class }} clearfix" role="article"{{ attributes|without('id', 'class', 'role') }}>
+<article id="node-{{ node.id }}" class="{{ attributes.class|merge(['clearfix'])|join(' ') }}" role="article"{{ attributes|without('id', 'class', 'role') }}>
 
   <header>
     {{ title_prefix }}
diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme
index c3e7a32..313242b 100644
--- a/core/themes/seven/seven.theme
+++ b/core/themes/seven/seven.theme
@@ -15,18 +15,16 @@ use Drupal\Component\Utility\String;
 function seven_preprocess_page(&$variables) {
   /** @var \Drupal\Core\Page\HtmlPage $page_object */
   $page_object = $variables['page']['#page'];
-  $attributes = $page_object->getBodyAttributes();
-  $classes = $attributes['class'];
-  // Add information about the number of sidebars.
+  $variables['attributes'] = $page_object->getBodyAttributes();
 
+  // Add information about the number of sidebars.
   if (!empty($variables['page']['sidebar_first'])) {
-    $classes[] = 'one-sidebar';
-    $classes[] = 'sidebar-first';
+    $variables['attributes']['class'][] = 'one-sidebar';
+    $variables['attributes']['class'][] = 'sidebar-first';
   }
   else {
-    $classes[] = 'no-sidebars';
+    $variables['attributes']['class'][] = 'no-sidebars';
   }
-  $attributes['class'] = $classes;
 
   $variables['primary_local_tasks'] = $variables['tabs'];
   unset($variables['primary_local_tasks']['#secondary']);
@@ -271,10 +269,8 @@ function seven_element_info_alter(&$type) {
  */
 function seven_preprocess_install_page(&$variables) {
   $page_object = $variables['page']['#page'];
-  $attributes = $page_object->getHtmlAttributes();
-  $classes = $attributes['class'];
-  $classes[] = 'install-background';
-  $attributes['class'] = $classes;
+  $variables['attributes'] = $page_object->getHtmlAttributes();
+  $variables['attributes']['class'][] = 'install-background';
 
   // Normally we could attach libraries via hook_page_alter(), but when the
   // database is inactive it's not called so we add them here.
@@ -294,10 +290,8 @@ function seven_preprocess_install_page(&$variables) {
  */
 function seven_preprocess_maintenance_page(&$variables) {
   $page_object = $variables['page']['#page'];
-  $attributes = $page_object->getHtmlAttributes();
-  $classes = $attributes['class'];
-  $classes[] = 'maintenance-background';
-  $attributes['class'] = $classes;
+  $variables['attributes'] = $page_object->getHtmlAttributes();
+  $variables['attributes']['class'][] = 'maintenance-background';
 
   // // Normally we could attach libraries via hook_page_alter(), but when the
   // // database is inactive it's not called so we add them here.
