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
theme.scss might look like:
@import "base"; @import "typography"; @import "media"; etc.
so that compiling
theme.scss results in
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.
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.
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.
Once you've done that, create a task (called
compass here) in your
Gruntfile.js that looks like this:
Taking each of the main sections in turn:
optionssection defines settings common to the parent and child themes. Obviously, you can change
environmentas preferred, or add other options.
parentsection 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
childsection defines the same settings, but with key differences. First, the
importPathjumps into the
sassdirectory of the child theme that we created earlier. Second, the
cssDiris set to send our compiled CSS into the child theme.
So, running the
compass task will compile
theme.scss twice, resulting in
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
We can change
parent/sass/parent-only/_colors.scssand have it apply only to the parent theme.
We can change
child/sass/_colors.scssand have it apply only to the child theme.
We can change
_media.scss, or any other shared Sass file, and have the changes apply to both themes.