Use the coupon code WORDPRESS and save 30% OFF! Buy Now

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

Last Updated On
How to create a custom color scheme for your WordPress theme using the customizer WordPress template

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',
'sanitize_callback' => 'sanitize_hex_color',
) );

$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',
'sanitize_callback' => 'sanitize_hex_color',
) );

$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',
'sanitize_callback' => 'sanitize_hex_color',
) );

$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',
'sanitize_callback' => 'sanitize_hex_color',
) );

$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 settings if we do not explicitly instruct it to do so, but it does provide us with the tools to easily do it. 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.

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

...
// Link color
$wp_customize->add_setting( 'link_color', array(
'default' => '',
'transport' => 'refresh',
// Sanitize on insertion
'sanitize_callback' => 'sanitize_hex_color',
) );

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

...

$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!

10 responses to “How to create a custom color scheme for your WordPress theme using the customizer”

  1. AlfredJKwack says:

    Hi,

    Very useful article. Thanks for posting it.

    I do have one correction though: WordPress by default does provide sanitization for its options. You might want to check the ‘sanitize_callback’ option of the add_setting array.

  2. latheesh says:

    Hi..Thank for posting! cleared all my doubts..

    1 question : if i am creating theme options and allow user to change it…and then save it in database and retrieve it and generate css based on that?
    like the avada theme options..

    any tutorials to achieve this?

    thanks

  3. Dan says:

    Thanks so much for this super clear/helpful write up! I’ve got it mostly working but I’m having to add `!important` to all of my rules in `functions.php` to get it to override my stylesheet.

    Something like this
    “`
    $text_color = get_theme_mod( ‘text_color’, ” );
    if ( ! empty( $text_color ) ) {
    ?>
    body {
    color: !important;
    }
    <?php
    }
    “`
    This works but I'd love to not have to resort to using !important all over the place. Do you have any ideas or suggestions for why this might be happening?

    Thanks again for the article!

    • Vassilis Mastorostergios says:

      Thanks for the kind comments.

      What you’re experiencing is due to the effects of the cascade (C for CSS). It could be caused by different things, perhaps your inline customizer styles are being written before your main stylesheet, or your stylesheet selectors are a bit more complicated and get a higher specificity than your customizer ones.

      In a previous article, “Writing effective CSS for WordPress“, I have a section devoted to this problem (check “Taming the Cascade”) that will most probably help! Let me know how it goes!

  4. brzy says:

    Hi, thank you! the article helped a lot !
    However, I see that when you change the color of an object, it changes it for all of them.
    What should I do if I only want some specific links in a different color and not the others.

  5. Babita says:

    Thank you for the great code, I need to ask if you could help, How can I put the transparent option in the settings?

    Thank you in Advance

    • Nik says:

      Hello.
      Unfortunately due to the way the color picker is implemented in the Customizer there is no simple way to add a color picker with transparency in the options. It requires some pretty extensive modifications which fall outside the scope of this post. I’m sorry.

Leave a Reply

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

Get access to all WordPress themes & plugins

24/7 Support Included. Join 115,000+ satisfied customers.

Pricing & Sign Up

30-day money-back guarantee. Not satisfied? Your money back, no questions asked.

Back to top