Creating a Drupal 8 sub-theme, or sub-theme of sub-theme

Last updated on
14 February 2018

Sub-themes are just like any other theme, with one difference: they inherit the parent theme's resources. There are no limits on the chaining capabilities connecting sub-themes to their parents. A sub-theme can be a child of another sub-theme, and it can be branched and organized however you see fit. This is what gives sub-themes great potential.

To create a sub-theme you define your theme like any other theme and declare the base theme using the "base theme" key. Note that the key has no underscore.

Example sub-theme Fluffiness

This is an example of a sub-theme that uses Classy as a base theme.

This is the folder structure you'll end up with implementing the following files:

themes/
└──  fluffiness/
     ├── fluffiness.info.yml
     └── fluffiness.libraries.yml

The info file is named fluffiness.info.yml:

name: Fluffiness
type: theme
description: This is a fluffy sub theme of Classy
core: 8.x
# Defines the base theme
base theme: classy
# Defines libraries group in which we can add css/js.
libraries:
  - fluffiness/global-styling
# Regions
regions:
  header: Header
  featured: Featured
  content: Content
  sidebar_first: First sidebar
  sidebar_second: Second sidebar
  footer: Footer

Include fluffiness.libraries.yml file to add css/js in a global-style group, defined above in the libraries: key.

global-styling:
  css:
    component:
      css/style.css: {}

Read more about adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 theme.

If you want to use a different name instead of "fluffiness", just replace all occurrences of "fluffiness" with your own name ("all occurrences" includes the folder name too), for instance:

themes/
└──  my_custom_theme/
     ├── my_custom_theme.info.yml
     └── my_custom_theme.libraries.yml

The text you put in the "name:" line of the info.yml file is free and doesn't need to exactly match your theme name, for example that could be like this:

name: My Custom Theme
# (all the other lines omitted for brevity)

Sub-theme of a sub-theme

When creating a sub-sub-theme of a sub-theme, you must specify the sub-theme you want to extend as the base theme.

  • Fluffiness: First sub-theme of Classy
    name: Fluffiness
    type: theme
    description: This is a fluffy sub theme of Classy
    core: 8.x
    # Defines the base theme
    base theme: classy
    
  • Shaved: sub-theme of Fluffiness (sub-sub-theme of Classy)
    name: Shaved
    type: theme
    description: This is a reduced fluff sub theme of Fluffiness
    core: 8.x
    # Defines the base theme
    base theme: fluffiness
    

Inheriting Theme Regions

Theme regions are not automatically inherited from the specified base theme.  If the regions: parameter is left blank in your sub-theme's info.yml file or doesn't contain all regions from your base theme, then Drupal standard regions will be used for block placement in your sub-theme. We highly recommend copying all regions defined in your base theme into your sub-theme's info.yml file.

# This example demonstrates 2 levels of region inheritance from some of
# the standard Drupal regions (not all), additional custom regions from
# a base theme, plus 3 more colophon regions only define in the sub-theme.
regions:
  # 1. Standard Drupal regions (also defined and used by base theme).
  # 2. Custom base theme regions.
  # 3. Additional custom sub-theme regions.
  header:             'Header'                    # 1
  primary_menu:       'Main menu'                 # 1
  secondary_menu:     'Secondary menu'            # 1
  highlighted:        'Highlighted'               # 1
  help:               'Help'                      # 1
  section_nav:        'Section Nav'               # 2
  breadcrumb:         'Breadcrumb'                # 1
  page_title:         'Page Title'                # 2
  local_tasks:        'Local Tasks'               # 2
  content:            'Content (Constrained)'     # 1
  content_fullwidth:  'Content (Edge-to-edge)'    # 2
  colophon_first:     'Colophon First Col'        # 3
  colophon_second:    'Colophon Second Col'       # 3
  colophon_third:     'Colophon Third Col'        # 3
  footer:             'Footer'                    # 1

Inheriting Block Placement

In Drupal 8, themes may come with config/install/ folder where pre-defined block configurations—including placement into theme regions—will be imported upon enabling the theme. Drupal can inherit these block configurations and region placement from the base theme but if the theme regions defined in your sub-theme's info.yml file do not match those available in the base theme, unpredictable placements in random regions can occur. 

Inheriting Block Templates

If the theme you are extending has custom block templates these won't be immediately inherited because a sub-theme creates copies of all the blocks in the parent theme and renames them with the sub-theme's name as a prefix. Twig block templates are derived from the block's name, so this breaks the link between these templates and their block. Fixing this problem currently requires a hook in the sub-theme.  Following the examples above we'd create a file called shaved.theme in the sub-theme's directory.  In that file insert this hook.

/**
 * Implements hook_theme_suggestions_HOOK_alter for blocks.
 */
function shaved_theme_suggestions_block_alter(&$suggestions, $variables) {

  // Load theme suggestions for blocks from parent theme.
  foreach ($suggestions as &$suggestion) {
    $suggestion = str_replace('shaved_', 'fluffiness_', $suggestion);
  }
}

For your own sub-themes replace "shaved" with the name of your sub-theme, and "fluffiness" with the name of your base theme.

Differences with Drupal 7

The most notable difference with Drupal 7 is that .info files have become .info.yml files that use the YAML syntax