Creating a Drupal 8 Theme with Sass,Singularity & Breakpoint
On this page
In this post I wanted to share my experience of setting up a new Drupal 8 theme.
I wanted to take Drupal 8 for a spin and familiarize myself with the new TWIG template system and other theming changes, so I set out with a goal of creating a simple, clean, minimal configurations blog theme. I called it "Formata." Sounds like a cool name, right?
Demo (opens in new window) of the theme.
You can also Download or Clone it from GitHub (opens in new window)
What is included in this theme:
- Drupal's 8 TWIG based (obviously)
- SASS partials structure
- Singularity Grid System (opens in new window) for responsive grids
- Breakpoint (opens in new window) media queries in Sass
- Typecsset (opens in new window) for vertical rhythm typography
- Code syntax highlighting (opens in new window) with Rainbow
- Naver (opens in new window) A jQuery plugin for responsive navigation
- Google Fonts (opens in new window) Merriweather Serif and Sans-serif families
- Font Awesome Icons (opens in new window)
Installing Drupal 8
You can find the latest Drupal 8 Release here (opens in new window) or on Github (opens in new window)
As of writing this we are at drupal 8.0-alpha8. Once you have that set up on your environment, be cautious about making upgrades and installing contrib modules (if they exist for D8). At this point Drupal 8 is in active development, so things can change and break very easily. As always, Clear Cache often and backup your Database.
Drush
I had to upgrade the Drush (opens in new window) install in order to use it with D8. Since I am using homebrew (opens in new window) all I had to do was: $ brew unlink drush then $ brew install --HEAD drush. Also the drush cache-clear all or drush cc all command is deprecated for Drupal 8 so instead I had to use drush cache-rebuild or the short version drush cr command.
If you are using Sublime or Textmate you might find this Twig syntax highlighting and auto-completion plugin (opens in new window) useful.
Setting up the theme
I started looking into the D8 theme set up by reverse engineering an existing core theme. You can use Bartic or Stark (opens in new window) (now a core theme). These themes were specifically useful and helped me better understand the new API, TWIG syntax, and different variables. There are other contrib themes that are actively being ported to Drupal 8 and have lots of good stuff in them. I've looked at adaptivetheme (opens in new window) and gratis (opens in new window) as an example. For more info check out D8's documentation (opens in new window) or this post I put together earlier about D8 resources: Top Resources for Getting Started with Drupal 8
Theme directory
Your custom theme now goes into a "theme" directory in the root and not in the "/sites/all/themes" as we had gotten used to in Drupal 7.
.info file becomes theme_name.info.yml. Drupal 7's .info file was proprietary to Drupal. Now D8 has adopted the YAML format which is a standard for many programming languages. The advantage of YAML is that it uses a specific standard that's supported by other libraries.
Adding stylesheets
# Add a CSS file: stylesheets: all: - css/style.css
You can also remove a system stylesheet. For example drupal.base.css is now replaced by normalize.css (opens in new window) but in my theme I've removed it as I am using compass reset
# Remove a CSS file: stylesheets-remove: - normalize.css
If you want to include a different version of normalize.css, you can also do an override:
# Override a CSS file stylesheets-override: - normalize.css
Same with adding javascript files
# scripts: - js/custom-script.js
Setting up regions
regions: content: 'Content' sidebar: 'Sidebar' footer: 'Footer'
As you can see this is pretty straight forward, and not very different from D7.
page.html.twig
All theme files are now html.twig instead of .tpl.php. For example "page.html.twig" and variables in the template use twig syntax.
{% if page.sidebar %} {{ page.sidebar }} {% endif %}
template.php becomes theme_name.theme
Libraries and Scripts
By default Drupal 8 doesn't load any additional scripts. So jQuery is not there, you have to declare it as a dependency. Drupal 8 now comes with Backbone.js (opens in new window) and Underscore.js (opens in new window) which can also be your dependencies.
drupal_add_js and drupal_add_css are deprecated so we need to use hook_library_info to declare jQuery and Modernizer as dependencies. For all core assets look into /core/assets/vendor
Here is an example of how I ended up bringing in custom javascrpt and its dependencies
function formata_library_info() { // Add jquery as a dependancy on script.js $libraries['formata.corescripts'] = array( 'title' => 'Adding all scripts and dependencies', 'version' => '1.0', 'js' => array( drupal_get_path('theme', 'formata') . '/js/jquery.fs.naver.min.js' => array(), drupal_get_path('theme', 'formata') . '/js/jquery.scrollUp.min.js' => array(), drupal_get_path('theme', 'formata') . '/js/rainbow/rainbow.min.js' => array(), drupal_get_path('theme', 'formata') . '/js/rainbow/rainbow.linenumbers.min.js' => array(), drupal_get_path('theme', 'formata') . '/js/rainbow/language/generic.js' => array(), drupal_get_path('theme', 'formata') . '/js/script.js' => array(), ), 'dependencies' => array( array('system', 'jquery'), array('system', 'modernizr'), ), ); return $libraries; } drupal_add_library('formata', 'formata.corescripts');
For external CDNs I used this
function formata_css_alter(&$css) { $theme_path = drupal_get_path('theme', 'formata'); // Add googlefonts. $googlefonts = '//fonts.googleapis.com/css?family=Merriweather:300,300italic,700,700italic,400,400italic|Merriweather+Sans:400,400italic,700,700italic,300italic,300'; $css[$googlefonts] = array( 'data' => $googlefonts, 'type' => 'external', 'every_page' => TRUE, 'media' => 'all', 'preprocess' => FALSE, 'group' => CSS_AGGREGATE_THEME, 'browsers' => array('IE' => TRUE, '!IE' => TRUE), 'weight' => -1, ); // Add FontAwesome. $fontawesome = '//netdna.bootstrapcdn.com/font-awesome/4.0.1/css/font-awesome.min.css'; $css[$fontawesome] = array( 'data' => $fontawesome, 'type' => 'external', 'every_page' => TRUE, 'media' => 'all', 'preprocess' => FALSE, 'group' => CSS_AGGREGATE_THEME, 'browsers' => array('IE' => TRUE, '!IE' => TRUE), 'weight' => -2, ); }
Gem file and Bundler set up
I used sass, compass, Singularity (opens in new window) for responsive grids and Breakpoint (opens in new window) for media queries. These gems had to be declared as dependencies in my gemfile, and Bundler (opens in new window) takes care of the rest.
Sass Structure and Partials
This part is not necessarily Drupal 8 specific and I will not go into too much detail about it here, it just helps me keep things organized. I have to credit @Snugug (opens in new window) and Team Sass (opens in new window) for all the great tools they produce. This theme's structure is very similar to Drupal's Aurora (opens in new window) which I use for all my D7 projects. I like this set up and I've adopted the structure with some modifications here:
├── partials │ ├── design │ │ └── _design.scss │ ├── global │ │ ├── _base.scss │ │ ├── _extendables.scss │ │ ├── _functions.scss │ │ ├── _mixins.scss │ │ ├── _typecsset.scss │ │ └── _variables.scss │ ├── layout │ │ └── _layout.scss │ ├── navigation │ │ └── _navigation.scss │ └── typography │ └── _typography.scss └── style.scss
All the responsive stuff is done with Singularity (opens in new window) and Breakpoint (opens in new window) which are great additions to my workflow.
For example if for a medium breakpoint I need my main content to span the width of 5 columns starting on the 3rd column, and 7 columns for a large breakpoint, I can declare it with these singularity's mixins:
#main-content { @include breakpoint($break-medium) { @include grid-span(5, 3); } @include breakpoint($break-large) { @include grid-span(7, 3); } }
Typography and Vertical Rhythm
For Vertical Rhythm I've tried Typecsset (opens in new window)which is a small Sass library for setting type on the web. It gives you an automatic, pixel-perfect, baseline grid.
$typecsset-base-font-size: 16px; $typecsset-base-line-height: 24px; $typecsset-show-baseline: true;
In conclusion
Overall, my experience with D8 theming was great. There is obviously more to learn about the new API, TWIG, and hook system, which I intend to explore as D8 gains more prominence.
Once again you can view the theme here: Demo (opens in new window)
And Download or clone it on GitHub (opens in new window)