debuggable

 
Contact Us
 

How To Generate Monochromatic CSS Stylesheets Within Seconds Using PHP

Posted on 7/6/07 by Tim Koschützki

Hi folks! As a follow-up to my previous article Control your CSS via PHP - Good Stuff I have tried to implement the techniques explained there to build monochromatic stylesheets within seconds. First off, I will explain to the ones, that do not know yet, what a monochromatic color scheme is.

What Is A Monochromatic Color Scheme?

The monochromatic color scheme uses variations in lightness and saturation of a single color. It looks clean and elegant. Monochromatic colors go well together, producing a soothing effect. The monochromatic scheme is very easy on the eyes, especially with blue or green hues.
You can use it to establish an overall mood, which we will do later with the css generation. The primary color can be integrated with neutral colors such as black, white, or gray. However, it can be difficult, when using this scheme, to highlight the most important elements.

The monochromatic color scheme is perfect for our task of generating CSS via PHP based on forming shades of a base color. First off, please download the PHP Script for generating CSS. Place it in any folder on your website or your local php installation.

Setting Up Our CSS Generation Environment

Next off we will borrow some XHTML / CSS code from my buddy Paul O'Brian, one of the greatest CSS Gurus on the net. His site features plenty of css goodness, tutorials and effects I am sure you haven't seen before. It is definately worth to check out! We will take the code of his universal three column layout that works in most browsers and allows any column to be the longest. Save that markup to a file named "test.html" in the same folder where you saved the php file. Now, in that same folder, create a file "css.php" where you insert the following CSS code:


// Tell the browser that this is CSS instead of HTML
header("Content-type: text/css");

// Get the color generating code
require_once("csscolor.php");

// Define a couple color palettes
//$base = new CSS_Color('C9E3A6');
$base = new CSS_Color('99E456');

// Trigger an error just to see what happens
// $trigger = new CSS_Color('');
/* CSS Document */
* {margin:0;padding:0}
p {margin-bottom:1em}
ul{margin-left:20px;margin-bottom:1em}
/* commented backslash hack v2 \*/
html, body{height:100%;}
/* end hack */

body {
  background:#<?php echo $base->bg['-2'] ?> repeat-y left top;
  color: #FFF;
}
#outer{
  margin-left:130px;
  margin-right:130px;
  background: #<?php echo $base->bg['0'] ?>;
  border-left:1px solid #000;
  border-right:1px solid #000;
  margin-bottom:-52px;
  min-height:100%
}
#header{
  position:absolute;
  top:0;
  left:0;
  width:100%;
  height:70px;
  background: #<?php echo $base->bg['-3'] ?>;
  border-top:1px solid #000;
  border-bottom:1px solid #000;
  overflow:hidden;
}
#left {
  position:relative;/*ie needs this to show float */
  width:130px;
  float:left;
  margin-left:-129px;/*must be 1px less than width otherwise won't push footer down */
  z-index:100;
  left:-1px;
}
#left p,
#right p {padding:3px}
#right {
  position:relative;/*ie needs this to show float */
  width:130px;
  float:right;
  margin-right:-129px;/*must be 1px less than width otherwise won't push footer down */
  left:1px;
  color: #000;
}
#footer {
  width:100%;
  clear:both;
  height:50px;
  border-top:1px solid #000;
  border-bottom:1px solid #000;
  background-color: #<?php echo $base->bg['-4'] ?>;
  text-align:center;
  position:relative;
}
#clearheader{height:72px;}/*needed to make room for header*/
#clearfooter{clear:both;height:52px;}/*needed to make room for footer*/
* > html #clearfooter {float:left;width:100%;}/* ie mac styles */
#centrecontent {
  width:100%;
  float:left;
  position:relative;
  z-index:1;
  margin:0 -1px;/* moz fix*/
  color: #000;
}
/* css stuff below is just for presentation and not needed for the demo */
#centrecontent p { padding: 0 20px; }
h1 {font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: lighter; font-size: 150%; padding: 20px;}
#left span {
  display:none
} 
#left a:hover {
  text-decoration: none;
  text-decoration: none;
  color:#222;
  background: #FFF;
}
#left a:hover span {
  display:block;
  position:absolute;
  left:130px;
  width:150px;
  z-index:20;
  background:#fff;
}
@media all and (min-width: 0px){
  #left a:hover span {
  top:150px;
  }
}
#footer a, #left a { color:#FFF; }
#footer span {
  display:none
} 
#footer a:hover {
  text-decoration: none;
  color:#222;
  background: #FFF;
}
#footer a:hover span {
  display:block;
  position:absolute;
  top:-95px;
  width:150px;
  z-index:20;
  background:#fff;
  left:50%;
}
html>body #minHeight{float:right;width:0px;height:100%;margin-bottom:-52px;} /*safari wrapper */

