Category Archives: Web Design

Collapsing Navigation in jQuery


Accordion menus, collapsing navigation, f’eh. Everyone’s got their own version, including the one native to jQuery UI. I’ve never really been satisfied with any of them, however, so I took a stab at rolling my own. I built it in two versions, one that only allows you to have one navigation section open one at a time, and one that allows multiple sections.

If you have poor impulse control and just want to skip to the code demos, you can check out the implementations here:

Stylized “One-At-A-Time” Collapsing Navigation
Stylized “Many-At-A-Time” Collapsing Navigation

Making the magic sauce.

Here’s the basic code that makes it happen. I’ll only outline the “one-at-a-time” implementation here, but the “many-at-a-time” version is remarkably similar. All these code examples are available on the demo pages as well.

First, use this HTML code, or something similar to it. Basically, what you need is a series of double-nested unordered lists with the proper ID.

<ul id="collapsing-nav">
	<li><span>Main Nav One</span>
			<li><a href="#">Sub Nav One</a></li>
			<li><a href="#">Sub Nav Two</a></li>
			<li><a href="#">Sub Nav Three</a></li>
	<li><span>Main Nav Two</span>
			<li><a href="#">Sub Nav One</a></li>
			<li><a href="#">Sub Nav Two</a></li>
			<li><a href="#">Sub Nav Three</a></li>
	<li><span>Main Nav Three</span>
			<li><a href="#">Sub Nav One</a></li>
			<li><a href="#">Sub Nav Two</a></li>
			<li><a href="#">Sub Nav Three</a></li>

Next, these are the raw CSS styles that you’ll need to create the effect. Once you understand what’s going on, feel free to customize these rules however you see fit.

<style type="text/css">
	ul#collapsing-nav li a {
		color: #00f;
		text-decoration: underline;

	ul#collapsing-nav li a:hover {
		color: #f00;

	body.enhanced ul#collapsing-nav span {
		color: #00f;
		text-decoration: underline;

	body.enhanced ul#collapsing-nav span:hover {
		color: #f00;
		cursor: pointer;

	body.enhanced ul#collapsing-nav li.selected span,
	body.enhanced ul#collapsing-nav li.selected span:hover {
		color: #000;
		cursor: default;
		text-decoration: none;

