diff --git a/core/modules/grid/config/grid.ninesixty_12.yml b/core/modules/grid/config/grid.ninesixty_12.yml
new file mode 100644
index 0000000..405317c
--- /dev/null
+++ b/core/modules/grid/config/grid.ninesixty_12.yml
@@ -0,0 +1,9 @@
+id: ninesixty_12
+label: '960px wide, 12 column grid'
+type: equal_column
+options:
+  type: 'fixed'
+  width: 960
+  columns: 12
+  padding_width: 20
+  gutter_width: 10
diff --git a/core/modules/grid/config/grid.ninesixty_16.yml b/core/modules/grid/config/grid.ninesixty_16.yml
new file mode 100644
index 0000000..4ddff62
--- /dev/null
+++ b/core/modules/grid/config/grid.ninesixty_16.yml
@@ -0,0 +1,9 @@
+id: ninesixty_16
+label: '960px wide, 16 column grid'
+type: equal_column
+options:
+  type: 'fixed'
+  width: 960
+  columns: 16
+  padding_width: 20
+  gutter_width: 10
diff --git a/core/modules/grid/config/grid.six_column_fluid.yml b/core/modules/grid/config/grid.six_column_fluid.yml
new file mode 100644
index 0000000..baff675
--- /dev/null
+++ b/core/modules/grid/config/grid.six_column_fluid.yml
@@ -0,0 +1,9 @@
+id: six_column_fluid
+label: Six column fluid
+type: equal_column
+options:
+  type: 'fluid'
+  width: 100
+  columns: 6
+  padding_width: 1.5
+  gutter_width: 2
diff --git a/core/modules/grid/config/grid.three_column_fluid.yml b/core/modules/grid/config/grid.three_column_fluid.yml
new file mode 100644
index 0000000..345e90c
--- /dev/null
+++ b/core/modules/grid/config/grid.three_column_fluid.yml
@@ -0,0 +1,9 @@
+id: three_column_fluid
+label: Three column fluid
+types: equal_column
+options:
+  type: 'fluid'
+  width: 100
+  columns: 3
+  padding_width: 1.5
+  gutter_width: 2
diff --git a/core/modules/grid/config/grid.twelve_column_fluid.yml b/core/modules/grid/config/grid.twelve_column_fluid.yml
new file mode 100644
index 0000000..35022f6
--- /dev/null
+++ b/core/modules/grid/config/grid.twelve_column_fluid.yml
@@ -0,0 +1,9 @@
+id: twelve_column_fluid
+label: Twelve column fluid
+type: equal_column
+options:
+  type: 'fluid'
+  width: 100
+  columns: 12
+  padding_width: 1.5
+  gutter_width: 2
diff --git a/core/modules/grid/grid.info b/core/modules/grid/grid.info
new file mode 100644
index 0000000..9dd6db4
--- /dev/null
+++ b/core/modules/grid/grid.info
@@ -0,0 +1,8 @@
+name = Grid
+description = Pluggable grid system manager.
+package = Core
+version = VERSION
+core = 8.x
+dependencies[] = config
+configure = admin/structure/grids
+
diff --git a/core/modules/grid/grid.module b/core/modules/grid/grid.module
new file mode 100644
index 0000000..0e2e5ba
--- /dev/null
+++ b/core/modules/grid/grid.module
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Pluggable grid system manager module.
+ */
+
+use Drupal\grid\Grid;
+
+/**
+ * Implements hook_entity_info().
+ */
+function grid_entity_info() {
+  $types['grid'] = array(
+    'label' => 'Grid',
+    'entity class' => 'Drupal\grid\Grid',
+    'controller class' => 'Drupal\Core\Config\Entity\ConfigStorageController',
+    'config prefix' => 'grid',
+    'entity keys' => array(
+      'id' => 'id',
+      'label' => 'label',
+      'uuid' => 'uuid',
+    ),
+  );
+  return $types;
+}
+
+function grid_help() {
+  $grid1 = entity_load('grid', 'six_column_fluid');
+  $grid2 = entity_load('grid', 'ninesixty_12');
+  return $grid1->getGridCss() . $grid2->getGridCss();
+}
diff --git a/core/modules/grid/lib/Drupal/grid/Grid.php b/core/modules/grid/lib/Drupal/grid/Grid.php
new file mode 100644
index 0000000..236df5b
--- /dev/null
+++ b/core/modules/grid/lib/Drupal/grid/Grid.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\grid\Grid.
+ */
+
+namespace Drupal\grid;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\grid\Plugin\GridInterface;
+
+/**
+ * Defines the grid entity.
+ */
+class Grid extends ConfigEntityBase implements GridInterface {
+
+  /**
+   * The grid ID (machine name).
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The grid UUID.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * The grid label.
+   *
+   * @var string
+   */
+  public $label;
+
+  /**
+   * Plugin identifier for this grid.
+   *
+   * @var string
+   */
+  public $pluginId;
+
+  /**
+   * Plugin configuration to instantiate the plugin instance.
+   *
+   * @var array
+   */
+  public $pluginConfiguration;
+
+  /**
+   * Instantiated plugin to handle the grid.
+   *
+   * @see Drupal\grid\Grid::GetPlugin().
+   *
+   * @var Drupal\grid\Plugin\GridInterface
+   */
+  public $plugin;
+
+  /**
+   * Get a plugin instance for this grid.
+   */
+  public function getPlugin() {
+    if (!isset($this->plugin)) {
+      // Pass on Grid ID as part of the configuration array.
+      $this->options['id'] = $this->id;
+      $this->plugin = drupal_container()->get('plugin.manager.grid')->createInstance($this->type, $this->options);
+    }
+    return $this->plugin;
+  }
+
+  /**
+   * Implements Drupal\grid\Plugin\GridInterface::getGridCss().
+   */
+  public function getGridCss($wrapper_selector = NULL, $col_selector_prefix = NULL, $skip_spacing = FALSE) {
+    return $this->getPlugin()->getGridCss($wrapper_selector, $col_selector_prefix, $skip_spacing);
+  }
+
+}
diff --git a/core/modules/grid/lib/Drupal/grid/GridBundle.php b/core/modules/grid/lib/Drupal/grid/GridBundle.php
new file mode 100644
index 0000000..7c68f29
--- /dev/null
+++ b/core/modules/grid/lib/Drupal/grid/GridBundle.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\grid\GridBundle.
+ */
+
+namespace Drupal\grid;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Grid dependency injection container.
+ */
+class GridBundle extends Bundle {
+
+  /**
+   * Overrides Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   */
+  public function build(ContainerBuilder $container) {
+    // Register the GridManager class with the dependency injection container.
+    $container->register('plugin.manager.grid', 'Drupal\grid\Plugin\Type\GridManager');
+  }
+}
diff --git a/core/modules/grid/lib/Drupal/grid/Plugin/GridInterface.php b/core/modules/grid/lib/Drupal/grid/Plugin/GridInterface.php
new file mode 100644
index 0000000..ca73fd8
--- /dev/null
+++ b/core/modules/grid/lib/Drupal/grid/Plugin/GridInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\grid\Plugin\GridInterface.
+ */
+
+namespace Drupal\grid\Plugin;
+
+/**
+ * Defines the shared interface for all grid plugins.
+ */
+interface GridInterface {
+
+  /**
+   * Generates grid CSS for this grid system.
+   *
+   * @param (string) $wrapper_selector
+   *   (optional) Wrapper CSS selector to use to scope the CSS.
+   * @param (string) $col_selector_prefix
+   *   (optional) Column selector prefix to scope the CSS.
+   * @param (boolean) $skip_spacing
+   *    Whether we should skip including spacing in the output. Useful for tight
+   *    layout demonstration presentation.
+   *
+   * @return string
+   *   Grid CSS for this grid system.
+   */
+  public function getGridCss($wrapper_selector = NULL, $col_selector_prefix = NULL, $skip_spacing = FALSE);
+}
diff --git a/core/modules/grid/lib/Drupal/grid/Plugin/Type/GridManager.php b/core/modules/grid/lib/Drupal/grid/Plugin/Type/GridManager.php
new file mode 100644
index 0000000..f86ec60
--- /dev/null
+++ b/core/modules/grid/lib/Drupal/grid/Plugin/Type/GridManager.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\grid\Plugin\Type\GridManager.
+ */
+
+namespace Drupal\grid\Plugin\Type;
+
+use Drupal\Component\Plugin\PluginManagerBase;
+use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
+use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
+use Drupal\Component\Plugin\Factory\ReflectionFactory;
+
+/**
+ * Grid plugin manager.
+ */
+class GridManager extends PluginManagerBase {
+
+  /**
+   * Overrides Drupal\Component\Plugin\PluginManagerBase::__construct().
+   */
+  public function __construct() {
+    $this->discovery = new AnnotatedClassDiscovery('grid', 'grid');
+    $this->factory = new ReflectionFactory($this);
+  }
+}
diff --git a/core/modules/grid/lib/Drupal/grid/Plugin/grid/grid/EqualColumn.php b/core/modules/grid/lib/Drupal/grid/Plugin/grid/grid/EqualColumn.php
new file mode 100644
index 0000000..db38826
--- /dev/null
+++ b/core/modules/grid/lib/Drupal/grid/Plugin/grid/grid/EqualColumn.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\grid\Plugin\grid\grid\EqualColumn.
+ */
+
+namespace Drupal\grid\Plugin\grid\grid;
+
+use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
+use Drupal\grid\Plugin\GridInterface;
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * @Plugin(
+ *  id = "equal_column"
+ * )
+ */
+class EqualColumn extends PluginBase implements GridInterface {
+
+  /**
+   * Implements Drupal\grid\Plugin\GridInterface::getGridCss().
+   */
+  public function getGridCss($wrapper_selector = NULL, $col_selector_prefix = NULL, $skip_spacing = FALSE) {
+    $grid = $this->configuration;
+    $css = '';
+
+    // If the wrapper selector was not provided, generate one. This is useful for
+    // specific administration use cases when we scope the classes by grids.
+    if (empty($wrapper_selector)) {
+      $wrapper_selector = '.grid-' . $grid['id'];
+    }
+
+    // If the col span selector was not provided, generate one. This is useful
+    // for the front end to apply varying span widths under different names.
+    if (empty($col_selector_prefix)) {
+      $col_selector_prefix = '.grid-col_';
+    }
+
+    // If spacing is to be skipped, override the gutter and padding temporarily.
+    if ($skip_spacing) {
+      $grid['gutter_width'] = $grid['padding_width'] = 0;
+    }
+
+    switch ($grid['type']) {
+      case 'fluid':
+        $size_suffix = '%';
+        // Override to 100% whatever it was.
+        $grid['width'] = '100';
+        break;
+      case 'fixed':
+        $size_suffix = 'px';
+        break;
+    }
+
+    // Because we use the border-box box model, we only need to substract the
+    // size of margins from the full width and divide the rest by number of
+    // columns to get a value for column size.
+    $colwidth = ($grid['width'] - (($grid['columns'] - 1) * $grid['gutter_width'])) / $grid['columns'];
+
+    $css = $wrapper_selector . ' .grid-col {
+  border: 0px solid rgba(0,0,0,0);
+  float: left;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -moz-background-clip: padding-box;
+  -webkit-background-clip: padding-box;
+  background-clip: padding-box;
+  margin-left: ' . $grid['gutter_width'] . $size_suffix . ';
+  padding: 0 ' . $grid['padding_width']  . $size_suffix . ';
+}
+' . $wrapper_selector . ' .grid-col' . $col_selector_prefix .'first {
+  margin-left: 0;
+  clear: both;
+}
+';
+    for ($i = 1; $i <= $grid['columns']; $i++) {
+      $css .= $wrapper_selector . ' ' . $col_selector_prefix . $i . " {\n";
+      if ($i == 1) {
+        // The first column does not yet have any margins.
+        $css .= '  width: ' . $colwidth * $i . $size_suffix . ";\n";
+      }
+      elseif ($i == $grid['columns']) {
+        // The full width column always spans 100%.
+        $css .= "  width: " . $grid['width'] . $size_suffix . ";\n  margin-left: 0;\n";
+      }
+      else {
+        // Other columns absorb all columns that they need to include and one
+        // less margin before them.
+        $css .= '  width: ' . (($colwidth * $i) + ($grid['gutter_width'] * ($i -1))) . $size_suffix . ";\n";
+      }
+      $css .= "}\n";
+    }
+
+    return $css;
+  }
+
+}