What this does is simply using our css generation script to alter the code of the original css file from the universal three column layout. We create a base color ($base = new CSS_Color('99E456');) and form shade variations for the two navbars, the header and the footer:

body {
  background:#<?php echo $base->bg['-2'] ?> repeat-y left top;
  color: #FFF;
}
#outer{
  margin-left:130px;
  margin-right:130px;
  background: #<?php echo $base->bg['0'] ?>;
  border-left:1px solid #000;
  border-right:1px solid #000;
  margin-bottom:-52px;
  min-height:100%
}
#header{
  position:absolute;
  top:0;
  left:0;
  width:100%;
  height:70px;
  background: #<?php echo $base->bg['-3'] ?>;
  border-top:1px solid #000;
  border-bottom:1px solid #000;
  overflow:hidden;
}
#footer {
  width:100%;
  clear:both;
  height:50px;
  border-top:1px solid #000;
  border-bottom:1px solid #000;
  background-color: #<?php echo $base->bg['-4'] ?>;
  text-align:center;
  position:relative;
}

Now change the line

in your site.html file and then launch it via a browser. You should see something like this:

Picture of first generated layout

Changing The Base Color For Some Cool Results

It is not exactly pretty, but we can play around with the base color a bit:

$base = new CSS_Color('98ccac');
Picture of second generated layout

$base = new CSS_Color('ccac99');
Picture of thirdgenerated layout

$base = new CSS_Color('ccccff');
Picture of forth generated layout

What Other Uses For This Can We Think Of?

Now you could also add other colors to highlight some other parts, like singleing out the footer from the monochromatic scheme or always staying with white background for the main content column.

$highlightFooter = new CSS_Color('973432');
$outer = new CSS_Color('ffffff');
...

We could also generate a grayscale website using white or black as the base color. I am sure there are endless cool possibilities for this stuff, like different shades for list elements, headings, paragraphs and what not. I am eager to hear your ideas in the post comments below!

So How Does This PHP Thing Work?

When you look at the csscolor.php file, you will quickly notice that it is a very well-made object-oriented PHP script. The foundation of the magic is here:

