22 Comments, 0 Tweets, why not add one?
There are a number of ways to use PHP with other web languages and technologies. I myself use PHP in some of my JS scripts and sometimes even in CSS files.
While surfing the net I found someone asking for a way to create ‘color variables’. I commented outlining a way that this could be accomplished using PHP, but it was of coure garbled since I was using < and > in my comment.
Thankfully Bish found a tutorial on the net that said basically the same thing, but I thought I would write a little something up here as well, covering creating ‘color constants’ in your CSS, and more interesting, creating randomly generated paths for the backgrounds of DIV’s.
It is really a no-brainer to want to take some common CSS elements and simplify the process of changing them or updating them. Before we get any further though, let me stress that this is a limitied use technique. The very nature of CSS is to cascade, which would be defeated by this if you went nuts with it.
So lets take a very simple example; we want to define the base color scheme and font families we want to use for body, h1 and our menu. Lets move those into PHP so that we can update them all with one small change.
First we begin with a bit of code that forces our PHP to conduct itself as though it were CSS:
<?php
header('Content-type: text/css');
?>
Now that we have sent our PHP undercover as CSS we need to write some code to handle our fonts and colors. And here is where we get into new territory for Sillyness. We will be writing Object Oriented Code for this tutorial.
There are many reasons for this, the least of which would be that having a font object and a color object just makes sense when you think about it.
The basic building block of OOP is the class. In the simplest terms a class contains both variables and functions (which we should be familiar with by now), and serves as the template from which to spawn specific (and multiple) instances of that class.
Instances of a class are what we call ‘objects’; each object you ‘spawn’ is a kingdom unto itself working within the confines of the variables and functions that are defined in the class.
So lets go through the steps needed to make an object beginning with a look at PHP 4 syntax:
<?php
// first we create our font class
class font {
// now lets create our CONSTRUCTOR function
function font($args=array()) {
$this->fields = array('headline','body','menu');
foreach ($this->fields as $field) {
$this->{"$field"} = $args["$field"];
}
}
}
?>
Okay, so lets talk about what the above code is actually doing. First we create a class, in this case font and then we create a function called a ‘constructor’ and as I am sure you can already guess it allows us to construct the array that we will be populating our objects with.
So now, lets take a closer look at our constructor function. As you can see it contains an array that will hold our font information. You pass information to the function in an array as well, we then set the fields in the array equal to the arguments passed to our constructor with a foreach loop. All pretty straightforward.
We would build the color class in the same way. There is a pretty large difference between PHP 4 and 5 when it comes to writing constructors. In 4 the class and constructor must share the same name, in PHP 5 you actually call the constructor… CONSTRUCTOR! Scary I know:
<?php
// first we create our font class
class font {
// now lets create our CONSTRUCTOR function
function __construct($args=array()) {
$this->fields = array('headline','body','menu');
foreach ($this->fields as $field) {
$this->{"$field"} = $args["$field"];
}
}
}
?>
With me so far? If not, there is an excellent walk through of OOP from Zend Technologies… it mentions bears, how great is that?
My gawd I am witty. So now it is time to create our font object. Fortunately this couldn’t be easier:
$font = new font(array(
headline => "Trebuchet MS, san-serif",
body => "Times New Roman, serif",
menu => "Arial, Heveltica, san-serif",
));
Very, very straightforward here people. We are saying that $font is a new instance (or object) of the font class, then we are creating an array that will be passed back to the font class via the constructor. Basically we are saying set the class array equal to the arguments array.
Okay now we have a font object that contains the fonts we want to use, we need to call those fonts out in the appropriate places:
body
{
font-family: <?php echo $font->body; ?>;
}
h1
{
font-family: <?php echo $font->headline; ?>;
}
.menu
{
font-family: <?php echo $font->menu; ?>;
}
And that is all there is to it. We call for the appropriate ‘field’ from our class, which has been set equal to the corresponding argument from our object.
So now that we have done a little OOPing, what say we write a function that will allow us to randomly select the background of a DIV?
So the basic gist of this is that we have a DIV, lets say .header and we want it to have a different background image each time we refresh our site. Since we have already set up our PHP file to parse as CSS, this is a breeze:
function rotater() {
$path='/path/to/my/images/';
for ($i=0; $i < 1; $i++) {
$random = (rand()%6);
$file = 'header';
$image = $path . $file . $random . '.png';
}
echo $image;
}
Okay so lets take the above code apart; first we are setting a variable ($path) equal to the path to our images directory, pretty straightforward. We are then using rand() to generate a random number, in this case between 0 and 6 (hence the rand()%6)).
Next we define the $file variable, and set it to header; we then put them all together to get $image which should be randomly generated each refresh.
We then call the rotater() function from our CSS and viola, we have a randomly chosen background image for our header div:
.header
{
background-image: url(<?php rotater(); ?>) no-repeat;
}
Well I think that is all for now, I hope you all have enjoyed this bit o’ nonsense as much as I have. You can find the code from this tutorial over here (you will notice that I moved most of the PHP into its own file that I then included into style.php) and you can see a working copy right here. Go ahead and refresh the page a couple of times and watch the image path change.
If you post about this on Twitter, please use the hashtag #silly534.
Wow, nice. I’m definitely gonna’ be using this method soon. Great job, Chris. I need to brush up on my OOP as well, so this tutorial is just the practice I need.
What I recommend doing is creating two CSS files… one with caching headers, and this will hold your static CSS. You can still use PHP to make generating it easier, but it won’t change that often. Then, create a second CSS file with all the fancy dynamic PHP-CSS stuff that Chris suggested, and let that be downloaded each time. That way, the stuff that needs to be dynamic is dynamic, and the stuff that doesn’t, isn’t.
Also, a little tip: when you change your static CSS, you’ll want browsers to pick it up immediately. But most browsers will be caching your CSS. So what I do to trigger a reload, is having the src attribute of the <style /> call have a variable appended to it in a query string… like: <style type="text/css" src="style.css.php?rev=<?php echo $css_revision; ?>" />
Then, at the top of my header.php file, I set $css_revision to a number. Each time I roll out a major change, I increment $css_revision, and all browsers download the new CSS instantly, because they think it’s a different file.
I did read the article, but maybe you didn’t make my point clear (of course this would be my fault).
One advantage of using an external CSS file is to split content and presentation. This way you wouldn’t have to download the ‘style’ every time, which saves some bandwidth. Using no-cache headers renders this bandwidth saving ridiculous since the CSS file would be read every time the page is loaded. Nevertheless there are different reasons why to use PHP inside external CSS files.
a) Variables which I named static (fonts, colors,…) are supposed to stay unchanged for a longer time. For such rules you would use PHP variables in external CSS files and benefit from client-side caching. PHP variables just make it easier to write the code.
b) Random content is different, since it is supposed to change on every page load. My solution is to split these things out of the external CSS file and include them as inline style into the generated HTML. Here, PHP’s #include statement is your friend. This way, the random CSS rules would be loaded every time the page loads and you wouldn’t have to worry about caching.
Mark J,
Hey long time, no comment. Your solution is interesting, and one I thought of initially. I am a fan of splitting out CSS that is only used in some places, but I just couldn’t bring myself to do it here. I might try that in Believe and see how much it adds to the complexity.
And I have been seeing the ?version=blah and ?rev=’blah blah’ infecting the net lately, you too huh?
* Bryan bows.
I am definitely going to use this. :D Beats standard image rotation in a heartbeat. And, it’ll force me to get used to OOP.
This is a great tutorial, I’ll definitely be using this and you’re making use of OOP which is even better!
Zarniwoop,
Thanks for clarifying. I still don’t really agree with you, but at least now I know what we are disagreeing about! I am not sure where people have gotten the idea that CSS is about permanence… CSS is about seperating structure from styling. There are ‘bandwidth’ savings that are part of it, but that is not the point of CSS nor should it be.
Robert,
I agree with alot of your thoughts, I really only use PHP in CSS when I want to do things like the image rotater. But I would disagree that people who want to use an approach like this have a lack of stylesheet skills. I also think that acknowledging the need for this in CSS, but looking down on those who are making it work until the W3C get thier act together is a bit much.
But to each his/her own. Thanks for the discussion.
Bish,
Sure, hope you find it helpful.
Zarniwoop,
Not sure if you actually read the article, but I a.) already stated that I split out the PHP into its own file and b.) not having the PHP referenced from within the CSS itself defeats the purpose.
Mathias,
Interesting point about the expires header, but I have never run into a problem with caching, and I have been doing this for a while. As for Inman’s solution, I am not a fan; there are a number of problems with it from the fact that it requires mode_rewrite to well, lots of other things.
This example is a very limited one by design, but simplistic by design as well. Thanks for the comments guys.
Ooh! This looks quite fun… thanks for putting it together, Chris. I’ll be referencing it for quite a while. :)
On my old design, I used PHP to do my CSS file. I had 4 or 5 different headers, and each header had a slightly different color scheme. When you first accessed the page it set a session cookie, so the page wouldn’t change each time you navigated,
Now I just use it for browser detection. I use a png with transparency for the header and footer, but since that doesn’t work in IE, I have a gif of the same image. Looks a lot worse, but I get the transparency. I use the php to do browser detection then feed it this:
background: url('/css_images/paper-trans.<?php
if ($b == "IE") echo "gif";
else echo "png";
?>') repeat-x top left;
If you visit the page in IE you get the gif, otherwise you get the png.
One should be careful because CSS is assumed to be static, so most browser cache it for a long time. A solution would be to split the CSS into a static part (font, colors, etc.) loaded from a file and a dynamic part (all things random) #included via PHP in the header of the actual html file.
Ooh! This is really nice. I did see someone use PHP as CSS earlier, but didn’t get the purpose. Thanks for the tutorial.
Hey Daniel,
That looks interesting, I look forward to what you are able to turn out.
YES! I praise heavily the merging of languages!
To each his strength!
Great article, Chris, and great experiment, Daniel!
Good…
This is an awesome article! Thanks for the information!
Sweet Ozh, I am very much in favor of seeing other ways to do things.
Thanks for the tip.
Its really funny that i havent done something like this … i mean its so obvious … i guess now is the time … im using a function in my new design to rotate my header image between AM and PM but i would probably save some space and make it much cleaner by making some classes and dumping them to a css :D
great article… dig it !
Very helpful! Thanks. :)
This is an excellent technique. I have seen this used in a variety of Government web sites. This is totally going to help in future projects. Can’t wait to try it out!!! :)
Hi
Great article.
But tell me, why doesn’t this work?
background-image: url(‘my_image_generator_script.php’)
???
it works in html img tags, why not in css??
waah
Chris,
To be more clear, I should say that the people I’ve met that have suggested such a solution has had a lack of stylesheet skills. But again, it’s up to everyone to do what they like, but it’s not a solution/approach I’d use.
However, if I came across as being elitistic, I just want to state that I do encourage thinking out-of-the-box. It just comes down to what the idea is. :-)