Advanced color manipulation using the customizer

I was building a new free theme called Shoestrap ( ) and I needed to control many things using wordpress's customizer. I 'm not going to go through the process of adding a setting etc to the customizer, there's an excellent article by Otto here:
However, I'm going to tell you how I 'm controlling for example the text color depending on the background color, and how to create gradients. If you take a look at my theme, the user selects a color for the navbar (among other things...) and these things happen:
* the navbar gets a slight gradient depending on the color.
* If the background color selected is bright, the navbar text is dark and vice-versa.
* the color of the menu items changes depending on the color the user has selected so that's a variation of the selected color

This is simply going to show you the principal. If you want to know more about the exact implementation, you can simply download the theme from the above link (or from github: ) and take a look at the files inside the /includes/customizer folder. Please note that if you wish to use this theme I suggest you download it from in order to get a free licence which will provide you automatic updates.

Most of the heavy-duty work is done by 2 functions. Unfortunately I don't remember where I saw them to congratulate the guy that initially wrote them.
First, we'll need a function to detect the brightness of the color the user has selected:

function shoestrap_get_brightness($hex) {
  // returns brightness value from 0 to 255
  // strip off any leading #
  $hex = str_replace('#', '', $hex);

  $c_r = hexdec(substr($hex, 0, 2));
  $c_g = hexdec(substr($hex, 2, 2));
  $c_b = hexdec(substr($hex, 4, 2));

  return (($c_r * 299) + ($c_g * 587) + ($c_b * 114)) / 1000;

Next, a function that will allow us to change the brightness of a color:

function shoestrap_adjust_brightness($hex, $steps) {
  // Steps should be between -255 and 255. Negative = darker, positive = lighter
  $steps = max(-255, min(255, $steps));

  // Format the hex color string
  $hex = str_replace('#', '', $hex);
  if (strlen($hex) == 3) {
      $hex = str_repeat(substr($hex,0,1), 2).str_repeat(substr($hex,1,1), 2).str_repeat(substr($hex,2,1), 2);

  // Get decimal values
  $r = hexdec(substr($hex,0,2));
  $g = hexdec(substr($hex,2,2));
  $b = hexdec(substr($hex,4,2));

  // Adjust number of steps and keep it inside 0 to 255
  $r = max(0,min(255,$r + $steps));
  $g = max(0,min(255,$g + $steps));
  $b = max(0,min(255,$b + $steps));

  $r_hex = str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
  $g_hex = str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
  $b_hex = str_pad(dechex($b), 2, '0', STR_PAD_LEFT);

  return '#'.$r_hex.$g_hex.$b_hex;

This last function will affect the brightness in steps (0-255) and not in percentages.

For the custom NavBar I implemented, the user selects a background color (setting: shoestrap_navbar_color).

Let's start with the menu items color tweaks:

<?php $navbar_color           = get_theme_mod('shoestrap_navbar_color'); ?>
.navbar-inner a{
<?php if (shoestrap_get_brightness($navbar_color) >= 160){ ?>
color: <?php echo shoestrap_adjust_brightness($navbar_color, -160); ?>;
<?php } else { ?>
color: <?php echo shoestrap_adjust_brightness($navbar_color, 160); ?>;
<?php } ?>

What the above does:
IF the navbar color is brighter than 160 (min:0, max:255) then the color applied to the .navbar-inner a element is 160 steps darker than the navbar color.
IF the navbar color is darker than 160 then the color applied to the .navbar-inner a element is 160 steps brighter than the navbar color. This way, we can make sure that no matter what the color the user selects there will always be enough contrast between the text and the background to ensure visibility.

Next, the gradient of the navbar:

.navbar-inner, .navbar-inner ul.dropdown-menu{
  background-color: <?php echo $navbar_color; ?> !important;
  background-image: -moz-linear-gradient(top, <?php echo $navbar_color; ?>, <?php echo shoestrap_adjust_brightness($navbar_color, -10); ?>) !important;
  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(<?php echo $navbar_color; ?>), to(<?php echo shoestrap_adjust_brightness($navbar_color, -10); ?>)) !important;
  background-image: -webkit-linear-gradient(top, <?php echo $navbar_color; ?>, <?php echo shoestrap_adjust_brightness($navbar_color, -10); ?>) !important;
  background-image: -o-linear-gradient(top, <?php echo $navbar_color; ?>, <?php echo shoestrap_adjust_brightness($navbar_color, -10); ?>) !important;
  background-image: linear-gradient(to bottom, <?php echo $navbar_color; ?>, <?php echo shoestrap_adjust_brightness($navbar_color, -10); ?>) !important;
  filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(<?php echo $navbar_color; ?>),argb(<?php echo shoestrap_adjust_brightness($navbar_color, -10); ?>))) !important;
  border: 1px solid <?php echo shoestrap_adjust_brightness($navbar_color, -20); ?>;

I know it seems scary but if you take a good look at it and analyse it a bit it's pretty simple.
The chaos is caused simply because of browser compatibility, so instead of 1 line we have to use 1 for each browser.

That's it! try it yourself, I find it pretty useful!