Featured: Pink for October

Sillyness, werd


Entry: Variables in your CSS via PHP


 

Meta & Errata


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.

PHP and CSS sitting in a tree

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.

OOPing is the new black

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?

An object lesson

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.

Randomness, my favorite

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.

 

Comments & Pontifications


  1. personal avatar Robert Nyman
    Stroll on over and visit Robert Nyman
    March 1, 2007

    Chris,

    But I would disagree that people who want to use an approach like this have a lack of stylesheet skills.

    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. :-)


  2. personal avatar Matt Boothby
    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.


  3. personal avatar Mark J
    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.


  4. personal avatar Zarniwoop
    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 #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.


  5. personal avatar Chris J. Davis
    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?


  6. personal avatar Bryan Veloso
    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.


  7. personal avatar Prashant
    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!


  8. personal avatar Chris J. Davis
    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.


  9. personal avatar Chris J. Davis
    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.


  10. personal avatar bish
    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. :)


  11. personal avatar Morydd
    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.<?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.


  12. personal avatar Zarniwoop
    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.


  13. personal avatar Indranil
    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.


  14. personal avatar Chris J. Davis
    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.


  15. personal avatar luxuryluke
    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!


  16. personal avatar gpessia
    Stroll on over and visit gpessia
    March 1, 2007

    Good…


  17. personal avatar WebtrafficJunkie
    Stroll on over and visit WebtrafficJunkie
    March 1, 2007

    This is an awesome article! Thanks for the information!


  18. personal avatar Chris J. Davis
    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.


  19. personal avatar moe
    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 !


  20. personal avatar Devlin Palmer
    Stroll on over and visit Devlin Palmer
    March 1, 2007

    Very helpful! Thanks. :)


  21. personal avatar Pete L
    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!!! :)


  22. personal avatar Andrew Blake
    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


  23. personal avatar Robert Accettura
    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?


  24. personal avatar esearing
    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.


  25. personal avatar Domi
    Stroll on over and visit Domi
    March 9, 2007

    Why not ?
    Good idea !


  26. personal avatar drakazz
    Stroll on over and visit drakazz
    March 9, 2007

    Amazing! Let’s digg this!


  27. personal avatar IndoDX
    Stroll on over and visit IndoDX
    March 15, 2007

    So, parsing PHP variable to CSS right?


  28. personal avatar Chris J. Davis
    Stroll on over and visit Chris J. Davis
    March 16, 2007

    IndoDX,

    So, parsing PHP variable to CSS right?

    Yeah, basically. This shows you how to use PHP to globally certain CSS properties.


  29. personal avatar G3
    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.


  30. personal avatar Chris J. Davis
    Stroll on over and visit Chris J. Davis
    March 26, 2007

    Classes can make things much easier. Glad you find something helpful here.


  31. personal avatar Torkil
    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: ;
    }

    h1{
    font-family: ;
    }

    .menu {
    font-family: ;
    }

    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.


  32. personal avatar Torkil
    Stroll on over and visit Torkil
    March 26, 2007

    Seems like my php-code didn’t make it through the filter…

    can I use

    Code here

    Or maybe [code]Code here[/code]?


  33. personal avatar Torkil
    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: ;
    }

    h1 {
    font-family: ;
    }

    .menu {
    font-family: ;
    }

    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.


  34. personal avatar karynn
    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 :(


  35. personal avatar Chris J. Davis
    Stroll on over and visit Chris J. Davis
    January 26, 2008

    Sorry Karynn, the links are fixed now.


  36. personal avatar Tamer
    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


  37. personal avatar andrej
    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


  38. personal avatar Devlin
    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.


  39. personal avatar Demon
    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 ?

Pingbacks & Trackbacks


  1. NWM Blog » Variables in your CSS via PHP » [...] Variables in your CSS via PHP [...]
  2. StanShinn.com » Sillyness Spelled Wrong Intentionally | Variables in your CSS via PHP » [...] on e-Business... Sillyness Spelled Wrong Intentionally | Variables in your CSS via PHP Some tips on dynamically generating CSS from PHP. Note this first code trick by changing thecontent type: < ?php header('Content-type: text/css'); ?> Read full article: Variables in your CSS via PHP [...]
  3. Amanita.net » Blog Archive » Quicklinks for 2005-12-19 » [...] Variables in your CSS via PHP Complicated (to me) but potentially useful. [via weblogtoolscollection] (tags: csstricks php) [...]
  4. nuovoMatic » Blog Archiv » Variables in your CSS via PHP » [...] Link: PHP and CSS [...]
  5. Lorelle on WordPress » Using CSS in PHP » [...] Thanks to a heads-up from Weblog Tools Collection, a must-monitor blog resource site, I learned that Chris J. Davis has been at it again with Variables in Your CSS Via PHP. 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 limited use technique. The very nature of CSS is to cascade, which would be defeated by this if you went nuts with it. [...]
  6. test » Blog Archive » test22 » [...] Variables in your CSS via PHP [...]
  7. davidbisset.com » Variables in your CSS via PHP » [...] A technique to give your CSS more “functionality” via PHP, although you do have to be aware of a few pitfalls and it might be overkill for simple needs. [...]
  8. CSS Variables - Brajeshwar » ...e your CSS. Some of them like CSS-PHP Variable and Variables in your CSS via PHP treats CSS like PHP and thus able to inject PHP variables rendering them inside your CSS codes. The...
  9. » CSS Collection II 2008 CSS Concept: CSS can be just that easy.. » ...ika.com/uni-form/">Uni-Form Sillyness ...

Leave a Reply