Stylesheet Switcher (PHP / CSS)
Right, what we have here is a very handy way of allowing a user to switch between multiple stylesheets on your site.
This should be a bit superfluous to users of recent Gecko browsers, but as most of the world is using Internet Explorer at this point in time, it's very handy for these users to be able to change font sizes etc. without having to dig deep into IE’s settings.
Also, it’s all done server-side, so you don’t have to worry about your user having JavaScript turned on etc.
Before I go any further, some credit where credit is due, this tutorial is an extension of a great article by Chris Clark on A List Apart.
This article fixes a couple of issues that might prevent Chris’s solution working in newer PHP releases due to higher security, and extends it to a dynamic list.
Right: let’s get it on...
First Up: Build Your Stylesheets
Here on this very site the code in this tutorial was once used to control font sizes.
As a result I built these stylesheets —
default.css,
small.css,
large.css and
x-large.css.
Default.css is where all the magic happens, this file contains all the classes for the site, and at the very top contains roughly the following lines:
body {
font-family: Arial, Verdana, Helvetica, Sans-Serif;
font-size: x-small;
voice-family: "\"}\"";
voice-family: inherit;
font-size: small;
}
/* be nice to 4.x browsers */
p, a, li, ul, span, div, td, address, label,
input, select, textarea, dl, dt, dd {
font-family: Arial, Verdana, Helvetica, Sans-Serif;
font-size: x-small;
voice-family: "\"}\"";
voice-family: inherit;
font-size: small;
}
Let’s examine these lines.
Both blocks define the font family that will be used for the website, and both define the font size twice.
Why is this necessary?
The font family first: older browsers like Netscape 4.x and it’s peers had terrible memories.
They remembered that all the text in <body> was Georgia or some such font, but by the time they got to <body><table><tr><td>my text they’d completely forgotten about what font they were using.
As a result we define all the main tags in the document and remind old browsers what they’re doing.
Now, what about those 4 font size definitions?
Well you see, these old browsers weren’t the brightest sparks in other areas either.
When the makers decided to add the font sizes xx-small, x-small, small, medium, large, x-large and xx-large, they made them all too big.
It’s beyond the scope of this article to explain why they did it, all we need to know is that we need to make old browsers use x-small and new browsers use small.
Luckily, we can use old browsers bugginess to our advantage.
You see, when a CSS parser comes across something it doesn’t understand in a class, it’ll just give up on the rest of the class completely.
So when old browsers see:
font-size: x-small;
voice-family: "\"}\"";
voice-family: inherit;
font-size: small;
..all they ever understand is font-size: x-small, as the next line confuses the hell out of them.
New browsers understand it, so continue right to the end and pick up the correct size.
Sweet.
After that little aside on the wonders of 4.x browsers, back to the matter in hand.
Default.css is our main stylesheet, and so has the first word in what our site looks like.
However, there is nothing wrong with having two main stylesheets, so that's what we're going to do.
In the <head> of your document (view source on this page if you’re not sure where) add the following lines:
<link type="text/css" rel="stylesheet" href="/c/default.css" />
<link type="text/css" rel="stylesheet" href="/c/large.css"/>
This will mean your site first looks at all the styles in default.css.
It will then look at all those in large.css.
If any conflict with each other, the ones in large.css will be used.
As the font sizes defined in large.css are bigger, it’ll use these.
So far so good, but how can the user change large.css to something else?
Enter PHP...
Next: Changing styles with PHP & Cookies
In case you’re wondering, PHP is a free, open-source server-side scripting language.
It is run on thousands of servers, and as it’s free, won’t cost you an arm and a leg to find a host that supports it.
You can use it for little tweaks like changing stylesheets, right up to professional e-commerce solutions to control orders, stock etc.
Right, we'll create a file called stylechange.php (use any text editor you like) and bung the following code in it:
<?php
$action = $_GET["action"];
/* The list of towns on the road */
$sheets = array('small','medium','large','x-large');
/* Stand in the place where you live, now face north... */
$stylesheet = $HTTP_COOKIE_VARS["stylesheet"];
if (!$stylesheet) {$stylesheet = 'medium';}
if ($action == 'up' || $action == 'down') {
/*
Think about direction, wonder why you have it now...
If you want to go south but you're facing north, don't turn around.
It's much easier to turn the world around.
*/
if ($action == 'down') {$sheets = array_reverse($sheets);}
/*
Walk to the next town,
unless you're already at the end of the world.
*/
for ($i=0;$i<count($sheets);$i++) {
if ($sheets[$i] == $stylesheet && ($i+1) != count($sheets)) {
$stylesheet = $sheets[$i+1];
break;
}
}
/* Make a note of where you've got to */
setcookie('stylesheet', $stylesheet, time()+31449600);
}
Header('Location: '.$_SERVER["HTTP_REFERER"]);
?>
That’s quite a chunk of code, especially for someone who’s not too hot on PHP.
If you want to know why it does what it does, read on.
Otherwise, skip down to the next section about plugging it in...
Still here?
OK then, let’s take it from the top.
First of all we pull the action we want from the URI, which will be either stylechange.php?action=up or stylechange.php?action=down.
If some Smart Alek decides to try something like stylechange.php?action=delete_your_entire_website it won’t matter.
For those of you who know PHP, you might be wondering why I used $_GET.
This is because newer releases of PHP insist that you say where you want to get your variable from.
This stops people going to your website and doing things like getting round your lovely login script by using www.mysite.php?loggedin=true to make your site think that the variable it should find from a cookie called $loggedin is there when it’s not.
Nasty eh?
Simple solution: use $_GET["myvariable"] for querystring, $HTTP_COOKIE_VARS["myvariable"] for cookies.
There are others for file uploads, post data etc, but they’re not needed here.
Next up we define an array of all the possible stylesheets on the site. We’ve defined their names without the .css extensions as we’ll put them on later.
Straight after that we find out what stylesheet the user is already using. They might not have chosen yet in which case we assume they’re using the medium one.
Then we get down to business. We choose which way we’re going — up or down — and go through the array to find out what the next one is.
If we’re already at the end of the list, we just stay put.
Then we write the users choice to a cookie, and run on back to the page the user came from.
The user never knows they’ve been to this page, as to them the website just refreshes with bigger text.
Finally: Chomping Down on Those Cookies
Right, your user can now theoretically change the text size.
Trouble is, they can’t find where to do it.
So let’s add a little control to their experience.
First up , we’ll bung two links into our document using the following code:
Font Size:
<a href="/stylechange.php?action=up">Increase</a> |
<a href="/stylechange.php?action=down">Decrease</a>
It’s basic, but it does the job.
With that in place, the user can now set a cookie on her system that will store the font size she wants.
However, the site still doesn’t know what she wants because it’s not checking the cookie.
Remember we typed some lines back that went a little something like this:
<link type="text/css" rel="stylesheet" href="/c/default.css" />
<link type="text/css" rel="stylesheet" href="/c/large.css"/>
Well, let’s change them to this:
<link type="text/css" rel="stylesheet" href="/c/default.css" />
<?php
$stylesheet = $HTTP_COOKIE_VARS["stylesheet"];
if (isset($stylesheet) && $stylesheet != 'medium') {
echo '<link type="text/css" rel="stylesheet" href="/c/'.$stylesheet.'.css"/>';
}
?>
And there you have it, a fully working stylesheet switcher, one that is compatible with just about any browser as long as it can receive cookies.
If you click here you can download a fully working example to play with at your leisure.
Just place the enclosed files on a PHP enabled environment and you’re away.
Feel free to use this code any way you like, however, a link to my site (this page or any other) would be very much appreciated in return. Thanks.