Finally, insert this JavaScript in the <head> of your HTML page. Also, grab a copy of jQuery and make sure this code points to that file as well.

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
function collapsing_nav() {
	$("#collapsing-nav > li:first").addClass("selected");
	$("#collapsing-nav > li").not(":first").find("ul").hide();
	$("#collapsing-nav > li span").click(function() {
		if ($(this).parent().find("ul").is(":hidden")) {
			$("#collapsing-nav ul:visible").slideUp("fast");
			$("#collapsing-nav > li").removeClass("selected");

The above code adds an “enhanced” class to the <body> element, marks the first navigation section in the unordered list with a “selected” class, and hides all the remaining sections. When the user clicks on a section heading it hides any open navigation sections, reveals the section that corresponds to the clicked heading, and marks that section as selected.

If you want to see this basic code in action, visit the basic demo page or download these code examples for your own nefarious purposes.

There are a few things that make this collapsing navigation better than a lot of the other crud out there. While I certainly wouldn’t purport that this is the best of the best, I’ve found it to be perfectly suitable for many of my purposes.

It’s easy to implement and customize.

Just add the proper ID to a double-nested unordered list with the proper HTML markup, and you’re good to go. You’ll have to do some work with the CSS to get it to look good and behave just the way you want, but in the basic code example I’ve sketched out the behavioral CSS scaffolding that you’ll need to get off the ground. In the designed example I’ve compartmentalized the CSS rules across a few files, to clearly delineate what code applies to the navigation, and what is purely ornamentation.

It’s compatible.

I’ve tested these examples and they work perfectly in Safari 3.2.1, Firefox 3.0.6, Opera 9.63 and Internet Explorer 7.0. They work in IE 6.0 as well, with one small caveat: IE6 doesn’t support the :hover pseudo-class on any element other than <a> elements, and since the section headings use spans instead of hyperlinks, the hover state doesn’t work. This is a bummer, but if you tweaked the JavaScript to add an “ie-hover” class to the <span> element on hover, and if you defined that class in the CSS, you could totally work around this. For me it isn’t worth the effort, as I believe that IE6 users should be forced to browse the web in constant agony. For you, this activity could be a learning experience.

It’s lightweight.

Simply bring in 46KB of jQuery hotness, and the JavaScript and CSS to make this puppy work weighs less than 5KB.

It degrades gracefully with JavaScript turned off.

All nested lists are displayed wide open by default, so all navigation items are available to the user. Additionally, when JavaScript is disabled the section headings are not hyperlinked and are not clickable, as one would reasonably expect, considering that the only reason they should be clickable is to toggle the list. Without JavaScript to collapse and uncollapse the navigation, the hyperlink would serve no purpose other than to confuse the user. Indeed, if something isn’t clickable in a particular use case, it shouldn’t have an affordance that suggests otherwise. This lack of attention to detail in so many slipshod JavaScript snippets annoys me to no end.

I achieve this effect by using <span> elements (rather than <a> elements) to wrap the first-level list items. These spans could certainly be replaced by something like a header element that would more semantically descriptive, but such is a task I leave up to the reader. Then, with JavaScript I add an “enhanced” class to the <body> element, which calls in the basic CSS styles that control the presentation of the first-level list items and make them behave as clickable headings. This abstraction of presentation and behavior ensures that the collapsing navigation works as expected in most cases, and that those browsing without JavaScript will enjoy an experience unsullied by irrelevant controls.

It behaves the way you think it should.

Which is more than you can say about a lot of collapsing menus out there.

The section headers aren’t clickable when they shouldn’t be clickable, such as when they’re already expanded in the “one-at-a-time” example, or in cases where JavaScript is disabled.

As with all of the things I design these days, I didn’t start with code when I set out to build this navigation. I started with sketching, which helped me better grasp the behavioral requirements of such a navigation scheme.


Sketching helped me realize one core problem that needed to be solved, that the first item in the list needed to be expanded by default. Indeed, there’s no reason that all navigation items should start out closed, as that’s lazy and inane. Second, this offers an affordance to the user, suggesting the behavior that can be expected from the other navigation items.

So that’s that. Visit the demo page to see the hotness stylized, or check out the basic code that makes the magic happen.

Quantum Entanglement – Part II

This is Part II. Read Part I.

As I mentioned earlier, Siskiwit and Rosco were unintentional BFF. When I launched Rosco I wanted to preserve the link structure of Siskiwit, because people were still way into searchin’ for and diggin’ on that stuff.

Siskiwit had a long and colorful history of publishing platforms, but a number of years ago it settled on Movable Type, where it has remained ever since. Recently I tried upgrading its circa-2005 installation to the latest and freshest version, Movable Type 4.1, and I nearly fell out of my chair because it executed so flawlessly. Seriously, nothing went wrong. This made me realize that Siskiwit was far more portable than I gave it credit for, and I began strategizing on how to move it away from and onto its own subdomain.

Transmit Textmate BBEdit

Up until recently, I have done all of my development on my server at DreamHost, hosting them at super-secret subdomains. The majority of my development cycle would involve launching Transmit, opening a file on the server in TextMate (or BBEdit if I need to do some heavy-duty regex), editing that file, saving it, and refreshing my browser window. I don’t know how many web designers work this way, but I’m willing to bet a fair amount of them.

If I’m installing a package of software (say, Movable Type or WordPress) I’ll often FTP into my server to upload the tarball or .zip file, SSH into my server to expand the file, and then return to Transmit to move the expanded folders and files to their proper locations. Ditto for large image directories, or other cases where I have multiple files to upload at once. All the goddamn handshaking that goes on with an FTP transfer makes it a horrible tool for uploading multiple files, and if your connection drops halfway through a transfer, it’s difficult to figure out what got copied successfully and what didn’t. I don’t know how many times I’ve been hosed by a file that appears to have transferred successfully, but turns out later to have been only a 0 KB placeholder.

This, this development process is dumb. I never realized how dumb until I started working with Jason, and we did all of our development in Subversion.

Subversion: Time Machine for Your Project

If you’ve never used a version control system you may have no idea what all the fuss is about. Once you’ve used one, though… no, once you’ve lived in one for a few weeks, you’ll wonder why everything in the world isn’t done this way. Seriously, everywhere I look now I see opportunities for version control. I wish I could rollback the street in front of my house, so I could drive on it at a moderate speed without bottoming out on this year’s crop of potholes. I wish I could form a branch for this day, which has been kind of cloudy and crummy but altogether windy, and see what would have happened if I chose to go kiteboarding instead of writing all afternoon. The planet? Sheesh, talk about something that needs to be loaded into Subversion, like, yesterday.

Subversion is a popular open-source version control system, which stores and tracks every change made to every folder and file that you load into it. Well, not every change, as it only tracks changes that you “commit” to it. Anywho, it’s like Time Machine for code. Your entire Time Machine drive would be called a “repository” in Subversion parlance, and every snapshot of your computer (or project) at a particular moment in time would be considered a “revision”.

Phew! Being a noob myself I’m in no place to teach you everything you need to know about version control with Subversion, but fortunately there’s an excellent book on that very subject. If nothing else you should read chapter one, which covers the fundamental concepts of version control, and shows some examples of Subversion in action.

If you’re used to developing on a web server, applying version control to your development requires a fundamental shift in practice. Fortunately, this shift is one that turns out to be rewarding in many ways, including speed of development, robustness of your code, and ease of deployability. Your Subversion repository lives in the cloud, so to speak, and you download, or “checkout”, the most recent revision to a folder on your local machine to do your work.

OS X Leopard has just about everything you could ever want in a web server already installed on it, including Subversion, Apache 2, mod_rewrite, PHP 5, Ruby, Ruby on Rails, and MySQL, so creating a local web development environment is a pretty straightforward deal. That said, a lot of these fixin’s aren’t enabled out of the box, and they will take a bit of mucking around to get running. You need to turn on mod_rewrite and PHP, you might want to upgrade Rails and other preinstalled Gems, and installing the MySQL preference pane might make your life easier. At a later date I’ll try to outline my experience of getting my own OS X development environment running. For now, just trust me.

A step-by-step manual for setting up your local machine for version-controlled development is outside the scope of this article, but at the very least I want to give you a cursory glance of what my current setup looks like. This all came into being within the last few weeks, but already it hands-down beats the knickers off Ghetto-Ass Subdomain Remote Web Server FTP Development.

Non-Ghetto-Ass Local Development

First off, if you need a Subversion repository look no further than Beanstalk, who definitely put the sexy in version control. Honestly, if my first time had been with anyone but Beanstalk, I would have sworn off the whole thing entirely, given the craptastic nature of most Subversion applications. Most host and client setups assume prior knowledge of Subversion, incredible technical aptitude, and hella-tolerance for lousiness. Beanstalk makes it really easy to import your initial project into Subversion, and offers a free account with up to 20 MB of space, which will be fine out of the gate unless you’re planning on working with tons of images. Or, perhaps, if you’re planning on using the SQL on Rails framework.

The cool thing with Subversion is that every time you commit a revision to your project, it doesn’t need to make new copies of all the files. It hardly even makes a copy of the updated files. Nay, it just tracks and records the changes within the files. Thus, a 2 MB project with 10 revisions will not weigh 20 MB. For instance, I have a current project where my working copy weighs 11.5 MB, but the repository (with 69 revisions already) only weighs 3.4 MB. Wow, that’s a surprise. I have no idea how that works, in that my working copy weighs more than the entire repository. Perhaps there’s some voodoo magic going on, but I’m not gonna argue!

svnXOnce you have a repository, you’ll probably want to install a Subversion client on your local machine to make it easier to interact with the repository. Subversion is built with the command-line in mind, but a lot of us don’t think that way. I’ve been using the svnX client for a number of months now, and while it’s incredibly goofy I believe it’s the best one available for OS X. You can configure it to connect to a repository, and then checkout a revision to make a working copy on your local machine.

HeaddressManaging, hosting and testing multiple web design projects can be a pain, however, especially if you don’t want to muck around inside Apache’s httd.conf file. I use Headdress, a tiny application that helps you manage virtual hosts in OS X, to handle all of my local development websites. The free version of Headdress lets you host two sites simultaneously, and if you want to run more it’s a lousy $14.99.

Ahem. Welcome to your new workflow, where you edit your local working copy while testing it in a browser window. When you feel like you’ve reached a comfortable point in your development, or if you’re about to try something risky, go ahead and commit the changes you’ve made to your working copy to the repository. This is how I do it now. Edit locally, refresh locally. Edit locally, refresh locally. Time to fix another cup of tea? Commit all local changes to the repository as a new revision.

“What about launching? What about deploying? What good is all this work if no one can see it?” I’m glad you asked! I still maintain a number of super-secret subdomains, where I can test my development work directly on the web server that will ultimately host its production version. Remember, the working copy of your website on your local machine is just that: a copy from the repository. So long as you’ve committed all your changes, the exact same site exists inside the repository as the most recent revision of your project.

Deploying your site, whether it’s deploying on a testing domain or deploying for realz realz, is just a matter of “checking out” a fresh copy from the repository. This is pretty easy, so long as you have Subversion installed on your web server. I’ve found the easiest way to do this is to SSH into my server, navigate to the parent directory that holds the folder in which I would like to expand the copy, and using the svn checkout command to checkout the most recent revision from the repository into that folder. After I’ve done that, I can continue to freely edit my working copy on my local machine, and commit those changes to the repository, without worrying about messing up the copy on my web server.

Once I’m happy with some new changes I’ve made, however, it’s easy to bring the version on my web server up to speed. All I do is SSH into my server, navigate to the child directory into which I originally checked out the copy, and type svn update. Bam! Everything that was out-of-date is now up-to-date! It can certainly be a lot more complicated than this, which is why there are services like Capistrano that automate the deployment and updating process, but at its most basic this is what’s going on.

“Dammit, Dane!” you’re saying. “What about my database? What about my needs?” Indeed, to make this work well you need to have a database that your local working copy can connect to. Sometimes you can use a remote server, which is what I did until I found a better solution. Currently I run a few MySQL databases on my local OS X machine, which I connect to via localhost and manage through CocoaMySQL. Getting WordPress to connect to a local MySQL database took a bit of finagling, but a quick search revealed an easy solution.

Disentangling Siskiwit

So. I wanted to move Siskiwit, and each and every part of it, out of Brainside Out and onto its own domain. The fact that I was able to upgrade Movable Type made me realize that Siskiwit was likely more flexible and portable that I had thought. To test this theory, I created a new project on my local machine, did a fresh install of Movable Type on it, and imported its current MySQL database onto my local MySQL server.

After changing a few configuration files to reference the new local database, I told Movable Type to rebuild all the weblogs, which it did flawlessly after only a few initial hiccups. I had a few stray layout, design and container files that I had to bring down from the live server, but the amount of customization necessary to get the site working was minimal.

At this point, the old skool way of doing things would have been to wrap up my local copy of the site in a zip file, FTP it to its corresponding subdomain on the server, and SSH in and expand the file. As if! Instead I created a new Subversion project at Beanstalk and imported my local copy of Siskiwit as a starting revision. From there I SSH’d into my server and ran svn checkout to put a copy at its new subdomain. I changed a few configuration options to make the site reference its live MySQL server, had it rebuild all the weblog files, and it all worked like gravy.

It’s worth noting that I left all the “rebuilt” weblog files out of the Subversion repository, and I left out the actual Movable Type install as well. With the former, Movable Type creates the static rebuilt files based on the content in the database, so they’re completely unnecessary so long as Movable Type has a database to work with and rebuild from. With the latter, since I’m never going to edit the Movable Type system files there’s no need to keep them under version control, so I just uploaded the .zip to the server and expanded it.

Likewise, since my images directory for Siskiwit is pretty huge, and since I don’t plan on making any changes to it, I left it out of the repository as well. This can be some fairly subtle and complicated stuff, and I mention it just to be clear that it doesn’t make sense, nor is it necessarily advantageous, to store everything in version control. Your own mileage may vary.

Before nuking every last trace of Siskiwit from Brainside Out, I wanted to make sure that visitors accessing pages at their old locations (either through search engines or through a crazy-good memory) would be seamlessly redirected to the page’s new location at the site’s new subdomain. I did this by adding the following rule to my .htaccess file in the root of

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?brainsideout\.com$
RewriteCond %{REQUEST_URI} ^(/weblog|/photolog|/sundries|/classics|/av)
RewriteRule (.*)$1 [R=Permanent]

I have a few more rules besides this one, but they relate to CodeIgniter and aren’t relevant here. Also, if you want to monkey with .htaccess files on your locally hosted OS X websites you’re going to have to turn on mod_rewrite. It’s a bit of a thing, but you probably won’t die trying to do it. Headdress does have a bad habit of occasionally overwriting changes that you’ve manually implemented in your httpd.conf, especially when you add or remove a site from within Headdress. Yeah. Good luck with that.

With Siskiwit under version control and relocated to its new subdomain, and Rosco versioned and backed up as well for some inexplicable reason, I was finally ready to nuke everything at and deploy the new, CodeIgnited version. I SSH’d into the server, navigated to the corresponding directory, and with cautious fingers typed rm -Rv --preserve-root *.

I then left my computer and fixed myself a drink. Upon returning I checked, double-checked and triple-checked my work, and pressed return. Then, with a haste matched only by the files scurrying up my screen, I deployed the new edition of Brainside Out from the repository.

Spring is here, and comments are open.

That’s right, comments. It’s gonna be that kind of spring.

End Part II. Read Part I.

Quantum Entanglement – Part I

This is Part I. Read Part II.

Over the last few weeks I’ve been working diligently on a few personal web projects, and what you have in front of you now is the most recent incarnation of Daneomatic, which was launched last night. There’s also a new version of Brainside Out, which has already been puttering about the neighborhood for the last week or so.

Brainside Out

The original plan was simply to rebuild Brainside Out, but I was so fancied with the results from that project that I felt compelled to bring it over to Daneomatic. The act of “porting” the design and integrating it into the slapdash theming engine of WordPress took more effort than I expected, but I still figure a three-day turnaround from naked idea to launch isn’t that bad a churn.

The Problem With Supermodels

While it was definitely a fun challenge to piece together, in the end I was never too fond of the previous redesign of Brainside Out, launched in 2006 and codenamed Rosco. It always felt too heavy, confining and noisy. I was aiming for a funky private jet with shag carpeting and a rotating bed, and I feel like I hit a threadbare middle seat in coach. What’s more, the previous site was built to drum up work for an independent business that has since been pushed mostly aside to make room for a full-time job. This particular event happened more than a year ago, and if there’s one thing that supermodels, pets and websites don’t thrive on, it’s neglect. Unless they’re sea monkeys. sea monkeys dig that neglect shit. Kate and I are so gonna get some sea monkeys when we move into our new place.

More insidiously, the files that drove the Rosco edition of Brainside Out were intertwined with those for Siskiwit, the previous-previous version that was a weblog of sorts, a culmination of all the writing and web design I had done since 2001. The two sites existed side-by-side, confusingly wrapped around each other in a suffocating embrace, one stiff and businesslike, and the other bent low with a millstone of archives around its neck.

With the repositioning of Brainside Out as a business it didn’t really make sense, nor would it have been worth the effort, to bring Siskiwit and its thousands of archives forward into the Rosco design. Daneomatic would carry forth the Brainside Out weblogging tradition, but with five years’ worth of blood, sweat and tears put toward its name (or rather names, for those with ancient memories) I wasn’t about to nuke Siskiwit’s archives.

And so it came to be that I erected a crude scaffold around Siskiwit, allowing me to leave it fully intact while supplanting its front-facing views with Rosco. This worked. This worked just fine, and it very well would have continued to work if I hadn’t been born such a wild and restless child.

Bootstrapping in Flip-Flops

For years, up until just recently, all the sites I’ve built have been propped up with a laughably crude, but impossibly handy, PHP bootstrapper of my own devising. Calling it a bootstrapper may be too generous, as it’s nothing more than a glorified include file. Despite its inelegance it filled that void between “static website” and “dynamic template engine” with remarkable effectiveness, to the point that there was never really any incentive to improve upon it.

I’m a control freak when it comes to file structures and resource hierarchies, and as a code snob I am loathe to subject myself to the default outputs (or, gasp, the default layouts) of anyone’s content management system. With my simple bootstrapper I could build and deploy a site extremely quickly, all the while putting everything precisely where I wanted it to be. I wasn’t about to adopt another convention until I discovered something that was remarkably better.

And then I discovered something remarkably better.

Something Remarkably Better

Bixby BaconDuring SXSW I shared my experience with building Bixby Heart Dot Com (that’s B-I-X-B-Y Heart Dot Com) with the EllisLab folk, but unless you were one of the twenty people attending their open panel, this anecdote likely bears repeating.

Jake and I had limited time to work on the Bixby Heart project and we wanted to get it out the door in time for SXSW, so throughout our development process the focus was always on “light is right”. Jake is one of the most talented designers I know, and I’m a great front-end (and lousy back-end) developer. Thus, perhaps inevitably, Jake did all of the design and much of the front-end development, and it somehow fell to me to write the back-end code. Yikes.

I wrote all of Bixby Heart in PHP, and I felt I did a fairly decent job at it. I compartmentalized all my functions and fine-tuned them for robustness. In the interest of simplifying the development process, one of my earliest decisions was to use flat files, rather than a database, to store incoming data. Databases are one of the most fickle, insecure, time-consuming and misunderstood subjects of web design, and I wanted nothing to do with any of it. I figured if I sidestepped the issue it would just go away.

Boy was I wrong.

I set up a buffer flat file that intercepted incoming data, and rotated every few minutes on a cron to dump its contents into the primary flat file. At first it recorded boolean values for “bacon” or “juice”, and soon it recorded timestamps along with them. Then it recorded IDs to prevent writing the same entry multiple times. I’d parse the flat file with string compares, searching for tabs or newlines or what-have-you. I even set it up to increment through the contents of the flat file, in case it became so huge that the entire file couldn’t be held in memory at once.

It was when we actually wanted to do something with the data that it all fell apart. Display the number of bacons? How about the number of juices? Oh dude, how awesome would it be if we could graph the heart rate over time! Say, do we even know how to compute the current heart rate?

SXSW was in two days and I was at an absolute dead end. We were taking in test data but I couldn’t figure out how to work with it in any reasonable fashion. I tried tweaking the flat file setup. I tried setting up a database. I panicked, and even tried installing Pear DB. Before long the entire application was completely fucked up and I didn’t even have a working copy to roll back to. In a single night we went from having a semblance of an application to having an unmanageable rat’s nest of broken code. It could not be saved. I gave up. I gave the fuck up. I cried and screamed and pummeled at my pillow with tiny little fists.

And then I found CodeIgniter.

Code IgniterCodeIgniter is a lightweight MVC framework, brought to you live in PHP by the same guys who gave you ExpressionEngine. I had installed and tinkered with CodeIgniter before, and of all the application frameworks I had experimented with (CakePHP, Symfony, Django, Rails, etc.) it was by far the most clearly documented and easiest to install. It’s worth noting that the upcoming version of ExpressionEngine is written entirely in CodeIgniter, and it’s so hot it will make you cry. With less than 24 hours between us and SXSW, I realized that this was our best, and perhaps only, chance of finding a database class that would suit even our meager purposes.

I decided I would give it a shot, and eight hours later I had completely rewritten Bixby Heart in CodeIgniter. We had a fully-functional application to bring to SXSW. I built all the necessary database hooks, and Jake thusly grabbed them and wrote the front-end hotness. Before long we were soaked in whiskey and vodka, presenting Bixby Heart Dot Com to a private audience as we struggled to keep our balance in an RV lumbering through downtown Austin.

After that experience I decided any application, nay any website, that I built from thenceforth would be written in CodeIgniter or a suitable equivalent. I make a lousy zealot and thus am open to other options, but as an individual I have by far made the most progress working in CodeIgniter. When rebuilding the Big Winds website in Ruby on Rails I worked with Jason Ives, a talented local developer, but without his canny knowledge of server configurations, database schemas and all-around Ruby l33tness, I am but a lost little puppy.

And so it came to pass that the new version of Brainside Out is written in CodeIgniter. In its current state it’s skimpy as far as content goes, and I’m still debating how best to go about resolving that. The site still suffers from a modest identity crisis, especially since the majority of my web activity has moved offsite, but now it is far less confused than it was during the “is a business, is not a business” phase. More than anything, I needed to shrug off the yoke of all its legacy innards, and figure out an elegant way to store that stuff elsewhere.

And that, my friends, is our next story.

End Part I. Read Part II.



Jake and I are obviously up to no good.

Lacking even the sophistication of a Twitter update.

Ironically, I find myself spending so much time with the internet lately that I have no time for the internet.

Web Nerd Geek Party

Last October I accidentally threw away my iPod Shuffle. This may sound like an interesting story, but more than anything it was dumb. Just dumb. Sure, it was just one of the old style Shuffles, the kind that was as big as a pack of gum which seemed really small for about fifteen minutes there, and I had already replaced it once after all the buttons had stopped working, but that little bastard still set me back $150 at the time.

Last week my new iPod Shuffle arrived, the latest version of the latest kind that has a built-in clip and comes with Apple’s new-style headphones and is about the size of a postage stamp if postage stamps were a quarter of an inch thick and cost $79. Honestly, this thing is small. I almost swallowed it just taking it out of the box.

Anywho, I love the new Shuffle. At first I had planned on getting a nano, seeing as how the cheapest model would be the same price that I paid for my original Shuffle. After I realized that for my purposes I would need an armband or some crazy carrying shit like that, and discovering that such nonsense would run me an extra $30 or so, the Shuffle and its handy clip started looking much more attractive. I don’t need much from an mp3 player… I just need something that makes noise in my ears while I’m at the gym. Until I can afford a personal trainer, an iPod it is.

Hence the Shuffle, which is of a size that is so ridiculously small that it makes you wonder why your headphones need to plug into anything anymore, or even need to have cords for that matter. I still don’t have a proper full-size iPod, partly because I have no real use for one in my regular life, and partly because I keep putting off the purchase, in the interest of getting the next latest-and-greatest edition from Apple. I’ve been waiting for the multi-touch iPod ever since the iPhone was announced, and I know now that it’s only a matter of time.

It’s amazing when you realize that the click wheel, which was quite possibly the most innovative UI development of the oughts, has already been rendered completely irrelevant by the very company that invented it in the first place.

In other news, a week from today I take off for my second shot at SXSW. My first time was a blast and I got to spend it with my fellow UI-geek friend (and occasional lover) Jake Ingman, along with Sally and a number of other great friends we made down there in Austin. Jake and I have known of each other’s existences since 2001, but we didn’t hook up until SXSW last year. We rekindled our relationship through the 37signals personal ads (this joke was funnier before they started running their Job and Gig Boards) on a thread about Jim Brandenburg, and we spent our downtime at “South By” sharing the same bed. Or staying up all night blogging and uploading photos to Flickr. What can I say, we were both hopeless romantics at the time.

Jake and I are both jammin’ down to SXSW again this year, only this time around we’ve got two beds between us. Kate assured me, however, that she would be totally okay if we decided to share again. I guess we’ll just have to see what Anne says about the whole deal. Seriously though, some things just get out of control down in Texas.

Gainful Employment

“How’s the shop?” you ask. Yup, it’s been a couple weeks since I sold out and went whole-hog at Big Winds. It’s been great, and while my job suffers from a severe and terminal case of ADD, I’m not so sure that’s a bad thing.

Sometimes I’m working on the website, but much of the time I’m helping customers in the store, or answering kiteboarding questions on the phone, or processing internet orders, or cleaning out the microwave after my coffee exploded. For the next couple days I’m actually in charge of the shipping department, as Joe has taken a few days off to go out to Joseph, Oregon and give a ring to a special person. Sadly, he may return to find both his bachelorhood and his workspace in ruins.

A few days ago Bruce Peterson, the brilliant and kind fellow behind Sailworks, stopped by the shop. While climbing into his van he found me on the sidewalk in front of the shop, covered in dust and shaking the dirt out of a whole stack of rugs.

“Hey Dane, welcome back!”
“Thanks, Bruce!”
“So, web guy, eh?”
“And… rugs, looks like?”
“Uhh, yeah. Either way, I usually just take them all out back and beat them.”

So yeah, I’m all over the map these days and still busy getting reacquainted with the shop, but I’m really enjoying the diversity of it all. In regards to the website there’s a whole lot of changes I want to make, but much of it falls behind my current priority, which is to simply make our online product catalog accurate. There’s a lot of data in there, and even though I’ve nearly rewritten the entire back-end over the years, there’s a lot of legacy code that prevents me from efficiently making large-scale updates. That said, I have managed to eek a bit of coolness out of the deal:

Using this batch of Photoshop Automator Actions, I’ve automated the generation of product images for the website. It took a couple hours of development, but now I’ve got a nearly foolproof system that takes in a batch of original high-res images, and automatically creates large, standard and thumbnail sized images. The whole deal respects aspect ratios, throws in a bit of unsharpen mask and gently compresses each image, all while I microwave yesterday’s coffee for the fourth time.

Thanks to this, I’ve been able to integrate Lightbox with our kite detail pages. It’s still in beta so there aren’t any visual cues, but if you click on the kite picture it’ll bring up a larger version. I really wanted the large images to be much bigger, but our web statistics suggest that most of our visitors are still stuck at 1024×768 resolution, and I didn’t want them to have to scroll to hit the close button.

Hard to believe, eh? I mean, I kicked 1024 to the curb at least five years ago, maybe nine, and my preferred environment these days is a whopping 1900×1200. Apparently there are still a bunch of people out there who want to be miserable in front of their computers, and want blindness to accompany their barroom deafness.

Here’s another interesting discovery. According to our statistics, as well as some off-the-cuff usability studies I’ve conducted (which is just a fancy way of saying that I watched people browse our website), people have no clue that the “Boards”, “Sails”, “Masts”, etc. headings in our primary navigation are clickable.

It appears that even the New York Times website suffers from the same problem, which is probably why they have little » &raquo; glyphs next to their category headings. While I definitely have qualms about the improper semantics of using right angle quotes as visual cues rather than as, say, quotes, I figured I’d give them a shot and see if they affect usability at all.

Another kinda neat thing we did to the site is add a couple of QuickTime VR Tours of our shop. A couple months ago we had a guy come in and shoot the whole place with a fisheye lens, and stitch the photos together all right-nice. In the interest of catering to a hideous web browser that is used by a vast majority of our visitors (see my earlier point about how people want to be miserable at their computers), I tried to embed the videos as unobtrusively as possible, using these scripts provided by Apple.

Long story short, by using JavaScript to embed the video code, I am able to circumvent the repercussions of the Eolas lawsuit, and make the videos work in Internet Explorer without requiring visitors to hate their lives and click on it multiple times.

I know, I know. There are better ways to embed content, ways that will validate and are semantically correct. That said, even the most recent article on A List Apart doesn’t arrive at a definitive solution for the issue, and as such I’m willing to leave this one up to bloody pragmatism. My solution above worked in every browser I tested, under nearly all conditions, and I call that good.

In happier news, I did manage to get all of my tiny, disparate onload JavaScripts to fire using the same addEvent() function. Major props go to Dustin Diaz for his rock solid addEvent() function, though I might add we’re still gonna whoop his butt in bowling at SXSW.

And hey, did you know that in a Google search for “camp loo”, camping toilets come up in nearly all of the link ads? I just thought that was funny.

Hired Goon


I guess there’s been some changes ’round these parts over the last couple weeks. I’ve been busy with those so I’ve kinda been neglecting some things, small things like this blog and personal hygiene and common decency.

When I got back from Walla Walla last Sunday someone had been kind enough to leave me a dead bird on the sidewalk to my house. The next morning the bird was gone, replaced by little feathered turds. That afternoon I came home to find a dismembered wing on my front step, and the turds were missing.

So there was that.

Also, I’ve been busy raising a beard again. It’s hard work and it takes a lot of time and effort, especially for the few of us who do not have Chuck Norris in our ancestry. There’s so few of us.

So very few.

But yes, a beard. By the looks of things this is the winter of the Sketchy Facial Hair, and I wanted to throw in my lot. I would also like to have a beard for SXSW, along with a mohawk, if I can muster the guts to do that again. Yeah, a beard and a mohawk, so I can appear to be consistent with my Flickr and Facebook and profile photos. We call this “branding.”

This “alcoholic energy drink meets malt beverage” tastes like an atrocity.

That’s branding, too.

Hey, Kate took me to the Walla Walla Wal-Wal-Mart when I was back over there, and it is vastly superior to the Hood River Wal-Mart, and we actually went there twice, once to buy a potted plant and frozen chilies and again to buy windshield wipers and twelve mason jars, and both times the same clerk helped us. The same clerk! At checkout lanes that were at complete opposite ends of the store! And there’s a tram that runs every seven minutes to take you from one opposite end of the store to the other!

He was a really cool clerk, too. We wondered why he was working at Wal-Mart, being as cool as that. I thought he was probably writing a book about his experience, or at least blogging it.

Twelve mason jars is a lot more mason jars than I thought I needed, so I’ve been spending my time finding things to fill them up with, things like basmati rice and cashews and yerba mate. Yerba mate has a very strong organic, earthy taste to it, which is a nice way of saying it tastes like dirt. It’s dirt jam-packed with caffeine, though, so I’m not about to criticize. My bombilla fell apart way before the Web 2.0 boom so I need to find a new one before I can drink my mate again. Taragui, it was. The mate, that is. You can buy it by the kilo, like other things you can buy.

There was something else.

Oh yeah.

Tomorrow I start my new job at my windsurfing and kiteboarding shop. Even though job titles are kinda ridiculous and we really have no use for them, I shall be working as the Director of Web Marketing for Big Winds, a position which is known internally as “Hey, we have our own computer geek!”

I have worked for Big Winds a couple of times in the past, once in 2003 and again in 2005, and I hearts them lots and lots. I love the people who work there, I love the store and the products, and I love their business ethos. Needless to say, I’m stoked as hell to work for these guys, to be surrounded by people again, to be active in the community, and to know that this summer I will kiteboard so much I won’t even be able to piss straight.

The upshot of all this is that I’m taking on Big Winds as a full-time job, and I’m going to have very little time to run Brainside Out. I’m still kinda stunned by the whole bit, shocked and nervous and excited and somewhat nauseous, but I think there’s a tremendous opportunity to do some kick-ass stuff here. I’ve told my clients about the change, and they have all been extremely supportive and enthusiastic. Like, bummed I won’t be able to rock stuff for them anymore, but amped for me nonetheless.

Still, I’m freaked out by the fact that I’ll actually need to wake up in the morning. I suppose it’s a small price to pay to be able to interact with real people, though.

Brainside Out will continue to exist, perchance as a shadow of its formal self, but dammit if it’s not going anywhere. I’ve been running that dealy-deal for 1 1/2 years, have gotten to build some great websites for some absolutely ripshitkickass clients, and I take a huge amount of satisfaction in knowing that I’m fully capable of running my own show. With the ridiculous degree of autonomy that I’ve been enjoying in running Brainside Out, the shop may have gotten more than they bargained for. I mean, I build good shit, but I’m used to doing it on my own terms.

That said, I did work for them in-house on two separate occasions, for half a year on both counts. In 2003 I shared an office with the head manager for a couple weeks, until he realized that I talked and cursed to myself so much that I needed to be quarantined to my own office. Big Winds was also the first client that Brainside Out ever had, and thus precipitated my move to indie status.

Nah, they know what they’re gettin’. And I’m stoked.

Geez, did I mention I’m stoked?

Design WTF?

When I started Daneomatic I promised myself that I would never attempt to “design” it, as the focus here is supposed to be on “writing.” And “swearing,” if you will. But certainly not “designing.”

I had also promised myself I would call it Dane-O-Matic, but I quickly realized that I was far too lazy to go through all the work to type it that way. Geez, two hyphens, three shift keys? You’d think I wanted to pull a muscle while trying to spell it out. Thus, in the continuing interest of pragmatism and efficiency, Dane-O-Matic became Daneomatic. I estimate that I can type it at least ten times faster.

Faster than your mom, that is.

Anywho, as lovely as the default theme of WordPress is, and for how many blogs out there who must be using the exact same theme for many the same reasons as I, it was really starting to grate on me. The design was too narrow, too tight, the letters too small. I wanted something mo’ open, mo’ bigga, mo’ printy in nature. And so I cobbled this together.

The advantages are two-fold. First, I feel less cramped by my canvas. Second (and far more important), you can now freely browse this site and pretend you’re looking at something far more reputable, like the or something!

Things might could be kinda broken in a few terrible web browsers. I tested this design in all the worthwhile browsers I could think of (Safari, Firefox, Camino, Opera), as well as a few worthless ones (IE 7, IE 6) and everything works fine. Not great, not awesome, but fine. Yes, there are a number of whitespace inconsistencies, as well as some leftover default WordPress silliness that I find to be quite… silly. If I find something in the design that will literally cause people to die if it isn’t fixed, I will probably address it. If not, I shrug.

I’ll probably continue to tweak and massage this beast over the next couple weeks, so for the time being my only advice is to hang onto something. If all else fails there’s always the newsfeed, a syndication technology that stands to undermine the work of web designers everywhere.

And in all honesty, I’m perfectly okay with that.


While trying to get some shopping done on the interwebnet today, I was met by this jewel of an error message:

We are sorry for the inconvenience. Our site currently supports only Internet Explorer version 4.0 or higher. This is due to the advanced features used in the product customization process.

If you do not have Internet Explorer, it may be downloaded for free at Microsoft’s website here.

If you are currently using Internet Explorer version 4.0 or higher and are reading this message, there may have been an error. Please inform the webmaster.

This was all courtesy of the Staples Mark The World e-commerce store. While it’s a very user-friendly error I still noticed some problems with it. I sent their webmaster the following email:

Dearest Webmaster,

I regret to inform you of a typo on the web browser checking page on the Mark The World website. Currently, this page reads as follows:

We are sorry for the inconvenience. Our site currently supports only Internet Explorer version 4.0 or higher. This is due to the advanced features used in the product customization process.

It should read as so:

We are sorry for the inconvenience. Our site currently supports only Internet Explorer version 4.0 or higher. This is due to the horrible incompetence of our web developers.

In all honesty, whoever is maintaining your site should be fired right now. Seriously. Walk down the hall and tell them to clean out their desks. This sort of error is unacceptable. No large business should be doing this sort of browser detection and user-blocking in 2006.

I use an Apple computer, so suffice it to say I can’t go to the Microsoft website and download Internet Explorer for free. What’s more, Microsoft abandoned Internet Explorer for Mac more than three years ago. Even on Microsoft’s own website, they recommend that Mac users migrate to “more recent web browsing technologies such as Apple’s Safari.”

As such, I recommend that your website migrate to more recent web development technologies, such as punch cards, file cabinets and vacuum tubes.

Take care, and have a wonderful day.

Dane Petersen

A few minutes later I received the following message back. Is this not just total weak-sauce? apologizes for any inconvenience. We hope to have the website accessible to other browser options in the future. It is not our intention to stop other browser users from accessing the site. Please contact Staples Direct at 1-800-547-7224 ext. 35688 to try to place your order.

[email protected]

What boilerplate! What tripe! What’s more, I love how personal they get with the “Sincerely, [email protected]” nonsense. No name, not even a made-up name! Unless, as Jake pointed out, it is indeed a person’s name, who was born to some really shitty parents who were total tools of the internet age.

After seeing this, Jake decided that he’s going to change his last name to “Dotcom”, and name his kid “Goatse”.