Garrett Dimon’s review of For the People by the People, a book about architecture (buildings not pages) has prompted me to add it to my Amazon Wishlist. Sadly I missed the Campfire chat he had set up to discuss it, leaving me with just a small taste, and ultimately causing me to want to read it even more. It isn’t very often that you hear about online reading groups spontaneously occurring…
I’ll leave you with the quote that Garrett highlighted as that is what truly piqued my interest:
So it is inevitable that as the work of building passes into the hands of specialists, the patterns which they use become more and more banal, more willful, and less anchored in reality.
Christopher Alexander
Posted in Architecture & Furniture & Tagged: architecture, books
Cascading Style Sheets are an amazing tool, having transformed Web Design as an industry and the Web as a communications medium. But in all of its glory (and it is glorious), CSS has some flaws. The most frustrating for me is its static nature. I want to be able to reuse values (CSS variables if you will), I want to make use of browser detection instead of CSS hacks, or IE’s proprietary conditional comments and I want to use logic to serve up specific rules in certain situations. Enter PHP (or your server-side langugage of choice), which will provide us a wealth of new options for working with our CSS, including the ability to adapt to our end-users’ needs.
Yeah, client-side scripting can handle most of these requirements, but I don’t want to rely on a technology for my presentation that can be disabled by the user or their corporate IT department and frankly the JS support of mobile devices is poor at best. Enter server-side languages, which cover all of these bases without impacting the program or device rendering the site.
This article assumes that you have a Web server at your disposal that is running one of the aforementioned scripting languages and that you have a basic understanding of scripting in that language and know a bit about CSS. For the purpose of this write up I’ll be using PHP, but I have implemented versions of this system on production sites running JSP, and there’s no reason the same couldn’t be done with Ruby on Rails, Python, ASP or any other server-side solution.
This system can be as detailed or relaxed as you’d like, so I’m going to keep this write-up relatively simple with a few interesting bits thrown in. If it proves to be an interesting subject I’ll write a follow-up showing advanced usage. Let’s hit it!
In your editor of choice create a new PHP file. I’m calling mine styles.php. Paste this line at the very top of the document:
<?php header('Content-type: text/css'); ?>
This tells the server that the page should be sent to the browser as a CSS document, so the file won’t need the .css extension. All of our work will be done in this bad boy. So, on to the next step.
So, we have a PHP file that has a serious personality disorder, thinking that it’s a style sheet. What the hell are we going to do with it? Well, we’re going to set a few key variables that will make life much easier. Specifically, we’ll set variables for common measurements (columns, containers and the space between) and some colors from the site’s palette:
$gutter = '10px'; /* Used to separate visual blocks */
$pageWidth = '1000px'; /* Width of the Web page */
$pageWidthPadded = '980px'; /* $pageWidth minus padding ($gutter x 2) */
$col1 = '800px'; /* Width of the main content area */
$col1Padded = '780px'; /* $col1 minus padding ($gutter x 2) */
$col2 = '180px'; /* Width of the sidebar area */
$col2Padded = '160px'; /* $col2 minus padding ($gutter x 2) */
$lightGray = '#e5e5e5';
$charcoal = '#464646';
$orange = '#f60';
$darkBlue = '#0059b2';
The width variables will prove useful in creating a site as they guarantee consistent presentation from page to page and template to template. This model can easily be extended for multiple column widths, so if you want to subdivide Column 1, you only have to set it up once, creating the variables ($col1A, $col1B etc.) and setting their values to the appropriate widths. For you folks who love them grids, this should make life pretty easy.
Setting up color variables simplifies the initial site build-out and future revisions. When you return to the style sheet six months from now, you’ll notice $darkBlue is much easier to remember than #0059b2.
So, now that we have width and colors, it’s simple to use these new variables in the style sheet, all you need to do is use PHP’s echo shortcut (<?= 'print this' ?>):
#Wrapper {
background-color: <?= $lightGray ?>;
border 1px dotted <?= $darkBlue ?>;
margin: <?= $gutter ?>;
width: <?= $pageWidth ?>;
}
Advanced: I’ve begun to separate the measurement value (px, em, pt) from the actual numerical value so I can harness the power of PHP to do my math for me. That’ll be the subject of a future write-up.
I’ve used a couple of different packages in the past; at the moment I use BrowsCap, which covers these needs nicely, but use whatever fits your needs best. Place this code at the top of styles.php, after the PHP header line:
require_once('Browscap/Browscap.php');
// Create a new Browscap object (loads or creates the cache)
$bc = new Browscap('Browscap/cache/');
// Get information about the current browser's user agent
$current_browser = $bc->getBrowser(null,true);
$browser_platform = $current_browser['Platform'];
$browser_name = $current_browser['Browser'];
$browser_ver_major = $current_browser['MajorVer'];
$browser_ver_minor = $current_browser['MinorVer'];
$browser_ver_full = $current_browser['Version'];
$is_ie6 = false;
$is_ie7 = false;
$is_safari = false;
$is_ff = false;
if ($browser_name == 'IE' && $browser_ver_major == 6) {
$is_ie6 = true;
} elseif ($browser_name == 'IE' && $browser_ver_major == 7) {
$is_ie7 = true;
} elseif ($browser_name == 'Firefox') {
$is_ff = true;
} elseif ($browser_name == 'Safari') {
$is_safari = true;
}
So we now have a few variables that will allow us to quickly determine whether the user’s browser is IE 6, IE 7, Firefox (any version) or Safari (any version). You can extend this model to fit your specific audience and needs.
Sweet, now we can rock the styles all dynamic-like! Here are a couple of examples for you to nibble on:
body {
<? if($browser_platform == 'MacOSX') { ?>
font: .85em/1.4 normal "Lucida Grande", Verdana, sans-serif;
<? } else { ?>
font: .75em/1.4 normal "Lucida Grande", Verdana, sans-serif;
<? } ?>
That block outputs a larger font size for folks who are on a Mac compared to folks on PCs or other devices.
The next one modifies the value of a top margin, serving up 5px for IE 6, and zero for all other browsers.
#NavWrapper1 {
display: block;
height: 18px;
<? if ($is_ie6) { ?>
margin-top: 0;
<? } else { ?>
margin-top: 5px;
<? } ?>
margin: <?= $gutter ?>;
width: <?= $pageWidthPadded ?>;
}
Advanced: This method can be used to detect alternate browsers as well. So, you could detect a mobile browser and serve up a separate style sheet. Or if you detect a screen reader you could serve up a style sheet with proper aural rules defined.
That’s it, we’re rolling with dynamic CSS, harnessing the power of both PHP and Cascading Style Sheets. There is a lot more that can be done, but I hope this opened a few avenues for experimentation on your future projects.
It would be really easy to overuse this method. Do not try to replace proper use of grouping and the cascade with PHP. You won’t gain anything but frustration and larger style sheets. Take the time to think through the variables that you are going to create to make sure they make sense and are not simply recreating existing CSS functionality.
I am by no means the only person to think of this, there are many others who have covered the topic on their sites, but I felt that there were a few components missing, so here we are. I hope I added to your toolbox. It is also very important to note that there are some great folks with whom I’ve worked who have expanded on the concept and helped me flesh it out to be a viable and reusable tool in the Real World ™, most notably the inestimable Leesa of Red Velvet Cafe.
I look forward to your feedback and questions, so please leave a comment.
Posted in CSS, PHP & MySQL & Tagged: CSS, php, web design, Web Development
Thanks to Rick and Emre for the excellent suggestions which prompted these improvements to the Ma.gnolia WordPress plugin:
Please note, this is all or nothing, so you cannot just pull the image, or the image and description without the tags. Sorry, but that’s how it’s coming through and I spent too much time trying to find a way around it with a couple of different RSS parsers.
Please check out the official page to download the latest version and the new examples page to learn more about the plugin.
Note: for Users of 1.3: You should be able to drop this upgrade in place without changing any of your code. Please let me know if you notice any issues with your existing setup.
Posted in Magnolia Plugin & Tagged: Magnolia, php, WordPress
I’ve been running into problems ever since I upgraded WordPress to 2.x (not sure if it was 2.0 or 2.1) with new posts. The first time a new post was was loaded into the browser, the server kicked out this error:
PHP Warning: mysql_affected_rows() [<a href='function.mysql-affected-rows'>function.mysql-affected-rows</a>]: A link to the server could not be established in /Users/alex/Dev/SilverSpider/site/wp-includes/wp-db.php on line 183
I searched to find an answer when I first ran into the problem, but never found a solution. Then, while I was working on the Ma.gnolia plugin, it cropped up again, so I began comparing my install to the stock set up and and found that my old wp-config.php contained some lines that are not included in the 2.x wp-config-sample.php:
$server = DB_HOST;
$loginsql = DB_USER;
$passsql = DB_PASSWORD;
$base = DB_NAME;
As I upgraded from 1.x, and the instructions say not to mess with the config file, I hadn’t looked into it as a possible source of the problem, but by removing this block of code, all appears to be running properly, at least in my local development environment. This post will either reinforce my theory or blow it to bits…
Show time!
Well, this post worked perfectly and did not generate an error. If you upgraded from 1.x to 2.x and are running into this problem, backup your wp-config.php and then remove that block of code and try it for yourself. Please let me know if that doesn’t work for you. I’ve filed a ticket so this will be resolved all official-like (3992).
Damn it! The error just re-appeared after I edited this post. Grrr.
Posted in WordPress & Tagged: errors, mysql, Web Development, WordPress
Barry Price, the creator of the Ma.gnolia plugin for WordPress has set its development aside and has encouraged me to adopt the project. As I use the plugin heavily on this site, and I enjoy development, I decided to take him up on it.
This plugin makes it easy to output a list of your Ma.gnolia bookmarks anywhere on your site. You can set it to only pull bookmarks with a specific tag, which is great for listing sites related to a specific category or post.
Please download the plugin and provide me your feedback in the comments of this page. I’ll do my damnedest to fix any bugs you report and look forward to expanding it to be even more useful!
I’ve updated the plugin. Please go to the official page for the latest version: Ma.gnolia Plugin.

Magnolia WordPress Plugin
Make sure to join the Plugin group on Ma.gnolia to add your site to the list if you are using this plugin!
This plugin is very basic at the moment, so all it takes once you’ve installed the plugin is a single line of PHP, inserted wherever you want the list of links to appear. You can pass the following variables to the plugin:
The output consists of an unordered list, each link contained in a separate list item tag.
Here’s a snippet to output three bookmarks, with their associated descriptions from my bookmark list, regardless of the tag.
<?php magnolia('BaldTechnologist',3,1,0); ?>
<ul>
<li><a href="http://www.flickr.com/photos/17328648@N00/sets/1737284/" title="Cool & Wacky Records - a photoset on Flickr:: No Description" class="ToolTip">Cool & Wacky Records - a photoset on Flickr</a></li>
<li><a href="http://www.fortymedia.com/blog/post/59" title="Attention Mapping: The 10-Point Exercise:: Attention is the most fundamental unit of design. Once you get past the color schemes, typography, layouts, graphical treatments, etc., it all comes down to guiding and shaping the viewer’s attention." class="ToolTip">Attention Mapping: The 10-Point Exercise</a></li>
<li><a href="http://haha.nu/misc/html-tags-illustrated/" title="HTML Tags illustrated:: A collection of photos that demonstrate HTML tags." class="ToolTip">HTML Tags illustrated</a></li>
<li class="MagnoliaLink"><a href="http://ma.gnolia.com/people/BaldTechnologist/bookmarks" title="Alex Jones on Ma.gnolia::Browse through the sites and pages that I have added to my bookmark list on Ma.gnolia. If you're a member, add me as a contact!" class="ToolTip">View my bookmarks on Ma.gnolia</a></li>
</ul>
<?php magnolia('BaldTechnologist',5,0,0,0,'design'); ?>
<?php magnolia('BaldTechnologist',10,1,0,0,'History'); ?>
Barry Price built the first version of this plugin, and what you see here is a a modified version of his work the Last RSS Parser, which does much of the heavy lifting. At this point, Alex (BaldTechnologist on Ma.gnolia) has picked up the project and will be adding features as suggestions come in and time allows. If you have an idea, please contact me and I’ll see what I can do!
It’s easy to support this free plugin, and it won’t cost you a thing! Here are a few simple ways:
I’ve made some changes, both major and minor to the plugin, including:
These are not currently prioritized, but I want to add these features/implement these revisions:
Posted in Magnolia Plugin & Tagged: Magnolia, php, Web Development, WordPress
As South by Southwest Interactive is right around the corner, I want to let people know that I’m attending and would love to meet and hang out with any and all of you who are going too. It’s a great event with a ton of interesting panels and keynotes, but the most important part (for me at least) is the people you meet and talk to throughout the days and nights. Last year I met some really cool people and I look forward to doing so again.
If you’re coming and you’d like to hang out at the conference or any of the after-parties, lemme know by replying to this entry, or tapping my shoulder during the events. There is no reason to wander SXSWi alone! Start conversations with strangers, and if that isn’t your style, look for me and say hi (you’re reading this post, so we’ve now me, right? right). There’s a picture of me at the bottom of this entry so you’ll recognize me.
I’m local to Austin and am gathering some other local Web folk as well, so I hope to have a nice size group together. For those who aren’t technical, don’t worry, some of the best conversations tend to focus on broader topics, and I know many of us welcome a chance to learn about areas beyond dev and design. Cross-pollination is good.

Wow, that’s a large photo… Anyway, I may or may not be wearing the glasses, but my head should remain shiny.
So come say hi. It doesn’t matter if I’m talking to other people, join in!
Events I plan to attend, but subject to last minute distractions and possible double-booking (tell me if I’m missing something good!).
More places to find me at SXSWi ยป
I’ll try to publish the schedule of panels I plan to attend when I have a chance.
Posted in South by Southwest & Tagged: austin, social, South by Southwest
You are currently browsing the Alex Jones weblog archives for March, 2007.
© Copyright 1996 - 2008, Alex Jones
SilverSpider.com is powered by WordPress, these great plugins and SilverSpider Play List
RSS: Entries and Comments
I Want Sandy:
Safari's Font Rendering on Windows:
Non-linear Scheduling:
Capitalization of Internet and Web: