Creating a Dynamic Vertical Gradient in PHP
In This Tutorial
- Introduction
- Setting Up the Parameters
- Check the Variables for Validity
- Establish Working Variables
- Create the Image
Introduction
This is a tutorial for a script that I find indispensable. Gradients are a necessary and simple tool of web design, providing the perfect transition from color to color. The problem that I often find is the limitations the use of images puts on dynamic templates. I am a huge fan of dynamic templates – allowing color customization to match user preference as opposed to designer preference. Green may be the designer’s favorite color, but blue is mine, and purple is a friend of mine’s. So why should we have to look at your overly green website?
I for one don’t think we should. It’s simple enough to put background-color : <?php echo $_COOKIE['background-color']; ?> in your CSS file to alter basic colors. Unfortunately, it’s not that easy with more complex templates. Designs are comprised of more than strings in CSS. They include images, which are created in programs like PhotoShop, not browsers or web servers.
At least, that’s how the majority of web developers view images. Fortunately, they’re wrong. Starting at the basics, this tutorial is going to show you how to create dynamic gradients for your templates. Not only will this save you time in gradient creation (since you won’t have open PhotoShop just to create a gradient anymore), but this will allow you to use a much greater variety of template choices for your users. Limiting template choice due to the cost, time, or effort of image creation is a thing of the past – at least when it comes to gradients.
As a side note for those of you interested in the abilities of PHP, you can use PHP to change the hue of your images, thus making all of your images compatible with any color; but that won’t be covered in this tutorial. It involves more advanced programming. This tutorial serves more as an introduction to PHP’s image capabilities, covering easy-to-calculate images.
In an extreme example, let’s say I allow my members to enter their own color values, similar to vBulletin’s profile customization for those of you familiar with that. They type in #a0a0ff for the header background color and #008000 for the navigation bar. But there’s a problem! There is a gradient that fades the header to the navbar. I don’t want to have to manually create every possibly combination of colors! So what do I do? This a hurdle that this tutorial will help you jump.
Default Template Example:
Charles Stover’s Website
<style type="text/css"><!-- #my-site-header { background-color : #ffffff; /* gradient: 16px height, #ffffff start, #404080 end */ background-image : url('http://i.imgur.com/4L3aj.gif'); background-position : left bottom; background-repeat : repeat-x; } #my-site-header h1 { padding : 6pt 0; text-align : center; } #my-site-header h1, #my-site-navigation ul { margin : 0; text-align : center; } #my-site-navigation { background-color : #404080; padding : 3pt 0 6pt 0; } #my-site-navigation a { color : #ffffff; text-decoration : none; } #my-site-navigation li { display : inline; list-type : none; padding : 0 6pt; } --></style> <div id="my-site-header"> <h1>Charles Stover's Website</h1> </div> <div id="my-site-navigation"> <ul> <li><a href="http://www.charlesstover.com/" title="CharlesStover.com">Charles Stover</a></li> <li><a href="http://www.twitter.com/charlesstover" title="Charles Stover (charlesstover) on Twitter">Twitter</a></li> <li><a href="http://webdesignfan.com" title="WebDesignFan.com">Web Design Fan</a></li> </ul> </div>
Static Image Example:
When the user selects the two colors #a0a0ff and #008000, he or she will get these undesired results (a gradient that doesn’t match the background colors).
Charles Stover’s Website
Dynamic Image Example:
Using dynamic gradients, the user will see this instead.
Charles Stover’s Website
You didn’t even have to lift a finger or open PhotoShop to create the gradient. It created itself!
Setting Up the Parameters
The first things we need to establish when setting up a dynamic gradient are what parameters need to be dynamic. The height, start color, and/or end color? If any of these need to change on a per-image basis, they’ll need to be set via a $_GET variable. Otherwise, you can set them statically in the PHP file itself (e.g. $height = $_GET['height']; versus $height = 16;).
Using mod_rewrite for this is recommended. This isn’t a mod_rewrite tutorial, and I don’t know which variables you want to have be static, so I won’t provide an extensive code for that. Here is one for having all three variables be dynamic, where gradient.php is the gradient generating file:
RewriteEngine On
RewriteRule ^gradients\/(\d+)\-([a-fA-F\d]{6})-([a-fA-F\d]{6})\.gif$ gradient.php?height=$1&from=$2&to=$3 [L,NC]
This will redirect gradients/[integer for height]-[hex for start color]-[hex for end color].gif to gradient.php?height=[integer for height]&from=[hex for start color]&to=[hex for end color].
You, of course, may remove any variables from this equation if they are to remain static in the PHP file. My most used version of this code has a static height and start color, therefore I only need to reference the file as gradients/[hex for end color].gif. There’s no use in having the other variables in the URL if they don’t do anything.
Check the Variables for Validity
Something that isn’t done often enough in programs is checking for legitimate variable values of user input. While mod_rewrite uses regular expressions to prevent the redirection of bogus requests, if the user knows the URL to the gradient.php file, they may input what they please. For that reason, to prevent PHP errors from clogging error logs, to get into the habit of checking variable input, and to prevent worse-case-scenario injected code in complicated color algorithms, we check for appropriate values.
<?php // provide a generic 404 error if... >if ( !array_key_exists('from', $_GET) || // FROM/START color does not exist !preg_match('/^[a-fA-F\d]{6}$/', $_GET['from']) || // FROM/START color is not valid hex !array_key_exists('to', $_GET) || // TO/END color does not exist !preg_match('/^[a-fA-F\d]{6}$/', $_GET['to']) || // TO/END color is not valid hex !array_key_exists('height', $_GET) || // HEIGHT does not exist !is_numeric($_GET['height']) || // HEIGHT is not numeric // Be sure to set your minimum and maximum heights that you'll be using here. // If you need a 300px gradient, you'll need to up the value to 300. // But be sure to use a limit! A user who inputs 9,999,999 will destroy your server's memory and bandwidth. $_GET['height'] < 4 || // HEIGHT is too small (especially < 1) $_GET['height'] > 64 // HEIGHT is too large ) { header('HTTP/1.1 404 Not Found'); // 404 header header('Content-Type: text/plain; charset=utf-8'); // text document exit("Move along. Nothing to see here.\r\n\r\nSincerely,\r\nCharles Stover\r\nwww.CharlesStover.com"); // generic 404 error } ?>
Calculate the Variables
If only PHP understand hex innately, my job would be easier. There are three things we’ll need to calculate before generating the image: the RGB value of the start color, the RGB value of the end color, and the basic algorithm for determining every shade in between. All three of these are rather simple to calculate, and they are evidence for why programmers need to do well in math class (this is just a case of basic math, however).
<?php $height = $_GET['height']; // static height goes here $start = Array(); // static start color RGB goes here, e.g. Array(255, 0, 0) for red $end = Array(); // static end color RGB goes here, e.g. Array(0, 0, 255) for blue /* Convert start hex to RGB. Delete this block of code if using a static start color. For three values (red, green, and blue)... */ for ($x = 0; $x < 3; $x++) { /* We need to get the value of the color from its place in the hex string. e.g. for red, we'll want the first two characters. e.g. for blue, we'll want the last two characters. Take the color #fc8400 for example. For RED, $value1 will be f, $value2 will be c For GREEN, $value1 will be 8, $value2 will be 4 For BLUE, $value1 will be 0, $value2 will be 0 */ $value1 = substr($_GET['from'], $x * 2, 1); $value2 = substr($_GET['from'], $x * 2 + 1, 1); /* Convert the base-16 numbers to base-10. e.g. 0 is the 0th character so will be converted to 0 e.g. 8 is the 8th character so will be converted to 8 e.g. A is the 10th character so will be converted to 10 e.g. F is the 15th character so will be converted to 15 $value1 is multiplied by 16 because every 1 first digit in hex is equivalent to 16 second digits. e.g. 10 in hex is 16 in decimal, 20 is 32, f0 is 240. /* $value1 = stripos('0123456789abcdef', $value1) * 16; $value2 = stripos('0123456789abcdef', $value2); /* Add the decimal value to the array. e.g. FF when converted to RGB becomes $value1 = 'F' * 16 = 15 * 16 = 240; $value2 = 'F' = 15; $value1 + $value2 = 255; // FF = 255 */ array_push($start, $value1 + $value2); } /* Convert end color to RGB. Delete this block of code if using a static end color. Condensed because the algorithm was explained above. */ $end = Array(); for ($x = 0; $x < 3; $x++) array_push($end, stripos('0123456789abcdef', substr($_GET['to'], $x * 2, 1) ) * 16 + stripos('0123456789abcdef', substr($_GET['to'], $x * 2 + 1, 1) ) ); /* Now we need to calculate how much the gradient will change with each pixel. I call these "steps" A step for red, a step for green, and a step for blue. In English, if we're trying to get from 0 to 100 in 4 steps, each step needs to be 25 (25, 50, 75, 100). */ $step = Array(); // For each of red, green, and blue... >for ($x = 0; $x < 3; $x++) { /* Take the difference between the two values. e.g. 100 - 0 */ $difference = $end[$x] - $start[$x]; /* Calculate the step size for this difference. e.g. 100 / 4 */ $step_size = $difference / $height; array_push($step, $step_size); } ?>
Here is a blunt example of $step values:
<?php $height = 10; // gradient with 10px height $start = Array(250, 0, 0); // start color is #fa0000 $end = Array(0, 200, 100); // end color is #00c864 /* Each pixel's RED value needs to be 25 shades LIGHTER than the last. Each pixel's GREEN value needs to be 20 shades DARKER than the last. Each pixel's BLUE value needs to be 10 shades DARKER than the last. */ $step = Array(-25, 20, 10); /* After 10 steps, RED will be 250 + -25 * 10 = 0 GREEN will be 0 + 20 * 10 = 200 BLUE will be 0 + 10 * 10 = 100 The magic of algorithms: $start[$x] + $step[$x] * $height = $end[$x] */ ?>
Create the Image
Now that the variables are calculated, we can just use PHP’s image functions to actually create and output the image.
<?php // Tell the browser it's a GIF image. header('Content-Type: image/gif'); // Create an image with a width of 1 and height of $height. // Width only needs to be 1px because it will presumably be tiled horizontally. $gradient = imagecreatetruecolor(1, $height); // For each pixel in the image... >for ($x = 0; $x < $height; $x++) { // Take the start color and increment it a step for every pixel. $red = $start[0] + $step[0] * $x; $green = $start[1] + $step[1] * $x; $blue = $start[2] + $step[2] * $x; // Create an image-readable color value. $color = imagecolorallocate($gradient, $red, $green, $blue); // Set the color of the pixel 0 from the left and $x from the top to $color. imagesetpixel($gradient, 0, $x, $color); } // Output the image. imagegif($gradient); // Destroy the image from memory. imagedestroy($gradient); ?>
And there you have it! A gradient that creates itself. Here is the full code:
<?php // provide a generic 404 error if... >if ( !array_key_exists('from', $_GET) || // FROM/START color does not exist !preg_match('/^[a-fA-F\d]{6}$/', $_GET['from']) || // FROM/START color is not valid hex !array_key_exists('to', $_GET) || // TO/END color does not exist !preg_match('/^[a-fA-F\d]{6}$/', $_GET['to']) || // TO/END color is not valid hex !array_key_exists('height', $_GET) || // HEIGHT does not exist !is_numeric($_GET['height']) || // HEIGHT is not numeric // Be sure to set your minimum and maximum heights that you'll be using here. // If you need a 300px gradient, you'll need to up the value to 300. // But be sure to use a limit! A user who inputs 9,999,999 will destroy your server's memory and bandwidth. $_GET['height'] < 4 || // HEIGHT is too small (especially < 1) $_GET['height'] > 64 // HEIGHT is too large ) { header('HTTP/1.1 404 Not Found'); // 404 header header('Content-Type: text/plain; charset=utf-8'); // text document exit("Move along. Nothing to see here.\r\n\r\nSincerely,\r\nCharles Stover\r\nwww.CharlesStover.com"); // generic 404 error } $height = $_GET['height']; // static height goes here $start = Array(); // static start color RGB goes here, e.g. Array(255, 0, 0) for red $end = Array(); // static end color RGB goes here, e.g. Array(0, 0, 255) for blue /* Convert start hex to RGB. Delete this block of code if using a static start color. */ for ($x = 0; $x < 3; $x++) array_push($start, stripos('0123456789abcdef', substr($_GET['from'], $x * 2, 1) ) * 16 + stripos('0123456789abcdef', substr($_GET['from'], $x * 2 + 1, 1) ) ); /* Convert end color to RGB. Delete this block of code if using a static end color. */ $end = Array(); for ($x = 0; $x < 3; $x++) array_push($end, stripos('0123456789abcdef', substr($_GET['to'], $x * 2, 1) ) * 16 + stripos('0123456789abcdef', substr($_GET['to'], $x * 2 + 1, 1) ) ); // Calculate how much the gradient will change with each pixel. $step = Array(); for ($x = 0; $x < 3; $x++) array_push($step, ($end[$x] - $start[$x]) / $height); // Tell the browser it's a GIF image. header('Content-Type: image/gif'); // Create an image with a width of 1 and height of $height. $gradient = imagecreatetruecolor(1, $height); // Set each pixel in the image. >for ($x = 0; $x < $height; $x++) imagesetpixel($gradient, 0, $x, imagecolorallocate($gradient, $start[0] + $step[0] * $x, $start[1] + $step[1] * $x, $start[2] + $step[2] * $x)); // Output the image. imagegif($gradient); // Destroy the image from memory. imagedestroy($gradient); ?>
You’re done! Just call upon your gradient.php file whenever you need to use a gradient! I even use it when the gradient isn’t dynamic, simply because it saves so much time, especially when tweaking colors by only a few values.
Lastly, don’t forget to configure your entity tags and add Expires headers!
Want to pass testking 312-50 exams? Check out our latest comptia security+ study guides and mcse 2008 demos give you 100% exam pass guarantee of 70-270. You can also get testking 642-661 dumps from this website.

