Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dlh01/5726683 to your computer and use it in GitHub Desktop.
Save dlh01/5726683 to your computer and use it in GitHub Desktop.
Maintaining stylesheets for WordPress parent and child themes using Sass, Compass, and Grunt

This post outlines a way to use Sass, Compass, and Grunt to maintain stylesheets for a WordPress parent and child theme.

Sass is useful for many reasons, but for our purposes, the two most helpful features are partials and variables. We'll also take advantage of the importPath setting of Compass and Grunt.

Comments and improvements are always welcome.

Step 1: Create your parent stylesheet

Create a new Compass project in your theme and style away. When you're finished, your theme directory (called parent here) might look something like this:

parent/
├── css/
└── sass/
    ├── _base.scss
    ├── _media.scss
    ├── _typography.scss
    └── theme.scss

and theme.scss might look like:

@import "base";
@import "typography";
@import "media";
etc.

so that compiling theme.scss results in theme.css.

Step 2: Create parent-specific styles

Suppose that the main difference between our parent and child theme is the color scheme. We can start setting this up by, first, creating a new directory inside parent/sass. Call it parent-only for this example.

In the parent-only directory, create a partial to store the parent theme's color scheme. Make sure to use variables to define the colors. Then, of course, use the variables throughout your theme.

Our directory tree now looks like:

parent/
├── css/
└── sass/
    ├── parent-only/
        └── _colors.scss
    ├── _base.scss
    ├── _media.scss
    ├── _typography.scss
    └── theme.scss

_colors.scss might look like:

$primary: #ff0000;
$secondary: #0000ff;
$dark: #444444;
etc.

and theme.scss would now look like:

@import "base";
@import "colors";
@import "typography";
@import "media";
etc.

Step 3: Create child-specific styles

Create a directory in your child theme to hold Sass partials that will be specific to the child theme, as well as a directory for the compiled CSS. This results in a directory tree of:

parent/
├── css/
└── sass/
    ├── parent-only/
        └── _colors.scss
    ├── _base.scss
    ├── _media.scss
    ├── _typography.scss
    └── theme.scss
child/
├── css/
└── sass/

Next, create a _colors.scss file in our child theme's sass directory. This is where we specify the child theme's color scheme, using the same variables as the _colors.scss in the parent:

$primary: #ff00ff;
$secondary: #00ffff;
$dark: #444444;
etc.

giving us the directory tree:

parent/
├── css/
└── sass/
    ├── parent-only/
        └── _colors.scss
    ├── _base.scss
    ├── _media.scss
    ├── _typography.scss
    └── theme.scss
child/
├── css/
└── sass/
    └── _colors.scss

Step 4: Set up Grunt

For this method to work, we need to run Compass twice, with different settings each time. Grunt can help with that.

The Grunt website provides documentation on how to set up Grunt. You'll also need the grunt-contrib-compass plugin.

Once you've done that, create a task (called compass here) in your Gruntfile.js that looks like this:

compass: {
  options: {
    sassDir: 'sass',
    javascriptsDir: 'javascripts',
    fontsDir: 'fonts',
    outputStyle: 'compressed',
    environment: 'production'
  },
  parent: {
    options: {
      importPath: 'sass/parent-only',
      httpPath: '/wp-content/themes/parent/',
      cssDir: 'css/',
    }
  },
  child: {
    options: {
      importPath: '../child/sass/',
      cssDir: '../child/css/',
      httpPath: '/wp-content/themes/child/'
    }
  }
},

Taking each of the main sections in turn:

  • The options section defines settings common to the parent and child themes. Obviously, you can change outputStyle or environment as preferred, or add other options.

  • The parent section defines parent theme-specific settings. The most important of these is importPath. It tells Compass to search in the specified directory when looking for an @imported file if it can't find that file in the sassDir.

  • The child section defines the same settings, but with key differences. First, the importPath jumps into the sass directory of the child theme that we created earlier. Second, the cssDir is set to send our compiled CSS into the child theme.

So, running the compass task will compile theme.scss twice, resulting in wp-content/themes/parent/css/theme.css and wp-content/themes/child/css/theme.css.

importPath is where the magic happens. When Compass tries to compile theme.scss, it won't find _colors.scss in the sass directory. But importPath sends Compass to the parent or child theme and the _colors.scss file we created specifically for each.

5. The payoff

  1. We can change parent/sass/parent-only/_colors.scss and have it apply only to the parent theme.

  2. We can change child/sass/_colors.scss and have it apply only to the child theme.

  3. We can change parent/sass/_typography.scss, or _media.scss, or any other shared Sass file, and have the changes apply to both themes.

@allilevine
Copy link

This is really helpful, thanks! I was able to use it with Bones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment