Skip to main content

Drupal 8 Theming Guide

Drupal 8 Theming

In our earlier article, we had a solid understanding of Drupal 8 theming. In this post, we're going to dig into the theming fundamentals, files for styles, JS, CSS, library, Twig templates , adding new regions, attach the library to all the pages and working with breakpoints in Drupal 8 development.

Creating a Drupal 8 sub-theme

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.

Create an .info.yml file

To create a Drupal 8 theme you need to first create a file that provides meta-data about your theme to Drupal. This is similar to how modules and installation profiles are being defined, and as such it is important to set the 'type' key in the .info.yml file to 'theme' in order to differentiate it.

If your theme is named “Flower" then the folder is named “flower/" and the .info.yml file is named "flower/"

name: Flower
type: theme
description: 'A flower theme that offers extra fluffiness.'
package: Custom
core: 8.x
  - flower/globalstyling
  - '@classy/css/layout.css'
  - core/assets/vendor/normalize-css/normalize.css
  header: Header
  content: Content
  sidebar_first: 'Sidebar first'
  footer: Footer

Folder Structure

In Drupal 8, we can use the "themes" folder to add a new theme. You should note that Drupal core themes such as Bartik and Seven are located in the core/themes folder of your installation.

The best practice is to place the contributed themes in a sub folder named "contrib" and your own themes in a folder named "custom".

Here are some examples of files and folders that are structured in the new theme folder structure:

 |  |-install
 |  |  |-flower.settings.yml
 |  |-schema
 |  |  |-flower.schema.yml
 |  |-style.css
 |  |-flower.js
 |  |-buttons.png
 |  |-maintenance-page.html.twig
 |  |-node.html.twig

Twig in Drupal 8

Twig is a template engine for PHP and it is part of the Symfony2 framework. One of the results of this change is that all of the theme_* functions and PHPTemplate based *.tpl.php files have been replaced in by *.html.twig template files. Learn how to use the twig template engine in Drupal 8.

Adding Regions to a Theme

Adding region meta-data to your file
- Editing your page.html.twig file and printing the new regions

Declaring any new regions in your file. Regions are declared as children of the regions key like so:

# Regions
  header: 'Header'
  content: 'Content'
  footer: 'Footer'


header: 'Header'
Will become:

{{ page.header }}

In your Twig templates.

Adding (CSS) and JavaScript (JS) to a Drupal 8 theme

In Drupal 8, stylesheets (CSS) and JavaScript (JS) are loaded through the same system for modules (code) and themes.

Defining a library

To define one or more (asset) libraries, add a *.libraries.yml file to your theme folder. (If your theme is named fluffiness, then the file name should be fluffiness.libraries.yml). Each "library" in the file is an entry detailing CSS and JS files (assets)

Defining JS files

  version: 1.x
      css/cuddly-slider.css: {}
    js/cuddly-slider.js: {}
    - core/jquery

Defining CSS file

Defining CSS file
  version: 1.x
      css/layout.css: {}
      css/style.css: {}
      css/colors.css: {}
      css/print.css: { media: print }

Attaching a library file

  • Attaching a library to All page(s)

    To attach a library to all the pages on the site that use your theme, declare it in your theme's *.info.yml file, under the libraries key:

    name: Flower
    type: theme
    core: 8.x
      - flower/cuddly-slider

    You can list as many libraries as you want, all of them will be loaded on every page.

  • Attaching a library to a subset of pages :

    A theme can make this happen by implementing a THEME_preprocess_HOOK() function in the .theme file, replacing "THEME" with the machine name of your theme and "HOOK" by the machine name of the theme hook.

    For instance, if you want to attach JavaScript to the maintenance page, the "HOOK" part is "maintenance_page", and your function would look like this:

        function flower_preprocess_maintenance_page(&$variables) {
           $variables['#attached']['library'][] = 'flower/cuddly-slider';

Including Default Image Styles With Your Theme

The process for including an image style in your theme is similar to that of including default configuration in a module.

  • Create the Image Style you wish to include using the UI
  • Export the Image Style as YAML
  • Include the exported YAML in the config/install directory of your theme following the appropriate naming convention.
  • Start by creating an image style using the admin UI at Configuration > Image Styles (admin/config/media/image-styles). Once the image style has been created and saved, the configuration that makes up that image style will be stored in your site's active config.

This configuration can be exported using:

  • Single import/export tool at Configuration > Configuration management > Single Import/Export > Export (admin/config/development/configuration/single/export).
  • From the configuration type select list choose "Image style" then choose your image style from the configuration name select list.

Example: flower/config/install/

langcode: en
status: true
dependencies: {  }
name: black_white
label: 'black & white'
    uuid: 8d4f85cc-9a2d-4a30-af15-21b0833dc06d
    id: image_desaturate
    weight: 1
    data: {  }
third_party_settings: {  }

Working with breakpoints in Drupal 8

Breakpoint's properties

  • label - A human readable label for the breakpoint.
  • mediaQuery - Media query text proper all and (min-width: 851px).
  • weight - Positional weight (order) for the breakpoint.
  • multipliers - Supported pixel resolution multipliers.

Example: flower.breakpoints.yml
label: mobile
mediaQuery: ''
weight: 2
    - 1x
  label: narrow
  mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)'
  weight: 1
    - 1x
  label: wide
  mediaQuery: 'all and (min-width: 851px)'
  weight: 0
    - 1x

I hope this Drupal 8 theming guide illuminates the fundamentals of getting a theme started so that you can use it for Drupal projects.


Leave Your Comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.

start with anubavam today

You have an idea we have engineers to convert your ideas into reality

Request Quote