1174 Fans
2408 Readers
15570 Followers
It’s really superb blog with full of wonderful articles.Thanks
Valuable info. Lucky me I found your site by accident, I bookmarked it.
nice example of php image manipulaiton.
Best quality of the articles with supportable information related to this blog for the readers. Give more details about this blog for subscribe. Thanks
Couldnt agree more with that, very attractive article
Keep posting stuff like this i really like it
PHP vs CSS for vertical gradient.
I think CSS the best for gradient background
great guide! thanks for sharing the codes!
Keep posting stuff like this i really like it
Great read. Thanks for the info!
Great article for CSS and Web designing and Development.
Its very great and informatics.
It’s actually a great and helpful piece of information. I’m happy that you just shared this helpful info with us. Please keep us informed like this. Thanks for sharing.
Pretty insightful post. Never thought that it was this straightforward in the end. I had spent a great deal of time looking for someone to explain this topic clearly and you are the only one that ever did that. Kudos to you! Keep it up
This was a good read. Thanks for the post.
Hi there, I found your blog via Google while searching for a related topic, your web site came up, it looks great. I’ve bookmarked it in my bookmarks.
This is awesome reading material! It’s packed with useful info that anyone can read and understand. I love to read articles by writers that truly care about the content they produce and share. Thank you. I will most definitely insert a link to http://webdesignfan.com/creating-a-dynamic-vertical-gradient-in-php/ on my site.
I am extremely impressed with your writing talents and also with the format for your blog. Is this a paid theme or did you customize it yourself? Either way stay up the nice high quality writing, it is uncommon to see a great weblog like this one these days..
One of the best articles we have ever read on the internet! I recommend it for sure all your friends, so you may want to look you think that the Internet should be more people writing such a wonderful message. If you can recommend me more such articles on these topics, please have some information.
Straightforward and well crafted, ty for the post.
Interesting information, I will be recommending
Hey
This is a great blog Icame here from twiter.
I am a php developer have experience in joomla wordpress cakephp.If you need my help in theme development please email me
Thanks