Skip to main content

Base themes without the bloat

Base themes in Drupal are incredibly useful but often add bloat to the finished sub-theme when care isn’t taken to remove unnecessary css files, or files that are 5% used and 95% overridden. When porting aGov to Drupal 8 we took the opportunity to improve how it’s theme inheritance is managed, making it easier to create trim, lightweight sub-themes.

by rikki.bochow /

Drupal 7 inheritance

In Drupal 7 you could remove a stylesheet by referencing it in your sub-themes .info file - regardless of if it came from core, another module or a base theme.

For example adding the following line to your theme would prevent the base theme from loading that file (let’s just pretend it does have one with this name);

stylesheets[all][] = component.primary-navigation.css

Which is great if you don’t want any of it’s CSS. If you’re adding your own css just give your file the same name and Drupal will load it instead of the base themes one - not in addition to.

The same goes for Javascript files.

Drupal 8 inheritance

Drupal 8 can do the same thing only way better! Drupal 8 themes can have Libraries. So can modules and profiles but we’ll just focus on themes. A library can be a collection of CSS and JS and can even list it’s dependencies. Here’s what a library might look like:

primary-navigation:
 version: 1.x
 css:
   component:
     css/components/primary-navigation/primary-navigation.css: {}
 js:
   sass/components/primary-navigation/primary-navigation.js: {}
 dependencies:
   - core/jquery

This bundles everything required for the primary navigation block into one easy to manage chunk. Those curly brackets can contain extra options, like { media: print }, or if it’s an external file like your Google font:

//fonts.googleapis.com/css?family=Open-sans: { type: external, minified: true }

But why bother breaking all your CSS components out like this?

If you’re like me, you use a CSS preprocessor like Sass and compile all your components, base styles and layouts into one CSS file. Which you can still do in your sub-theme if you like, but if you divvy up your base theme into discrete Libraries it’s super easy to toggle them on/off in your sub-theme!

Say your sub-theme has an entirely different vertical/offscreen/multi-level/hamburger navigation, and the base theme only gives you a simple horizontal nav? You don’t want any of the primary-navigation CSS, Javascript or dependencies from the base theme because you need to start from scratch.

Just override it in your theme’s .info.yml file:

libraries-override:
 base-theme-name/primary-navigation: false

You can remove a module, profile or core library the same way. Just want to override a library? Say you’re theme requires a more extended version of modernizr than comes with core:

libraries-override:
 core/modernizr:
  js:
    assets/vendor/modernizr/modernizr.min.js: js/modernizr.min.js

Note the last line references the original file and is followed by the new file we’re including in our theme.

Drupal still has the same option to remove individual CSS files (or JS files), which also goes in the .info.yml file and looks like the following:

stylesheets-remove:
- '@base-theme-name/css/base/normalize.css'

That @ symbol is a shortcut to that themes name so you don’t have to worry about the path to the theme, just it’s name - so @classy or @stable works just the same.

How this looks in aGov

The 8.x branch of aGov has taken this approach for the most part, though it could be extended. The base theme is monochromatic but does have a few styles included to make it easy for people to get started and not be distracted by its blueness.

They’ve been broken up into the following Libraries:

  • Base (normalize styles and basic typography)
  • Base Components (components that don’t change very often like system messages, breadcrumbs etc)
  • aGov Components (ones that do change often and are more likely to be overridden)
  • Layout (basically the grid system)

You can see the full breakdown on github.

Then the Starterkit theme lists all the libraries and individual stylesheets (though commented out) in their respective libraries-override and stylesheets-remove sections to make it super easy to disable them and create your own. Check out it’s .info.yml file on github.

Other Drupal 8 base themes

Stable in Drupal 8 core has a LOT of library overrides so worth a look at it’s examples. Classy is also worth a look, particularly at using the weights option.

Zen (https://www.drupal.org/project/zen) takes the Libraries approach in its Starterkit and is a great example of using components.

Omega 5 (https://www.drupal.org/project/omega) has quite a complex Libraries list so is handy to see just what’s possible.