Last updated April 14, 2012. Created by skiquel on January 11, 2007.
Edited by shamio, montyd, jhodgdon, arianek. Log in to edit this page.

Color.module allows the admin to change the color scheme of a theme. By selecting a palette of colors (either from a set or by hand), you can change the colors of an entire theme.

The module can alter the stylesheet and re-render images. However, the theme must provide specific hooks to allow this, and the design must be created specifically to accommodate this.

This document explains the basics of making a colorizable theme.

Design

It is important to realize that due to the way color.module works, not every design can be colorized.

We take a transparent image of the design (the base), which includes everything except the background. We then compose this image on top of a colored background, to get the colored versions. Finally we slice up this composite image into smaller images and save them to separate image files.

We also process the stylesheet and change all the colors based on the ones you defined. The module smoothly changes the colors using the palette as a reference. Colors that don't appear literally in the palette are adjusted relative to the closest matching palette color (whether it is a link, text or background color).

So, the photoshop mockup of the design should consist of a layered file that has one or more colored layers at the bottom of the layer stack, with everything else blended on top. When you save the base image, you have to merge all layers together, while keeping the colored layers invisible. Take a look at Garland's base.png file to see an example (open it in an image editor to see the transparencies). There is a video showing how to create your own base.png file using Photoshop.

All the files generated in this process are written to /files/css and used instead of the default images. This means that a colorizable theme should still work out of the box without color.module, in the default color scheme.

In Practice

Let's use Garland as an example. The most important files are in the themes/garland/color subdirectory:

base.png
This contains the base design of the theme, which is composed and sliced into the images.
color.inc
This file contains all the necessary parameters to color the theme. See below.
preview.css
This stylesheet is used to generate the preview on the color changer.
preview.png
This image is used to generate the preview on the color changer.

The presence of color/color.inc makes the color picker appear on the theme's settings. It is a regular PHP file which contains an $info array with the following values:

Schemes

<?php
array('schemes' => array(
   
'#0072b9,#027ac6,#2385c2,#5ab5ee,#494949' => t('Blue Lagoon (Default)'),
   
'#464849,#2f416f,#2a2b2d,#5d6779,#494949' => t('Ash'),
   
'#55c0e2,#000000,#085360,#007e94,#696969' => t('Aquamarine'),
   
'#d5b048,#6c420e,#331900,#971702,#494949' => t('Belgian Chocolate'),
   
'#3f3f3f,#336699,#6598cb,#6598cb,#000000' => t('Bluemarine'),
   
'#d0cb9a,#917803,#efde01,#e6fb2d,#494949' => t('Citrus Blast'),
   
'#0f005c,#434f8c,#4d91ff,#1a1575,#000000' => t('Cold Day'),
   
'#c9c497,#0c7a00,#03961e,#7be000,#494949' => t('Greenbeam'),
   
'#ffe23d,#a9290a,#fc6d1d,#a30f42,#494949' => t('Mediterrano'),
   
'#788597,#3f728d,#a9adbc,#d4d4d4,#707070' => t('Mercury'),
   
'#5b5fa9,#5b5faa,#0a2352,#9fa8d5,#494949' => t('Nocturnal'),
   
'#7db323,#6a9915,#b5d52a,#7db323,#191a19' => t('Olivia'),
   
'#12020b,#1b1a13,#f391c6,#f41063,#898080' => t('Pink Plastic'),
   
'#b7a0ba,#c70000,#a1443a,#f21107,#515d52' => t('Shiny Tomato'),
   
'#18583d,#1b5f42,#34775a,#52bf90,#2d2d2d' => t('Teal Top'),
  ));
?>

This entry contains a straightforward array of pre-defined color schemes. Each entry must have 5 colors (which, in order, are base color, link color, top header, bottom header, and text color) formatted as above, and a title.

The first scheme is used as a reference and must match the colors used in the theme's default images and stylesheet closely. Otherwise, the final colors might not be what the user intended. See the 'stylesheets' section for more information about how the colors are calculated.

Images to copy

<?php
 
array('copy' => array(
   
'images/menu-collapsed.gif',
   
'images/menu-expanded.gif',
   
'images/menu-leaf.gif',
  ));
?>

