---
title: "Creating a Drupal 8 Theme with Sass,Singularity & Breakpoint · Appnovation"
url: "https://www.appnovation.com/insights/creating-drupal-8-theme-sasssingularity-breakpoint"
description: "How to set up a clean, minimal Drupal 8 theme using Twig, Sass, Singularity grids and Breakpoint for responsive layouts."
---

Article

# Creating a Drupal 8 Theme with Sass,Singularity & Breakpoint

[![](https://cdn.sanity.io/images/ey850001/production/d554cb30b50f2e0f5ec2f886c627b6f37dd65b94-68x68.png?w=68&auto=format) azvonkov azvonkov Senior Front End Developer](/people/azvonkov-azvonkov.md) Feb 11, 2014  
 8 min read 

![Creating a Drupal 8 Theme with Sass,Singularity & Breakpoint](https://cdn.sanity.io/images/ey850001/production/830314586984b64ef8b3599dfe2ec67d7b5ae5fd-680x200.jpg?w=1400&auto=format) 

On this page

## On this page

In this post I wanted to share my experience of setting up a new [Drupal 8 theme.](/services/drupal-development.md)

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)](http://drupal8.subtleshift.net)** of the theme.

You can also Download or Clone it from [GitHub (opens in new window)](https://github.com/zetagraph/formata)

## What is included in this theme:

*   Drupal's 8 TWIG based (obviously)
*   SASS partials structure
*   [Singularity Grid System (opens in new window)](http://singularity.gs) for responsive grids
*   [Breakpoint (opens in new window)](https://github.com/Team-Sass/breakpoint) media queries in Sass
*   [Typecsset (opens in new window)](https://github.com/csswizardry/typecsset) for vertical rhythm typography
*   [Code syntax highlighting (opens in new window)](http://craig.is/making/rainbows) with Rainbow
*   [Naver (opens in new window)](http://formstone.it/components/naver) A jQuery plugin for responsive navigation
*   [Google Fonts (opens in new window)](https://www.google.com/fonts/specimen/Merriweather) Merriweather Serif and Sans-serif families
*   [Font Awesome Icons (opens in new window)](http://fontawesome.io/icons)

## Installing Drupal 8

You can find the latest Drupal 8 Release [here (opens in new window)](https://drupal.org/node/3060/release?api_version%5B%5D=7234) or on [Github (opens in new window)](https://github.com/drupal/drupal/tree/8.x)

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)](http://drush.ws) install in order to use it with D8. Since I am using [homebrew (opens in new window)](http://brew.sh) 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)](https://github.com/Anomareh/PHP-Twig.tmbundle) 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)](https://api.drupal.org/api/drupal/core%21themes%21stark%21README.txt/8) (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)](https://drupal.org/project/adaptivetheme) and [gratis (opens in new window)](https://drupal.org/project/gratis) as an example. For more info check out [D8's documentation (opens in new window)](https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Render!theme.api.php/group/themeable/8.2.x) or this post I put together earlier about D8 resources: [Top Resources for Getting Started with Drupal 8](/insights/top-resources-getting-started-drupal-8.md)

### 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)](https://drupal.org/node/2168417) 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)](https://drupal.org/node/2053901) and [Underscore.js (opens in new window)](https://drupal.org/node/2053901) 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)](http://singularity.gs) for responsive grids and [Breakpoint (opens in new window)](https://github.com/Team-Sass/breakpoint) for media queries. These gems had to be declared as dependencies in my gemfile, and [Bundler (opens in new window)](http://bundler.io/) 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)](https://github.com/snugug/) and [Team Sass (opens in new window)](https://github.com/Team-Sass) for all the great tools they produce. This theme's structure is very similar to Drupal's [Aurora (opens in new window)](https://drupal.org/project/aurora) 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)](https://github.com/Team-Sass/Singularity) and [Breakpoint (opens in new window)](https://github.com/Team-Sass/breakpoint) 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)](https://github.com/csswizardry/typecsset)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)](http://drupal8.subtleshift.net)**

And Download or clone it[on GitHub (opens in new window)](https://github.com/zetagraph/formata)

[![](https://cdn.sanity.io/images/ey850001/production/d554cb30b50f2e0f5ec2f886c627b6f37dd65b94-68x68.png?w=68&auto=format) azvonkov azvonkov Senior Front End Developer · Appnovation](/people/azvonkov-azvonkov.md) 

## Keep reading

[![What is Sovereign AI](https://cdn.sanity.io/images/ey850001/production/a5889abdd5e80376912546622e046e3fbef234b4-2496x1664.png?w=640&auto=format)](/insights/what-is-open-source-sovereign-ai.md)

 Article · 7 min AI 

### [What Is Open Source, Sovereign AI?](/insights/what-is-open-source-sovereign-ai.md)

Every company is encouraging more AI, and almost every AI bill is climbing. Sovereign AI is about two kinds of control: over your data and over your costs. Here's why open source sits at its foundation.

[Iain MacNeil](/people/iain-macneil.md) Article 

[![AI-first experience design](https://cdn.sanity.io/images/ey850001/production/8bbc2418e87924ef10f36115478a2e10d5bed95e-1584x624.jpg?w=640&auto=format)](/insights/how-build-ai-first-experience-without-throwing-out-everything-youve-already-built.md)

 Article · 6 min AI Sep 10, 2026 

### [How to Build an AI-First Experience Without Throwing Out Everything You've Already Built](/insights/how-build-ai-first-experience-without-throwing-out-everything-youve-already-built.md)

Users now expect a direct answer, not a list of links to click through. Here's how organizations can layer an AI-First experience onto their existing website or app, in weeks rather than years.

[Andrew Douglas](/people/andrew-douglas.md) Article 

[![What Becomes Possible When AI Can Read All the Data](https://cdn.sanity.io/images/ey850001/production/c28ab0bd26753421ee42937e13adc7a7f19b47f0-1296x510.jpg?w=640&auto=format)](/insights/what-becomes-possible-when-ai-can-read-all-data.md)

 Article · 4 min AI Sep 09, 2026 

### [What Becomes Possible When AI Can Read All the Data](/insights/what-becomes-possible-when-ai-can-read-all-data.md)

Most of the world's data has never been analyzed, only sampled. AI changes that. How AI-ready data platforms unlock questions no one could ask before.

[Appnovation](/people/appnovation.md) Article 

## Get the thinking,  
*before everyone else.*

One considered email a month. New essays, field notes from live engagements, and the occasional strong opinion. No noise.
