When people are asked about features they would like to CSS, “variables” always seems to come up. Whether or not this is a good idea is still something I personally haven’t decided on, but I’d lean toward yes. Regardless, using PHP, it is trivially easy to use variables in CSS. This is certainly not a new trick, but I’ve never specifically covered it so I thought I ought to.
Style.php
Instead of using the .css file extension, use .php
<link rel='stylesheet' type='text/css' href='css/style.php' />
Content-type
At the top of your new style.php file set the Content-type back to CSS:
<?php
header("Content-type: text/css; charset: UTF-8");
?>
Set up variables
Now you can set up variables for whatever you like:
<?php
header("Content-type: text/css; charset: UTF-8");
$brandColor = "#990000";
$linkColor = "#555555";
$CDNURL = "http://cdn.blahblah.net";
?>
Use variables
Below all that PHP stuff, you can just commence regular CSS writing, only you can intermix some PHP to spit out those variables.
#header {
background: url("<?php echo $CDNURL; ?>/images/header-bg.png") no-repeat;
}
a {
color: <?php echo $linkColor; ?>;
}
...
ul#main-nav li a {
color: <?php echo $linkColor; ?>;
}
Extend the power / Other ideas
- While you are at it, might as well compress the CSS with PHP.
- Theoretically you could pull the user agent and attempt to do browser-specific CSS, but that is littered with problems and not recommended.
- Pull the date/time, and perhaps change some stuff on your site for the different seasons or time of day.
- Generate a random number, test the result, use it to set a random background image on your header.
Not working?
I did a totally static test page and it worked fine, then I tried this same technique within a WordPress site and no dice. The solution for me was to leave the file named style.css, and use .htaccess to parse it as PHP. Just make sure this code is in the .htaccess file (Apache servers only) at the same directory level as the CSS file. Then just use PHP inside it as you would any other PHP file.
<FilesMatch "^.*?style.*?$">
SetHandler php5-script
</FilesMatch>
Carlo DeAgazio wrote in to say this works for him in WordPress:
<?php
$absolute_path = explode('wp-content', $_SERVER['SCRIPT_FILENAME']);
$wp_load = $absolute_path[0] . 'wp-load.php';
require_once($wp_load);
/**
Do stuff like connect to WP database and grab user set values
*/
header('Content-type: text/css');
header('Cache-control: must-revalidate');
?>
Hey Chris, I was playing with this idea the other day, but never had time to look deep into it. I have one question: what can you tell me about perfomance? I suppose it´s slower than a pure css stylesheet, but it´s much slower or you cant even notice the difference?
Thanks for your time and for this very interesting post.
Really interesting concept. I could see it being very useful in a corporate setting like where I work now. It would be easy to change colors/fonts if the corporate branding went in a new direction.
Looks really interesting, thanks Chris. I’ll experiment with it myself very soon I think!
@Martin
There’s no reason why it should be slower than pure css: The moment the css is delivered to the client from the server, it has become pure css already.
Don’t forget that any php code is executed on the server before anything happens in the browser.
If your code is really complex, you might notice some kind of downside on performances because it would take some time for the server to execute the script. However I don’t see this happening at all with this kind of method.
My 2¢
I’m sure there is some cost as the server has to process it and then deliver it, rather than just deliver it – but we’re talking microseconds here.
When I used this method, it wasn’t noticeably slower than pure CSS.
Thanks for your answers, both O and LineIn. What you´ve wrote seems very coherent, so I think its just a matter of give this a try!
There is actually a performance issue. As far as I know, these php-parsed stylesheets do not get cached by the client. So the stylesheet is processed everytime it is called by the client.
Correct me if I am wrong.
You could probably set an “expires” header in php but I’m not that into HTTP myself. Any ideas?
Actually you don’t need to work around the caching problem. Since you aren’t really doing anything dynamic inside the script you could just run the following from the command line on mac/linux:
php myStyles.php > myStyles.css
Then link the the css file we just generated. You’ll have to recompile the css file each time you change it, so it’s only really useful once you’re done testing.
There are some major performance issues. You should not use PHP or any application tier logic to generate static content at runtime. I go into all the performance issues here:
http://bit.ly/4suKSp
Another way to do this, albeit not very effective, is to embed the styles directly in document and have php echo the variables there. A more useful variant of this method is applying it to JavaScript. I once utilized this when I had to position an element with JS generated CSS, when the position was reliant upon the submitting of a php form.
The biggest reason I’d want to use CSS Variables is class inheritance. e.g. for sprites.
.sprite {
background-url…
text-indent…
}
.header extends .sprite
.header {
background-position…
}
.submit extends .sprite
.submit {
background-position…
}
Which saves us from having to put things like
input class=”sprite submit” and littering HTML with class names.
I’d love to see something like that using this method.
Nicole Sullivan goes into some depth about this here: http://www.stubbornella.org/content/2009/11/09/css-wish-list/
you should take a look at the github project page of oocss (http://github.com/stubbornella/oocss) .
there you can find a lot of object oriented css code, which can be used like this “input class=”sprite submit” ” .
everybody knows that this is not the best way to do it but it’s actually a concept that should find it’s way into the css specs.
of course the project is open to any kind of contributions (ideas, comments, code, …)
Well, there is an ‘Object Oriented CSS’ out there but am not sure if it allows inheritance.. (though I believe it should) Have to study it.. Darn, these technologies are developing at a very past pace… No sooner I learnt CSS 2.0 than new versions of CSS i.e. CSS 3.0 and Object Oriented CSS came out in the market :P
You could also use something like Scaffold to do this, which also adds a number of other benefits (caching, nested selectors, compression, etc.).
Scaffold would be what I’d use if I were to go down this route. I’ve tried it out but unfortunately it doesn’t work on my WAMP set-up.
Then use LAMP. Does anyone actually use WAMP for serious production hosting?
Chris,
Since you’re the WordPress pro, I thought I’d ask. Is there an easy way to work this into a WordPress theme?
A lot of times when I sell a theme I get requests to change colors, etc, by people who don’t know CSS. If all they had to do was change a few variables at the top then it would be easy to explain.
I’ve always been perplexed by why this enhancement is so desired because this functionality already exists. Don’t you have have the ability to have psuedo variables with the ability of specifying multiple classes?
Sweet
Sweetness
That means you’d have to define style in the HTML. I’m not going to explain why that’s bad, google knows ;)
This is exactly what I was going to post. I found it very liberating to quickly create divs say
div class=”w500px h200px float-l bgcolor1 textcolor3 font1″
I don’t see why this is any worse or heavier than giving an element an id and creating a style chunk for it when I was playing around with this I was able to do a lot more with less code since you can declare a bunch of design specific variables and then just apply them to whatever element you desire easily. It also sets up addClass and toggleClass well with jQuery. I would like to know the downsides to this method though. Obviously when working with dynamically generated content things could get stickier. I noticed facebook uses a lot of these descriptor classes in their markup.
The WordPress theme Mandigo uses this technique. The style sheet is style.css.php. Interesting theme, but this makes it difficult to modify the theme at the code level. The end user has quite a bit of control using the admin theme options.
ohhh. interesting. that would be a big draw if users could set color codes in an admin panel I think.
Thanks Chris. This would be very helpfull.i’ll experiment to try in my future projects.
If you are gonna put this extra overhead to the project, well i suppose csscaffold will do this job just fine.
I am down with this. Nice one for pointing it out.
I used a style.php together with a neato js colour picker plugin from http://www.eyecon.ro to create some cool WP admin interface options – you can easily give your users a js colour wheel!
Only problem I ran into was that you had to call the wp_config.php file at the top of style.php to get access to all the WP functions/database options.
The only other downer, of course, is that some code editors (Dreamweaver) don’t colour code it correctly which can make it a little confusing to begin with.
Nice article!
For those curious why style.php won’t work in WordPress:
actually WordPress has no problem with this. Using PHP in CSS in WordPress is no problem just like a normal file.
However, since most themes user a quicktaggy : “get_bloginfo(‘stylesheet_url’)”, then it must be style.css since that bloginfo-thing looks for style.css.
Either:
* redirecting style.css to style.php;
* or rewriting it;
* or making an empty style.css and @include style.php
* or call it style.css and via .htaccess make the server interpret it as php (<– recommended and, in the end, cleanest way)
—
TeMc
@TeMc,
I would agree #4 would be the cleanest, but you may run into people having issues if you’re selling the theme. Some shared hosts won’t allow .htaccess, for example. It may be few, but still could be an issue.
I haven’t tried yet, but I wonder if you could hook into get_bloginfo and change style.css to style.php.
Fifth option:
Edit the theme header and change:
To:
/style.php
I’d argue that this was cleaner than having users mess with .htaccess files unnecessarily.
Just my opinion, though.
Dammit! Filtered out my php:
Should be:
change:
get_bloginfo(‘stylesheet_url’)
to
get_bloginfo(‘stylesheet_directory’)/style.php
yeah or maybe even something like:
get_bloginfo('stylesheet_url').php
and use style.css.php. I will need to try these options out later. WordPress pulls the theme info from the style.css, so either you’d have to have a separate style.css with that info in there, or maybe using style.css.php would still work, and that’s why Mandigo does it.
Oooh, nice. Never thought of that – just tested it now and it works great.
Nice one, Tim!
You do still need a style.css file, of course, as a WordPress theme isn’t valid without one.
…which is exactly what you just said.
i put this ont top of ccs/php files :
ob_start (“ob_gzhandler”);
header(“Content-type: text/css; charset: UTF-8”);
header(“Cache-Control: must-revalidate”);
$offset = 60 * 60 ;
$ExpStr = “Expires: ” . gmdate(“D, d M Y H:i:s”, time() + $offset) . ” GMT”;
header($ExpStr);
I put this on top of css/php files :
ob_start ("ob_gzhandler");
header("Content-type: text/css; charset: UTF-8");
header("Cache-Control: must-revalidate");
$offset = 60 * 60 ;
$ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
header($ExpStr);
;
can be shortened to
Almost all php-installations support this way
Looks like there’s a typo under the “Use variables” section. In the first code block, the php opening tag says “<php". Just noticed that. Anyway, this is an article that will definitely be valuable to people. Thanks for posting it.
The guys from Bigspaceship created Rosemary that does everything listed.
there’s also other solutions like LESS (really cool features and syntax), Sass, and many more…
cheers.
for some reason LESS link didn’t worked on the previous comment. it’s http://lesscss.org/
I just wrote a post about using <a href="http://wordpresstheming.com/2009/12/dynamic-css-theme-options/"dynamic stylesheets with WordPress. It involves passing variables from a theme options page to a php file with a css content type header.
Check it out: http://wordpresstheming.com/2009/12/dynamic-css-theme-options/
Hi Devin, looks like that page is gone now. do you still have a tutorial on this? I would love to see it!
Thanks!
Hi, i don’t know enough php to really understand the benefits of doing this instead of just changing the css.
could someone please enlighten me because i like the concept but i am not good enough at php to comprehend the benefits right now.
i’d really appreciate it too.
Thanks
The benefit is that you can edit a single variable that is used in multiple places/files.
For instance if you want to use a spot color of say #FF0 (bright yellow in this example), but you don’t want to edit every instance in the CSS files, you can simply make a variable like so in a file named ‘css_config.php’:
$spotColor = ‘#FF0’;
Each of your CSS files can include the master configuration variables like so:
require_once(‘css_config.php’);
By specifying your CSS files as css_styles.php and “faking” their output as text/css content types, then to the browser it is as if you called a regular .css file with the power of PHP.
By the way, another tip to help shorten and make your PHP code easier to be unobtrusive, you can do:
Hope this helps…
Love it!
Thanks very much for the explanation, i get it now. that’s a great idea for a big website with loads of different pages and section.
nice one man, i’m grateful for your help.
This is very cool… BUT…
It’s a bad move if you sell themes. Buyers won’t be able to access the WordPress “editor” options, which is a MAJOR deal breaker.
Also, the syntax highlighting doesn’t work for the CSS, which makes managing large files extremely cumbersome.
If this is for your personal theme, then go for it! :-)
Might consider Compass @ http://wiki.github.com/chriseppstein/compass – based on SASS (http://sass-lang.com/)
argh, my post didnt work.
i wanted to post
?=$var;?
(between angle brackets)
The use of short-tags within PHP is not generally recommended – can conflict with the xml opening tag.
Also, some servers have short-tags switched off, so if you’re distributing code you may run into avoidable compatibility problems by using it in your themes and whatnot.
Si
The big drawback of the approach is caching.
Normally, CSS is a file which does not change often, so the trend is to cache it heavilly, avoiding requests from the client.
PHP files aren’t cached by default, so the request is made with every visit. You should set the cache headers from the code with the “header” function or tell your HTTP server how to do it.
Great Tut, anyway!
You guys think too hard. Create the style.css file that loads the template information, but don’t load it in your html WordPress theme header.
Just enqueue the style.php instead.
The performance is ratty though, because the server still parses the style.php file, even if it were blank.
I wish it was more like this
I haven’t had any luck with variables. CSS needs to keep up with OOP. It would definitely save a lot of time for all of us.
If you’ve got a relatively busy site, it would be handy to implement some kind of caching ability.
this is amazing, I never had a clue that you could do this.
+1 for Scaffold
I never missed variables in CSS.. and setting all that stuff up and typing all the -php- echo ‘blah’; -php- stuff doesnt seem to be effective enough to even try it
I mean color:#535353 is so much shorter than -php- echo $textcolor -php- what the hell does this make writing CSS any better/shorter/easier?
The main points to use this method are two-fold:
1.) Editing a single variable across multiple framework/included files on a large site.
2.) Being able to abstract the markup from the values, by putting variables in a editable administration area, which then simply updates the variables, and doesn’t allow the markup itself to be touched by non-admins.
Just a few real world examples of this in action.
Hi Norman – I’m very new to CSS, but feel like variables will be helpful for me. I have an early stage website/webapp which will have a fair amount of internal linking. Thanks to this post, I’m using this method to create variables for all my links. As my file structure evolves and/or changes, I’ll only have to update each link variable once rather than finding every instance of that link on all the pages.
Although there could be a downside that I’m not aware of.
Thanks for this post. Like my previous speaker I don’t missed variables in CSS. Isn’t it enough that you can find php, html, css and javascript in the index? Should there php in the css? When is the time to put php in the javascript to write css in html?
I use PHP in my javascript and CSS so that I can allow users to easily change variables from friendly interfaces.
Users could change colours, for example, using a friendly colour wheel in the admin interface and never have to worry about editing raw CSS (and potentially break the site).
It’s all about the user experience!
You guys should have a look at xCSS, it is not really well known but this is really powerful, it event minify the CSS if you tell it to in the config
agreed
Could you use <a href="http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc"heredoc syntax? That way you don’t have to jump into PHP to echo variables, you could just say background-color:$brandcolor;.
I mean heredoc syntax :P
Good idea… You could wrap the entire bottom of the file (the CSS stuff) in HEREDOC and do it that way.
That’s how I’ve done it in the past. Works pretty well. And if you’re using textmate, put it into CSS mode and it will still highlight the syntax properly.
Please do be aware of the performance issues and, if you use this solution either use the “Expires” header to allow caching client-side (good) or pre-parse the file server-side before making it available as a normal static CSS file (better).
You don’t want the client to re-download and re-parse all the CSS on *every* page…
This is extremely useful, and unless you’re doing some extreme php stuff inside the css (which you shouldn’t be) then performance shouldn’t be a problem.
Just make sure to GZIP, and compress or code in single lines.
This is certainly very cool and can be a real powerful tool, but I wouldn’t use any PHP scripts on a production site. It’s just another bottleneck. You should instead use PHP to generate a static file and link that as your stylesheet.
This is a start, but using it without caching could end bad for your server.
Use something like Scaffold if you’re going down this route, but I may be a little bias :)
@Logan It’s not bad at all if you’re caching the file after it’s processed.
Awesome Concept!
Any idea if CSS will every support variables?
“Bake rather than fry”
Unless there’s a really, really good reason for generating the CSS dynamically then it should be generated at build rather than runtime.
Serving a static responses much faster than serving dynamic ones and imposes less load on the servers, static responses are also much easier to move to CDNs
Others have mentioned setting the cache headers and gzipping but don’t forget to minify too.
Andy
hello i am big fan of you but why typing its easy if you type #555
ul#main-nav li a {
color: ;
}
ul#main-nav li a {
color: #555;
}
I wonder why are there so few people using instead of . It’s makes code a lot more readable and I know that if I ever run into problems using it, I can just make a global search and replace.
Awesome tip, thanks Chris.
To use WordPress functions in the file, while using the first method, add this to the customstyle.php, your php stylesheet
Thanks!
@Arun Basil, that will not entirely work. What if wp was on a different directory? Document root would be htdocs or public_html and not the actual wp directory. I would use the example used in this tutorial for portability.
Just saved my ass. Thanks!
For the record, I got this working in WordPress 3.8.1 without the Apache mod or the wp_load modification.
Thanks so much for putting this out here!
I’m just starting to play with this now.
@Scott Russell, are you using wp_register/wp_enqueue_style to load the style.php file?