This array contains a list of images which should not be altered. They are copied to the location of the generated images and stylesheet.

Fill areas and Gradients

To color the image, we create a target image that is the same size as the base image, and draw colored areas and a gradient. For full flexibility, the location of these areas is defined by specifying their coordinates using (x, y, width, height):

<?php
 
array('gradient' => array(0, 37, 760, 121));
?>

You can specify one vertical two-color gradient.

<?php
 
array('fill' => array(
   
'base' => array(0, 0, 760, 568),
   
'link' => array(107, 533, 41, 23),
  ));
?>

You can specify regions for each of the palette colors. The region will be filled in with the selected color. Available colors are 'base', 'link', 'top', 'bottom' and 'text'.

Image slices

Next, you need to define the areas of the base image to slice out for each of the images. Again, you specify coordinates as (x, y, width, height) along with the filename of the image, as used in the stylesheet. The logo and screenshot slices are special and always take the same filename. The screenshot will be resized to 150x90 pixels.

<?php
 
array('slices' => array(
   
'images/body.png'                      => array(0, 37, 1, 280),
   
'images/bg-bar.png'                    => array(202, 530, 76, 14),
   
'images/bg-bar-white.png'              => array(202, 506, 76, 14),
   
'images/bg-tab.png'                    => array(107, 533, 41, 23),
   
'images/bg-navigation.png'             => array(0, 0, 7, 37),
   
'images/bg-content-left.png'           => array(40, 117, 50, 352),
   
'images/bg-content-right.png'          => array(510, 117, 50, 352),
   
'images/bg-content.png'                => array(299, 117, 7, 200),
   
'images/bg-navigation-item.png'        => array(32, 37, 17, 12),
   
'images/bg-navigation-item-hover.png'  => array(54, 37, 17, 12),
   
'images/gradient-inner.png'            => array(646, 307, 112, 42),
   
'logo.png'                             => array(622, 51, 64, 73),
   
'screenshot.png'                       => array(0, 37, 400, 240),
  ));
?>

Files

Finally you need to specify the location of the files for your theme. You need an image and a stylesheet for the preview, as well as the base image*:

<?php
array(
 
'preview_image' => 'color/preview.png',
 
'preview_css' => 'color/preview.css',
 
'base_image' => 'color/base.png',
);
?>

* As of drupal 6, Color.module no longer requires base_image, meaning it is possible to utilize the module without images.

Stylesheets (CSS)

The color.module will read in a theme's specified style.css file(s) as well as any other styles that are imported with @import statements and create a new style.css file. It will change the colors in the CSS. It uses (in Drupal 7, the 'default' scheme's colors) one of the chosen palette colors as a reference. This depends on context:

  • Links: the 'link' color is used, for rules that apply to a elements.
  • Text: the 'text' color is used, for rules that appear in color: styles.
  • Base: the 'base' color is used for everything else.

However, if a color in the stylesheet matches one of the reference colors exactly, the context will be ignored, and the matching replacement color will be used instead.

For example, suppose your reference color is dark blue by default, but you change it to red. Your default stylesheet contains both light blue and gray purple, both relative to this reference color.

The resulting colors (mauve and brown) are similarly different from red as the original colors were from blue. In technical terms: the relative difference in hue, saturation and luminance is preserved.

If you find color.module is using the wrong reference color, try separating the different pieces into separate CSS rules, each in their own selector { ... } section, so there is no confusion about the context.

Note that if you edit your stylesheet after changing the color scheme, you must resubmit the color scheme to regenerate the color-shifted version.

If you wish for certain colors in the stylesheet not to be altered, you should place their CSS below the following marker:

/*******************************************************************
* Color Module: Don't touch                                       *
*******************************************************************/

You can only use this marker once in your style.css file. It applies globally, so if you use it inside an imported stylesheet, all colors below the @import statement will be left alone too.

Making colors match

It is important that the generated images match with the shifted colors in the generated stylesheet. Otherwise, ugly edges might appear.

To make this work, pixels in the base image must all be a simple color in areas where they have to match with CSS-defined colors. Because we don't know where CSS-defined colors appear in the base image, we use a global blending color which must be the same in the whole design. Garland uses white. Note that the Garland base does include e.g. gray and black pixels, but only in areas where only images are used as backgrounds (e.g. the header). Other than white, black or gray are good candidates too.

