Chasing The Dream of Style Guide Driven Development in Drupal 8

Brian Perry

Breakthrough Technologies

Brian Perry

@bricomedy / brianperry

Breakthrough Technologies

So what exactly is Style Guide Driven Development anyway?

Decoupling of front and back end development

Theming doesn't have to come last















(Mario Kart Version)







The Living Style Guide

A Living Style Guide

  1. Is modular and re-usable
Atomic Design - design systems of components, not pages
Atomic Design Overview

A Living Style Guide

  1. Is modular and re-usable
  2. Uses real world css and markup
  3. Is always kept up to date
  4. Is testable

Has this ever happened to you?

Infomercial Saran Wrap Fail

One tiny css change causes a regression deep in the outer reaches of your site

(and, it goes unnoticed for lord knows how long)

Visual Regresison Diff for Teaser

Get to the Drupals Already...

Drupal 8 wants you to build better themes

Cleaner Markup

Base Themes

  • Classy
  • Stable

Clearer seperation between logic and display

	set classes = [
		'block-' ~ configuration.provider|clean_class,
		'block-' ~ plugin_id|clean_class,
< div {{ attributes.addClass(classes) }}>

(From block.html.twig)

{% if attributes.hasClass('myClass') %}
  {# do stuff #}
{% endif %}

Tools to Create Modular, Re-usable components

CSS Coding Standards

Seven CSS Folder Structure


  1. Base
  2. Layout
  3. Component (aka Module)
  4. State
  5. Theme (aka Skin)


Naming convention for components

  • Block
  • Element
  • Modifier

.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}
Seven Pager Components

Twig Extends


Default field.html.twig

Twig Blocks

Custom field.html.twig

Custom Field Template With Blocks

Twig Extends


Extended Field Template

Creating Your Style Guide

Style Guide API



Customized Style Guide Components
Customized Style Guide Categories

Style Guide D8 Port In-Progress

Style Guide Generators to the Rescue

Many options

  • Pattern Lab
  • Hologram
  • KSS


  • Human readable documentation syntax
  • Any flavor of CSS
  • Node JS implementation
  • Grunt plugin


(There's a module for that...)

npm install kss --save-dev

npm install grunt-kss --save-dev


Homepage Solutions Section

KSS Syntax

// Solution Teaser
// A teaser for solutions taxonomy as displayed on the homepage
// Markup: kss_markup/solution_teaser.html
// Style Guide: Solutions.Teaser
.view-solutions .views-row {
  .views-field-field-category-icon .col-xs-3 {
    padding: 3%;
    border-radius: 50%;
    background-color: $gray_light;
    img {
      @extend .img-responsive;

Build Style Guide

grunt kss


kss-node --source sass --destination styleguide --css css/style.css

KSS Solutions Teaser Output

Testing Your Style Guide and Theme


Behavior Driven Development Framework

Scenario: Footer style matches style guide
  Given I am an anonymous user
  And I am on "assessments/practice-assessments"
  When I am browsing using a "phone"
  Then "body" should have a "background-color" css value of "rgb(112, 84, 125)"
  And "#page" should have a "background-color" css value of "rgb(255, 255, 255)"
  And "footer" should have a "padding-top" css value of "50px"
  And "footer" should have a "padding-bottom" css value of "30px"

View Gist for detail of steps

BBC Mobile Screenshot Diff


Screenshot Comparison Tool

  • Compares two URLs
  • Simple configuration
  • Typically 'all or nothing' diffs
Wraith Screenshot Report

Phantom CSS

CSS Regression Testing

Phantom CSS Diff Screenshot
  • PhantomJS/SlimerJS - Headless Browser
  • CasperJS - Navigation and Scripting
  • ResembleJS - Screenshot Comparison

Strengths: interactivity, easier to target components.


Selenium Bindings for NodeJS

WebdriverIO Robot Logo
  • Selenium - Browser Automation
  • WebdriverIO - Node library to drive selenium
  • WebdriverCSS - CSS Regression Testing

Strengths: interactivity, easier to target components.


npm install webdriverio@3.4.0 webdrivercss@2.0.0beta-rc1 selenium-standalone --save-dev

./node-modules/.bin/selenium-standalone install

Creating a Test


var wdio = require("webdriverio");
var webdrivercss = require("webdrivercss");
var assert = require("assert");

var options = {
  desiredCapabilities: {
    browserName: "chrome"
var browser = wdio.remote(options);
webdrivercss.init(browser, {
  screenshotRoot: "screenshots"

function assertShots (err, shots) {

  Object.keys(shots).forEach(function(element) {
    shots[element].forEach(function(shot) {
      assert.ok(shot.isWithinMisMatchTolerance, shot.message);

  .webdrivercss("solutions", [
      name: "solution teaser",
      elem: ".view-solutions .views-row:first-child"
  ], assertShots)
  .webdrivercss("navigation", [
      name: "Off Canvas Menu",
      elem: ".sidebar-offcanvas"
  ], assertShots)
Phantom Generated Screenshot of Solutions Teaser

Chasing the dream?

Still Chasing...

  • My workflow - tools continue to evolve
  • Component Based Rendering Initiative
  • Drupal and Style Guide Sharing Markup
Zen Theme
MVC vs MVP diagram

Component Based Rendering Initiative #components