How to create a custom color scheme for your WordPress theme using the customizer

Ever since WordPress version 3.4 it’s been extremely simple to add site settings to our websites with the Theme Customization API. Here at CSSIgniter it’s actually been a couple of years now where we’ve completely abandoned custom Theme Options pages in lieu of the Customizer, since the benefits are too many to pass: ease of use, consistent API, native look and feel, and live previews to name a few.

All our themes are bundled with an abundance of settings, from simple post meta visibility to complex layout options which allow for drastic interventions on the theme’s appearance, however, our most popular group of settings is the “Appearance” section, where every single color of the theme can be tweaked. In this short post we’ll go through our basic strategy on handling color settings and how you could incorporate them into your own theme or existing website.

Planning the color scheme

For our simple theme we’re going to style a few different global parts which are generally common among websites, therefore we’ll need the following settings:

  • Text color: The theme’s main text color.
  • Link color: It will apply to all the theme’s links.
  • Accent color: The accent color is usually used for variance in the theme between elements. An example of this is the Twenty Fourteen (the WordPress default theme from a few years back) which has a very prominent accent color (by default green) and all hovered links and buttons inherit it. For this tutorial we’ll assume our virtual theme uses the accent color to style buttons and links on hover.
  • Border color: Global border color (e.g. used in form elements).
  • Sidebar background color: The background color of the theme’s sidebar.

To get a better understanding of what we’re going to do, we’ll assume that our theme’s stylesheet is the following (in Sass):

$text-color: #333 !default; // very dark grey
$link-color: #3f5ee4 !default; // blue
$accent-color: #48bb8b !default; // green
$border-color: #d4d4d4 !default; // light grey

body {
  color: $text-color;
}

a {
  color: $link-color;
  border-bottom: 1px solid $link-color;

  &:hover {
    color: $accent-color;
    border-bottom: 1px solid $accent-color;
  }
}


input,
textarea {
  border: 1px solid $border-color;
}


button,
input[type="submit"] {
  border: 1px solid $accent-color;
  background-color: $accent-color;
}

.sidebar {
  // Our sidebar will not have any background color by default
}
Our virtual theme's styles

and we’re going to provide a group of settings so that our users can change these colors without touching any code (this is very similar to what we do for our themes).

Again, using Sass here is extremely helpful because we know every single color we use for the theme beforehand as they are all grouped in a _variables.scss file and we can easily grep them from the theme’s stylesheet and find all matching selectors.

Declaring the Customizer settings

First thing we need to do is open up our functions.php file and hook up the required customize_register action:

function theme_customize_register( $wp_customize ) {
   // All our settings will go here
}

add_action( 'customize_register', 'theme_customize_register' );
Setting up our code inside the customise_register action

Keep in mind that this is not specific to color options. The action is a requirement for any kind of option, and if you already have customizer settings in your theme your probably also have this hooked up (albeit it’s of no harm to add another hook).

Now let’s define our color settings. The customizer API makes this possible with just a few lines of code, it even provides us with color pickers out of the box. Each customizer setting requires two method calls, $wp_customize->add_setting for registering the setting itself and $wp_customize->add_control for displaying the markup which controls the setting.

Let’s see how this translates in code for our example:

<?php
  function theme_customize_register( $wp_customize ) {
    // Text color
    $wp_customize->add_setting( 'text_color', array(
      'default'   => '',
      'transport' => 'refresh',
    ) );

    $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'text_color', array(
      'section' => 'colors',
      'label'   => esc_html__( 'Text color', 'theme' ),
    ) ) );

    // Link color
    $wp_customize->add_setting( 'link_color', array(
      'default'   => '',
      'transport' => 'refresh',
    ) );

    $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'link_color', array(
      'section' => 'colors',
      'label'   => esc_html__( 'Link color', 'theme' ),
    ) ) );

    // Accent color
    $wp_customize->add_setting( 'accent_color', array(
      'default'   => '',
      'transport' => 'refresh',
    ) );

    $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'accent_color', array(
      'section' => 'colors',
      'label'   => esc_html__( 'Accent color', 'theme' ),
    ) ) );

    // Border color
    $wp_customize->add_setting( 'border_color', array(
      'default'   => '',
      'transport' => 'refresh',
    ) );

    $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'border_color', array(
      'section' => 'colors',
      'label'   => esc_html__( 'Border color', 'theme' ),
    ) ) );

    // Sidebar background
    $wp_customize->add_setting( 'sidebar_background', array(
      'default'   => '',
      'transport' => 'refresh',
    ) );

    $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'sidebar_background', array(
      'section' => 'colors',
      'label'   => esc_html__( 'Sidebar Background', 'theme' ),
    ) ) );
  }

  add_action( 'customize_register', 'theme_customize_register' );
All colors registered

A bit verbose, but generally very simple. All we do is copy and paste the two method calls for each setting and change the setting ID and label. Notice we’re using the handy WP_Customize_Color_Control class which WordPress provides and hooks us up with color pickers without any further hassle!