<?php
 
array('blend_target' => '#ffffff');
?>

Masochists can take a peek at color.module's innards, particularly the _color_shift() function if you're interested in the how and why of this.

PHPTemplate changes

Finally, you need to hook color.module into your theme. We'll use a PHPTemplate theme as an example, but this applies to other engines as well.

In your theme's template.php file, add the following snippet (for Drupal 6.x):

<?php
/**
* Override or insert PHPTemplate variables into the templates.
*/
function phptemplate_preprocess_page(&$vars) {
 
// Hook into color.module
 
if (module_exists('color')) {
   
_color_page_alter($vars);
  }
}
?>

In Drupal 5.x, you’ll need to add the following snippet:

<?php
/**
* Override or insert PHPTemplate variables into the templates.
*/
function _phptemplate_variables($hook, $vars) {
  if (
$hook == 'page') {
   
// Hook into color.module
   
if (module_exists('color')) {
     
_color_page_alter($vars);
    }
    return
$vars;
  }
  return array();
}
?>

This will allow the module to override your theme's logo, stylesheet and screenshot. If you perform other changes in _phptemplate_variables, you need to merge in this snippet.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

Is there anywhere an overview of themes using the color module.
I have done searching and could not find a good overview.

Thank you,
Tom

Update: my list
• Garland
• Minelli
• Abarre
• AD Blueprint
• Alldrupalthemes.com basetheme
• Auquanaut
• Austere
• Deco
• Wabi
• Picture
• Twilight
• Kommunity

For the sake of Image Processing Newbies, the following explains how to understand Garland's base.png and how you can create your own base.png using GIMP.

After opening garland's base.png in GIMP you may note something odd about it. There are 'shaded' areas which don't correspond to any pixel color. If you click around on the image, you will see white virtually everywhere, with the lettering done in a gray. So what do those shaded areas represent?

The PNG file format uses an RGBA representation for each pixel. The 'A' in this case stands for the alpha channel. Its a byte indicating how much background is allowed to shine through. This is key in many image processing effects. So the shaded areas that you seeing is GIMP's way of communicating to you the percentage of alpha each pixel actually is.

To see this more precisely, we can use GIMP's color picker. After loading garland's base.png in GIMP, you will see 3 windows. The left is the Toolbox window, the center is the image, and the right is the layering window.

Note: when using GIMP you need to be very aware of what layer you are in. I don't know how many times I was left completely befuddled, because the operation I was trying to do would not work even though I tried again and again. The problem was I was in the wrong layer.

Which layer you are in is controlled by the little cascade at top of the layering window. Use this cascade to ensure you are in the right file. Then, make sure the layer of interest is selected in the list beneath.

Garland's base.png will have just one layer called 'Background'. Select this, and then bring up the color picker on the toolbox window side. At the bottom of the dialog is a 'Use info window' check box. Click that. Now when you click on a pixel a little info window will pop up showing you not only the RGB value, but also the alpha percentage as well (100% = completely opaque, 0% = completely transparent).

Creating your own base.png from scratch:

Do File->New, and create an image the same size as garland's base.png image.

Ensure the layering dialog is set to the new file.

You should see one layer named 'Background' for your new base.png. Notice that the Background word is in bold. This means there are no alpha channels defined yet for that layer. You need to create one.

This is how I like to do it: Set the foreground color to white. Then fill the entire image with that color. Then, select Layer->Transparency->Color to Alpha. By default, it should have 'white' be the color. When you execute this command, it will replace the color white with a fully transparent pixel.

Creating Gradient Transparent Regions:

You will notice in garland's base.png that there are gradient transparency regions. For example, the left side bar is one such region. To create a gradient transparent region using GIMP, do the following:

First create a new layer. Now make sure that layer is selected. By default the size of the new layer will be the size of the image. That's fine for now. Select the region you want to create using the rectangular select tool. Now click on the Blend Tool in the Toolbox window. In the dialog you need to set the Gradient control to be 'FG to Transparency'. Make sure the foreground is white. Now let's say you want to make a gradient region with the top being mostly opaque to the bottom being mostly transparent. Click on the top of your selected region and drag with your mouse down to the bottom. After you do so, you should see shaded effect. If it's not working, most likely you are in the wrong layer.

