by Alexandra Atzl
Being relatively new to Drupal, I was overwhelmed recently by the task of implementing a base theme and three sub-themes for a customized system of Drupal sites we were developing at Singlebrook. I needed a clear, simple way to write the necessary CSS code, without having to repeat it up to four times.
The basic principle governing this entire project was to be as lightweight as possible. We wanted an end product with no repetitive or unnecessary code, and that would be relatively future-proof. Across the board, we strove to avoid unnecessary modules and to create our own custom ones to perform just the functionality we needed; no more and no less. We avoided Views, made generous use of Drupal hooks and theme functions, and ended up with a site that does what we want, without overly-large modules and excess code slowing it down.
On the theming side, we knew we needed to deliver three different themes to the client (#1, #2, & #3), plus an additional base theme, which would mostly mirror theme #2. We also knew we wanted to use SASS (now that I've begun using it, I'm completely reluctant to return to plain ol' CSS, and I think all of Singlebrook agrees).
Jeff A, one of our Drupal developers, set up a clever Guardfile in each of our themes that would run Compass to compile our SASS files, and then run LiveReload on a specified port to immediately reload our browser windows any time a .css or .js file was saved. This way, I could easily view any changes I was making on my external monitor, without having to switch windows and refresh the page (more on configuring Guard in a future post!).
Our base theme was made up of a series of specific .scss files for different parts of our site. I created _base_header.scss, _base_footer.scss, _base_sidebar.scss, etc. as partials, and then used a single base_style.scss file to import all the styles I needed. This is where I imported compass and zen grids, our chosen grid system, as well. Another key was the use of a variables.scss partial, to store all our variables and mixins in one convenient place.
base_theme/ sass/ _base_footer.scss _base_header.scss _base_sidebars.scss _base_typography.scss _variables.scss base_style.scss styles/ base_style.css theme #1/ sass/ _header.scss _sidebars.scss _variables.scss style.scss styles/ style.css theme #2/ sass/ _header.scss _sidebars.scss _variables.scss style.scss styles/ style.css theme #3/ sass/ _header.scss _sidebars.scss _variables.scss style.scss styles/ style.css
Using this setup (shown above), all our styles were compiled into a single base_style.css file, which was then inherited by each sub-theme.
Each sub-theme then had its own compiled css file, named style.css. Drupal sub-themes will override inherited css files if they have their own version of a file with the same name; because we wanted to inherit the base styles and then modify them on a per theme basis, the theme-specific css files were each called style.css in their respective directories, and our base css file was called base_style.
We could have used only one variables file, and then used its relative path to import in each style.scss file (for example, in theme #1, instead of:
which imports the _variables.scss file in the same folder, we could have used:
However, there was enough variation in our variable values across each theme that it made sense for us to keep separate variables files.
This workflow allowed me to easily override particular styles only where necessary (per theme), so that I didn't have to write the same code in each theme. Easier to update and maintain. Plus, the mixins and variables SASS supports, in addition to the magic of nested styles, made working with default Drupal markup (i.e. divs inside divs inside divs) much easier to deal with.