function CSS_Color($bgHex, $fgHex='')
  {
    // This is the constructor method for the class,
    // which is called when a new object is created.

    // Initialize this PEAR object so I can
    // use the PEAR error return mechanism
    $this->PEAR();

    // Initialize the palette
    $this->setPalette($bgHex, $fgHex);
  }

  //==================================================
  //==METHODS=========================================
  //==================================================

  //--------------------------------------------------
  function setPalette($bgHex, $fgHex = '')
  {
    // Initialize the color palettes

    // If a foreground color was not specified,
    // just use the background color.
    if (!$fgHex) {
      $fgHex = $bgHex;
    }

    // Clear the existing palette
    $this->bg = array();
    $this->fg = array();

    // Make sure we got a valid hex value
    if (!$this->isHex($bgHex)) {
      $this->raiseError("background color '$bgHex' is not a hex color value",
      __FUNCTION__, __LINE__);
      return false;
    }

    // Set the bg color
    $this->bg[0] = $bgHex;

    $this->bg['+1'] = $this->lighten($bgHex, .85);
    $this->bg['+2'] = $this->lighten($bgHex, .75);
    $this->bg['+3'] = $this->lighten($bgHex, .5);
    $this->bg['+4'] = $this->lighten($bgHex, .25);
    $this->bg['+5'] = $this->lighten($bgHex, .1);

    $this->bg['-1'] = $this->darken($bgHex, .85);
    $this->bg['-2'] = $this->darken($bgHex, .75);
    $this->bg['-3'] = $this->darken($bgHex, .5);
    $this->bg['-4'] = $this->darken($bgHex, .25);
    $this->bg['-5'] = $this->darken($bgHex, .1);
..

As you see, the bg-property's values are set via the CssColor::lighten() and CssColor::darken() methods. So, what are we waiting for? Let's look at them:

function lighten($hex, $percent)
  {
    return $this->mix($hex, $percent, 255);
  }

  //--------------------------------------------------
  function darken($hex, $percent)
  {
    return $this->mix($hex, $percent, 0);
  }

Hrm okay, nothing really here, escept that we now know the second parameter is treated as a percentage. This makes me think if it is possible to add more shades to choose from. We will look at that later. Let's look at the mix() method. I will leave out the error handling parts to preserve some space. :)

function mix($hex, $percent, $mask)
  {
    // ...

    for ($i=0; $i&#lt;3; $i++) {
      $rgb[$i] = round($rgb[$i] * $percent) + round($mask * (1-$percent));

      // In case rounding up causes us to go to 256
      if ($rgb[$i] > 255) {
  $rgb[$i] = 255;
      }

    }
    return $this->RGB2Hex($rgb);
  }

  //--------------------------------------------------
  function hex2RGB($hex)
  {
     // ...

    // Regexp for a valid hex digit
    $d = '[a-fA-F0-9]';
   
    // Make sure $hex is valid
    if (preg_match("/^($d$d)($d$d)($d$d)\$/", $hex, $rgb)) {
     
      return array(
       hexdec($rgb[1]),
       hexdec($rgb[2]),
       hexdec($rgb[3])
       );
    }
    if (preg_match("/^($d)($d)($d)$/", $hex, $rgb)) {
     
      return array(
       hexdec($rgb[1] . $rgb[1]),
       hexdec($rgb[2] . $rgb[2]),
       hexdec($rgb[3] . $rgb[3])
       );
    }

    $this->raiseError("cannot convert hex '$hex' to RGB", __FUNCTION__, __LINE__);
    return false;
  }

  //--------------------------------------------------
  function RGB2Hex($rgb)
  {
    // ...

    $hex = "";
    for($i=0; $i < 3; $i++) {

      // Convert the decimal digit to hex
      $hexDigit = dechex($rgb[$i]);

      // Add a leading zero if necessary
      if(strlen($hexDigit) == 1) {
  $hexDigit = "0" . $hexDigit;
      }

      // Append to the hex string
      $hex .= $hexDigit;
    }

    // Return the complete hex string
    return $hex;
  }

Okay, here is the magic! We simply calculate an array of rgb values out of the supplied hex color string, alternate its contents via some cool math formula ($rgb[$i] = round($rgb[$i] * $percent) + round($mask * (1-$percent));) and convert it back to hex and return it! This is actually quite simple.

Let us implement more shades. In the CssColor::setPalette() change

$this->bg['+1'] = $this->lighten($bgHex, .85);
    $this->bg['+2'] = $this->lighten($bgHex, .75);
    $this->bg['+3'] = $this->lighten($bgHex, .5);
    $this->bg['+4'] = $this->lighten($bgHex, .25);
    $this->bg['+5'] = $this->lighten($bgHex, .1);

    $this->bg['-1'] = $this->darken($bgHex, .85);
    $this->bg['-2'] = $this->darken($bgHex, .75);
    $this->bg['-3'] = $this->darken($bgHex, .5);
    $this->bg['-4'] = $this->darken($bgHex, .25);
    $this->bg['-5'] = $this->darken($bgHex, .1);

to

$this->bg['+1'] = $this->lighten($bgHex, .95);
    $this->bg['+2'] = $this->lighten($bgHex, .9);
    $this->bg['+3'] = $this->lighten($bgHex, .85);
    $this->bg['+4'] = $this->lighten($bgHex, .8);
    $this->bg['+5'] = $this->lighten($bgHex, .75);
    $this->bg['+6'] = $this->lighten($bgHex, .7);
    $this->bg['+7'] = $this->lighten($bgHex, .65);
    $this->bg['+8'] = $this->lighten($bgHex, .6);
    $this->bg['+9'] = $this->lighten($bgHex, .55);
    $this->bg['+10'] = $this->lighten($bgHex, .5);
    $this->bg['+11'] = $this->lighten($bgHex, .45);
    $this->bg['+12'] = $this->lighten($bgHex, .4);
    $this->bg['+13'] = $this->lighten($bgHex, .35);
    $this->bg['+14'] = $this->lighten($bgHex, .3);
    $this->bg['+15'] = $this->lighten($bgHex, .25);
    $this->bg['+16'] = $this->lighten($bgHex, .2);
    $this->bg['+17'] = $this->lighten($bgHex, .15);    
    $this->bg['+18'] = $this->lighten($bgHex, .1);
    $this->bg['+19'] = $this->lighten($bgHex, .05);  
   
    $this->bg['-1'] = $this->darken($bgHex, .95);
    $this->bg['-2'] = $this->darken($bgHex, .9);
    $this->bg['-3'] = $this->darken($bgHex, .85);
    $this->bg['-4'] = $this->darken($bgHex, .8);
    $this->bg['-5'] = $this->darken($bgHex, .75);
    $this->bg['-6'] = $this->darken($bgHex, .7);
    $this->bg['-7'] = $this->darken($bgHex, .65);
    $this->bg['-8'] = $this->darken($bgHex, .6);
    $this->bg['-9'] = $this->darken($bgHex, .55);
    $this->bg['-10'] = $this->darken($bgHex, .5);
    $this->bg['-11'] = $this->darken($bgHex, .45);
    $this->bg['-12'] = $this->darken($bgHex, .40);
    $this->bg['-13'] = $this->darken($bgHex, .35);
    $this->bg['-14'] = $this->darken($bgHex, .3);
    $this->bg['-15'] = $this->darken($bgHex, .25);
    $this->bg['-16'] = $this->darken($bgHex, .2);
    $this->bg['-17'] = $this->darken($bgHex, .15);
    $this->bg['-18'] = $this->darken($bgHex, .1);
    $this->bg['-19'] = $this->darken($bgHex, .05);

This gives us a whole range of new shades! Here are some stylesheets I could come up with using them:

Picture of fifth generated layout

Picture of forth generated layout

Picture of seventh generated layout

Much credit goes to Patrick Fitzgerald for this very nice script!

Thanks for reading! Have a good one, all!

 
&nsbp;

You can skip to the end and add a comment.

[...] the PHP-Coding-Practices.com site today, there’s a new tutorial posted showing how to create monocromatic (variations of the same color) CSS stylesheets quickly [...]

[...] How To Generate Monochromatic CSS Stylesheets Within Seconds Using PHP | PHP Coding Practices - Beco... (tags: php css) [...]

Hagrin said on Jun 10, 2007:

Great tutorial! I'm actually going to try and give this a try later on my dev server and see how it works. I actually liked the other article too so this site has been producing some solid info - keep up the great work.

I think the Drupal Garland theme works off a monochomatic theme, but I could be wrong.

Tim Koschuetzki said on Jun 10, 2007:

Thank you for the nice comments, Hagrin. :) I very much appreciate them.