In garland's base.png you will also see mostly uniform transparent regions. For example, the breadcrumb region is one such region. The way I created these was also with the Blend tool. But instead of starting at the top of the selected region, I started way above the selected region. Then, instead of ending at the bottom of the selected region, I ended far below the selected region. This will create a near uniform transparency for the selected region.

How the image slices are constructed in the color.module:

  1. An empty target image is created to the size of base.png.
  2. The 'fill' colors specified in your color.inc are applied to the indicated regions of the target image.
  3. The gradient region is made using the header top and header bottom color values as indicated in the configuration settings form.
  4. Now the base.png file is loaded and copied into to the target image. This means the fill and gradient colors will be lost unless transparency values were used in those exact areas from the base.
  5. From this target image, the slices as indicated in your color.inc are used to create the indicated files.

Producing your first set of default sliced images

The color module has one efficiency built in: for the default color scheme it will not generate any files. Rather it logically bails out of any processing it normally would do and simply uses the existing files in the shipped theme. This makes sense during production, but how can you get those initial images? I consider it too error prone to hand create your first crop of sliced images.

I didn't see a better way, so I recommended temporarily commenting out the relevant lines in the color.module. This would be lines 285->293 in modules/color/color.module. It's the section that starts with the comment 'Don't render the default colorscheme, use the standard theme instead.'

Now when you open do 'Save configuration settings' in the configuration settings for your theme, it will save the files in a new directory underneath the 'sites/default/files/color' folder. Copy these images to your official theme location. When you are done developing the initial images, undo the changes you made to the color.module.

Note: another thing I like to do just during development is to make an 'all.png' slice being the size of the image. This just lets me see if everything is getting put together correctly.

A simple color.module suggestion to the developer: in the aforementioned lines, bail out only if the theme is the default AND the first slice file exists in the theme directory. This way if the developer needs to recreate those initial images, all they have to do is remove the first slice file.

I added additional schema labels in color.inc (using Bartik theme). I applied the patch to have the new schema elements show in the UI.

When I save, the default->color->bartik...->colors.css get's updated (timestamped), but I don't see that any of the css values have changed to the specified colors from the UI. Second, how do I map the new schema elements to css tags in the .css generated file?

UPDATED: Never mind the above. The default schema color in color.inc has to match the corresponding colors in color.css. This article is very helpful!

I just wanted to mention that I found it much cleaner to do something like this...

$info['schemes'] = array(
  ..
);
$info['copy'] = array(
  ..
);
$info['slices'] = array(
  ..
);

Instead of this...

$info = array(
  'schemes' => array(
    ..
  ),
  'copy' => array(
    ..
  ),
  'slices' => array(
    ..
  ),
);

I think it's just pedantics, I just much prefer it and thought I'd mention it to others that may prefer it as well.

Michael Lustfield
Ubuntu Member, Nginx Hacker

