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.
The 642-426 exam are for troubleshooting unified communications. The troubleshooting exam for XP is 70-271 and the troubleshooting exams for XP desktops is 70-272. The 70-292 exams are for mcsa certification for windows server 2003. The BCMSN certification 642-812 is for network specialists. The most unique exam is the Cisco voice 642-432 exam. The SCSA exam 310-200 is a very extensive exam.
Stroll on over and visit Robert Nyman
March 1, 2007
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. :-)
Stroll on over and visit Matt Boothby
March 1, 2007
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.
Stroll on over and visit Mark J
March 1, 2007
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.
Stroll on over and visit Zarniwoop
March 1, 2007
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
#includestatement 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.Stroll on over and visit Chris J. Davis
March 1, 2007
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?
Stroll on over and visit Bryan Veloso
March 1, 2007
* 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.
Stroll on over and visit Prashant
March 1, 2007
This is a great tutorial, I'll definitely be using this and you're making use of OOP which is even better!
Stroll on over and visit Chris J. Davis
March 1, 2007
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.
Stroll on over and visit Chris J. Davis
March 1, 2007
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.
Stroll on over and visit bish
March 1, 2007
Ooh! This looks quite fun... thanks for putting it together, Chris. I'll be referencing it for quite a while. :)
Stroll on over and visit Morydd
March 1, 2007
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.<?phpIf you visit the page in IE you get the gif, otherwise you get the png.if ($b == "IE") echo "gif";
else echo "png";
?>') repeat-x top left;
Stroll on over and visit Zarniwoop
March 1, 2007
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.Stroll on over and visit Indranil
March 1, 2007
Ooh! This is really nice. I did see someone use PHP as CSS earlier, but didn't get the purpose. Thanks for the tutorial.
Stroll on over and visit Chris J. Davis
March 1, 2007
Hey Daniel,
That looks interesting, I look forward to what you are able to turn out.
Stroll on over and visit luxuryluke
March 1, 2007
YES! I praise heavily the merging of languages!
To each his strength!
Great article, Chris, and great experiment, Daniel!
Stroll on over and visit gpessia
March 1, 2007
Good...
Stroll on over and visit WebtrafficJunkie
March 1, 2007
This is an awesome article! Thanks for the information!
Stroll on over and visit Chris J. Davis
March 1, 2007
Sweet Ozh, I am very much in favor of seeing other ways to do things.
Thanks for the tip.
Stroll on over and visit moe
March 1, 2007
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 !
Stroll on over and visit Devlin Palmer
March 1, 2007
Very helpful! Thanks. :)
Stroll on over and visit Pete L
March 1, 2007
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!!! :)
Stroll on over and visit Andrew Blake
March 1, 2007
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
Stroll on over and visit Robert Accettura
March 5, 2007
I'd question how efficient this is for performance. Now you've likely got a PHP generated page, and PHP generated stylesheet. 2 tasks (ideally in parallel that need to be run through php).
If your only randomizing the header, or a few smaller things it would be better to use a block of css in the header of the page to do it. This way your css is static (and fast) and your server only has to process 1 php page.
Will somebody think of the servers?
Stroll on over and visit esearing
March 8, 2007
Seems a bit of overkill to create dynamic CSS but I can see its use for the background rotator.
I wonder if the OOP approach might be better suited for CSS style swapping for those who are visually impaired? Paragraph Fonts, form fonts, and other content fonts, could be dynamically increased/decreased via a couple of icons on the page while the headers and other font styles remain constant. It might be more elegant than maintaining multiple style sheets and doing a switch.
Of course one would have to build in persistance between pages and visits.
Stroll on over and visit Domi
March 9, 2007
Why not ?
Good idea !
Stroll on over and visit drakazz
March 9, 2007
Amazing! Let's digg this!
Stroll on over and visit IndoDX
March 15, 2007
So, parsing PHP variable to CSS right?
Stroll on over and visit Chris J. Davis
March 16, 2007
IndoDX,
Yeah, basically. This shows you how to use PHP to globally certain CSS properties.
Stroll on over and visit G3
March 22, 2007
I am using a similar technique at work. I have 11 different sites running off a core template, and I use custom php stylesheets to individualize each site.
I just used variables for my customization though. I like your use of classes here.
Stroll on over and visit Chris J. Davis
March 26, 2007
Classes can make things much easier. Glad you find something helpful here.
Stroll on over and visit Torkil
March 26, 2007
@Myrodd: Some shorter code for you :)
background: url('/css_images/paper-trans.echo ($b == "IE" ? 'gif' : 'png'; ?>') repeat-x top left;
@Chris D:
The tutorial is nice, but I don't see from this example why the OOP-approach is beneficial. It seems like OOP for the sake of OOP. After all I could just write this PHP-code:
$font = array(
headline = '"Trebuchet MS", sans-serif',
body => '"Times New Roman", serif',
menu => 'Arial, Heveltica, sans-serif');
And this in the CSS:
body {
font-family: = $font['body'] ?>;
}
h1{
font-family: = $font['headline'] ?>;
}
.menu {
font-family: = $font['menu'] ?>;
}
And that would be it. Alot less code, almost easier way to define the variables and totally reusable.
You even defined an array in the constructor that limits the amount of variables you can put in there, so if you choose to add a "caption" textstyle, you have to add that into the constructor as well.
So why did you choose the OOP-approach? It seems a bit like overkill just to be able to reuse some small variables here and there.
Stroll on over and visit Torkil
March 26, 2007
Seems like my php-code didn't make it through the filter...
can I use
Or maybe [code]Code here[/code]?
Stroll on over and visit Torkil
March 26, 2007
Allright... Here I try again then. Feel free to delete my two previous posts! :)
@Myrodd: Some shorter code for you :)
background: url('/css_images/paper-trans.echo ($b == "IE" ? 'gif' : 'png'; ?>') repeat-x top left;@Chris D:
The tutorial is nice, but I don't see from this example why the OOP-approach is beneficial. It seems like OOP for the sake of OOP. After all I could just write this PHP-code:
$font = array(headline => '"Trebuchet MS", sans-serif',
body => '"Times New Roman", serif',
menu => 'Arial, Helvetica, sans-serif');
And this in the CSS:
body {
font-family: = $font['body'] ?>;
}
h1 {
font-family: = $font['headline'] ?>;
}
.menu {
font-family: = $font['menu'] ?>;
}
And that would be it. Alot less code, almost easier way to define the variables and totally reusable.
You even defined an array in the constructor that limits the amount of variables you can put in there, so if you choose to add a "caption" textstyle, you have to add that into the constructor as well.
So why did you choose the OOP-approach? It seems a bit like overkill just to be able to reuse some small variables here and there.
Stroll on over and visit karynn
January 23, 2008
I would love to see the code from the tutorial (since it's kind of hard to tell what code goes in which file) and the working example, but your links are broken :(
Stroll on over and visit Chris J. Davis
January 26, 2008
Sorry Karynn, the links are fixed now.
Stroll on over and visit Tamer
March 19, 2008
really good article, i added it to my blog and to wikipedia css page : http://en.wikipedia.org/wiki/Cascading_Style_Sheets#Further_reading
Stroll on over and visit andrej
April 23, 2008
muh,...
i created a style.php and refernced it as
link rel="stylesheet" href="style.php" type="text/css"
in head HTML
it wont work, i got this in source and no function:
link rel=?stylesheet? href=?style.php? type=?text/css?
inside style.php for instance i put:
?php header(”Content-type: text/css”); ?>
a:link { text-decoration : none; color : # #FF0000; }
a:active { text-decoration : underline; color : # #FF0000; }
a:visited { text-decoration : none; color : # #FF0000; }
a:hover { text-decoration : underline; color : #660000; }
this wont work, any idea why?
best, Andrej
Stroll on over and visit Devlin
May 27, 2008
Why use php echo $font->name; instead of just =$font['name']? It's shorter and better looking in my opinion.
I've removed opening and closing tags on both of those so WordPress wouldn't ignore them.
Stroll on over and visit Demon
June 23, 2008
I got a question based on css. i am making a cms in php and the over all cms is working out great and so are the templates i have created. now my question is this. when i go into my theme class and take the styles and alter them and place the styles in a css file save it and then link the css to my theme class file when i render out my images they do not change. i am using the background url() style method to display the td background images for the blocks and all that in the theme class file if that is set in the td as a style it works but when i put the style codes into a css file the images do not load. why is that and can i fix it? a example like background url(Theme/Green Life/images/Banner.gif) now that in the styles td works but that in a css file does not work. but if i add the domain to the url it works. i cant seem to figure out how to make that code work in a css with a php theme class. any help ?