Please let me know how your trial run turns out. I will provide as much help as possible if you run into problems.

Thank you!

tomtom  said on Jun 10, 2007:

Thanks!

Nice tutorial. Working cool for me.

cheers

postgresql said on Jun 12, 2007:

Good work :)

[...] How To Generate Monochromatic CSS Stylesheets Within Seconds Using PHP | PHP Coding Practices - Beco... (tags: css php webdesign color monchromatic) [...]

Mgccl said on Jun 13, 2007:

The first thought in my head:
All those CSS masters got totally owned.

Good work, I might implement it on my site so it is a different color everyday

Tim Koschuetzki said on Jul 08, 2007:

Thank you, all. :)

haiko  said on Sep 13, 2007:

if say, i'd want to work with a mysql database.
is it possible to change

$base = new CSS_Color('99E456');

so that the value is a variable, that has been extracted from a database?

Tim Koschuetzki said on Sep 13, 2007:

Sure, why should this be a problem? The CSS_Color object has a constructor which receives a string as the base color, so you can supply anything that is a string, no matter where it came from.

haiko  said on Sep 13, 2007:

ok, thanks for the quick reply.

since i'm not an expert on php, i tried this:

$base = new CSS_Color($newcolor);
and

$base = $newcolor;

where, of course $newcolor is the variable taken from the database. but it didnt work out. how should i do this? any suggestions?

Tim Koschuetzki said on Sep 15, 2007:

$base = new CSS_Color($newcolor);

Should work fine. What is the contents of $newcolor?

haiko  said on Sep 15, 2007:

the contents are extracted, eg. extract(mysql_fetch_assoc($result));

the content is a text string, just like a manual input like FFCC00 or any color. but it won't turn up in the page.

Tim Koschuetzki said on Sep 15, 2007:

Please show the entire script.

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.