Now if we navigate to the Customizer we should see a section named “Colors” and our newly added settings under it. They don’t exactly do anything right now though, so let’s fix that!

Generating the CSS

Now that we’ve got our color options set up we’re going to need to output them at our theme’s <head>.

Like with all customizer settings, we’ll use get_theme_mod to fetch and echo them, and we’ll do that using the wp_add_inline_style function so that our styles go together with the theme’s main stylesheet.

Let’s see it in action for the first of our colors, the text color:

<?php
  function theme_get_customizer_css() {
    ob_start();

    $text_color = get_theme_mod( 'text_color', '' );
    if ( ! empty( $text_color ) ) {
      ?>
      body {
        color: <?php echo $text_color; ?>;
      }
      <?php
    }

    $css = ob_get_clean();
    return $css;
  }
Generating CSS out of our settings

And for echoing them:


// Modify our styles registration like so:

function theme_enqueue_styles() {
  wp_enqueue_style( 'theme-styles', get_stylesheet_uri() ); // This is where you enqueue your theme's main stylesheet
  $custom_css = theme_get_customizer_css();
  wp_add_inline_style( 'theme-styles', $custom_css );
}

add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );

Now every time we change the “Text color” setting, we should see our theme’s body color changing along with it. Similarly, let’s add all styles:

<?php
  function theme_get_customizer_css() {
    ob_start();

    $text_color = get_theme_mod( 'text_color', '' );
    if ( ! empty( $text_color ) ) {
      ?>
      body {
        color: <?php echo $text_color; ?>;
      }
      <?php
    }


    $link_color = get_theme_mod( 'link_color', '' );
    if ( ! empty( $link_color ) ) {
      ?>
      a {
        color: <?php echo $link_color; ?>;
        border-bottom-color: <?php echo $link_color; ?>;
      }
      <?php
    }

    
    $border_color = get_theme_mod( 'border_color', '' );
    if ( ! empty( $border_color ) ) {
      ?>
      input,
      textarea {
        border-color: <?php echo $border_color; ?>;
      }
      <?php
    }

    
    $accent_color = get_theme_mod( 'accent_color', '' );
    if ( ! empty( $accent_color ) ) {
      ?>
      a:hover {
        color: <?php echo $accent_color; ?>;
        border-bottom-color: <?php echo $accent_color; ?>;
      }

      button,
      input[type="submit"] {
        background-color: <?php echo $accent_color; ?>;
      }
      <?php
    }

    
    $sidebar_background = get_theme_mod( 'sidebar_background', '' );
    if ( ! empty( $sidebar_background ) ) {
      ?>
      .sidebar {
        background-color: <?php echo $sidebar_background; ?>;
      }
      <?php
    }

    $css = ob_get_clean();
    return $css;
  }

// Modify our styles registration like so:

function theme_enqueue_styles() {
  wp_enqueue_style( 'theme-styles', get_stylesheet_uri() ); // This is where you enqueue your theme's main stylesheet
  $custom_css = theme_get_customizer_css();
  wp_add_inline_style( 'theme-styles', $custom_css );
}

add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );

The general process goes something like this: We search for a specific color in our stylesheet and locate all rules that apply for that color, then we duplicate those rules in our PHP file under each color setting.

One thing I’d like to stress is not to only touch the actual color declarations, and not any rule concerning layout or other values. For example, if you take a look at the above snippet in the Link and Accent Color settings, we’re only changing border-bottom-color, not the whole border declaration. This cleanly separates our color scheme from anything else that would be categorized as presentational.

Bonus: Sanitizing user input

WordPress by default does not provide any kind of sanitization for its options. As we escape our html when we output it in our theme’s templates we must make sure we sanitize and escape the colors as well. This is a separate section because it’s quite important.

For this purpose, WordPress provides the handy sanitize_hex_color function, and we have to modify all of our output to use it, for example:

...

$link_color = get_theme_mod( 'link_color', '' );
if ( ! empty( $link_color ) ) {
  ?>
  a {
    color: <?php echo sanitize_hex_color( $link_color ); ?>;
    border-bottom-color: <?php echo sanitize_hex_color( $link_color ); ?>;
  }
  <?php
}
...
Sanitizing hex colors

Similarly, for more complex websites or themes, we can have different color settings for buttons (text color, background color, hover color and so on) or different parts of our website (i.e. header colors, footer colors etc), exactly like we do here at CSSIgniter or our WordPress themes.

And there we have it! We’re ready to give our users the ability to change their website’s colors without touching a single line of code. Which approach do you prefer? Do you like modifying the appearance of your website using the Customizer or do you prefer a more hands-on approach with a custom stylesheet? Let us know in the comments below!

Subscribe to our newsletter.

Get fresh WordPress content straight into your inbox. We hate spam more than you do.

Leave a Reply

Your email address will not be published. Required fields are marked *