Is it possible to add a new color that can be modified from the UI within a Bartik subtheme? I tried adding a "Menu link color" by modifying the color.inc file in my bartik subtheme, but I ran into some errors (I'm very new to programming in Drupal).
Here's where I added menu link color to the color.inc file:

$info = array(
  // Available colors and color labels used in theme.
  'fields' => array(
    'bg' => t('Main background'),
    'link' => t('Link color'),
    'top' => t('Header top'),
    'bottom' => t('Header bottom'),
    'text' => t('Text color'),
    'sidebar' => t('Sidebar background'),
    'sidebarborders' => t('Sidebar borders'),
    'footer' => t('Footer background'),
    'titleslogan' => t('Title and slogan'),
    'menulink' =>('Menu link color'),  // <------------here
  ),
  // Pre-defined color schemes.
  'schemes' => array(
    'default' => array(
      'title' => t('Blue Lagoon (default)'),
      'colors' => array(
        'bg' => '#ffffff',
        'link' => '#0071B3',
        'top' => '#0779bf',
        'bottom' => '#48a9e4',
        'text' => '#3b3b3b',
        'sidebar' => '#f6f6f2',
        'sidebarborders' => '#f9f9f9',
        'footer' => '#292929',
        'titleslogan' => '#fffeff',
        'menulink' => '#000100',  // <-----------and here
      ),
    ),

I also tried adding this to my colors.css file:

.sf-menu a, .sf-menu a:visited  {
  color: #000100;
}

But the menu link color doesn't show up in the UI, the menu links have the same color as normal links, and I get this error when trying to save the color configuration:
"Notice: Undefined index: menulink in _color_rewrite_stylesheet() (line 432 of /var/www/shyre/modules/color/color.module)."

What I tried was really just a shot in the dark, but I wanted to at least give it a try before asking for help.

I'm a beginner too, but I found one syntax error.
Your original code:
'menulink' =>('Menu link color'),  //<------------here
Correctly:
'menulink' => t('Menu link color'), //<------------here

I'm sorry but this is all presented in a very awkward way.

I'm definitely confused and this page has (after reading it 3 times) left me with a few "What? why?"

This line:
As of drupal 6, Color.module will no longer require base_image, meaning it is possible to utilize the module without images.

What does this mean? That all information above that line is a waste of time if you're theming for 6.x or above?

No, it means you can still use images if you want to (and will probably get more professional results), but it's no longer compulsory.

--Andy
Developing Drupal websites for Livelink New Media since 2008

Drupal 7 you need the following

<?php
/**
* Override or insert variables into the page template.
*/
function THEME_process_page(&$variables) {
 
// Hook into color.module.
 
if (module_exists('color')) {
   
_color_page_alter($variables);
  }
}
/**
* Override or insert variables into the page template for HTML output.
*/
function THEME_process_html(&$variables) {
 
// Hook into color.module.
 
if (module_exists('color')) {
   
_color_html_alter($variables);
  }
}
?>

I wanted to use a background image in the Bartik theme that also contains the color module.

I found out I have to include the background image in the 'copy to' array in color.inc. Then I found out the path in the modified color.css will not be the path as specified in the original color.css but rather that path always prepended by the path to the CSS folder. So, './images/picture.png' will be modified into '.../css/./images/picture.png' which is of course not a valid path.

I could only get this to work by placing the background image to use in the original css folder.
Seems to me a bug in the color module or I completely misunderstood how to combine a background image with the color module.

Met vriendelijke groeten, Kind regards, Mes meilleures salutations,
André Hartman
Kalmlthout, België

If you change the order of the colors you need to manually remove a variable from the variable table for your changes to take effect. It might also in some cases affect adding and removing colors. I have a post here about it: http://drupal.org/node/1396156

FYI: I read through the relevant part of the color module code and I didn't see any reason to have 5 colors nor to have them in a particular order (everything is done with associative arrays meaning all keys are found by name not position). I suspect that's for an older version of Drupal.

Normally I wouldn't mention a bug in a comment on an article like this (bugs come and go) but the behavior of the color module can be difficult to fully understand when you are getting started with it which makes it difficult to know that what's wrong may not be your fault.

So, for anyone using Drupal 7 who sees colors shifting that they don't think should be happening have a look at this issue: http://drupal.org/node/1415206.

Dont’t forget to add the colors stylesheet to your .info-file:

stylesheets[all][] = color/colors.css

In the generated output, this file will be replaced with the generated file.

Took me a while to figure this one out:

If you use underscores in the color variable names (eg 'my_color') then the link feature will stop working and spit out JavaScript errors.

......................................................................................................
Hi, my name is Marton Bodonyi and I'm an Interactive Junky.
http://www.interactivejunky.com
.........................................................

Hi,
I am trying to incorporate color scheme which is available in bartik, into my theme. I am able to generate the files which will be located at

sites/default/files/color/theme-4855b5/colors.css

after making options in color scheme of my theme.

But in the head tag of styles files, it still points to my theme directory colors.css instead of above mentioned directory, Which results in no change of colors for my theme.

My theme is actually a sub theme. What am i doing wrong ??

I have included color folder and inside that have color.inc files.
Also included color.css folder inside css folder.
hook_process_page(&$variables) and hook_process_html(&$variables) these functions included in template.php
included css file in info file too. stylesheets[all][] = 'css/colors.css'

What am I missing in not getting that css being replaced by dynamically generate one? Thanks in advance.