Permanent Ink Design

Accessible Data Visualization With Web Standards

posted by Jake

This A List Apart article is just brilliant. I now want to make charts, and lots of them.

The Mysterious “Save for Web” Color Shift.

posted by Jake

I’d seen the problem before, but never so pronounced: The color, through no fault of its own, was obviously changing, and we were at a loss for a way to prevent this.

Finally! It seems like I’ve struggled with this with every project over the past year. I tried everything I could think of, and I had some of the pieces in place, but I never worked out the full puzzle. I took smarter and more patient men than I…

markItUp! Universal Markup Editor

posted by Jake

Alright, so I’ve had this open in my browser for two days. I have been looking for a good javascript-based Markdown editor for a while, and I can’t wait for an excuse to try this out. Built on jQuery, like all the cool kids.

No Resistance Is Futile

posted by Jake

Not long ago, tasked to review 763 songs at a swoop, I cut the review length to six words and suffered not at all.

I saw this posted in a few places over the last couple of days. Outstanding.

37signals linked to it as well today. They also linked to Albert Einstein’s Theory of Relativity In Words of Four Letters or Less as a further example of restraint in writing (or resistance leading to brilliance, depending on how you want to look at it).

Reading these two articles together, I was struck at how a web site it a system with resistance. Much like the universe, without rules, the whole production falls apart. We constantly push what is capable within the confines of those rules—we write 763 insightful song reviews six words at a time, we fly to the moon, we participate on Twitter—but without the rules, nothing great is possible at all. Making order and sense from content and presenting it in a meaningful way is what web design is all about.

The Billion Dollar Letter

posted by Jake

I just ran across this brilliant piece of marketing today. So simple, yet so effective. I love that combination.

Permanent Reset

posted by Jake

Eric Meyer has created a permanent home for his lovely Reset CSS stylesheet. I couldn’t be more pleased.

Ding Dong, the Bar Is Dead!

posted by Jake

Which ol’ bar? The translucent bar!

(optionally dead, that is)

Fontifier

posted by Jake

This is pretty cool. Fontifier creates a font from your (or anyone you can coerce into filling out the form) handwriting. Only $9.

I guess once I do this I can finally throw out all my ink pens. Yes, Nick, I realize you are good enough to draw with a pen, so I guess you might want to keep some around.

Simplify Working With Shares in Leopard

posted by Jake

Macworld has a handy article on working with network shares in Leopard. New info to me. I tend to use good ol’ command-k when connecting to shares, but I can see using this for myself on some occasions or showing it to others that aren’t as comfortable with the Go menu.

Instapaper

posted by Jake

I used several of the social bookmarking sites when they first launched, but couldn’t stick with it. I guess I worry too much about things being under someone else’s control, meaning I don’t want to become attached only to have a beloved service shut down and leave me in the lurch. Most of my long-term bookmarking in now done in Yojimbo.

With that said, I also find I leave tabs open in my browser for obscene amounts of time as pages linger somewhere between being closed and forgotten and becoming a long-term bookmark. Most of the time, I am simply keeping things around until I have time to read them thoroughly so I can make a decision about that page’s status. That’s where Instapaper comes in. It allows me to quickly mark things for later reading, getting them out of site until I have time to dig in. Awesome.

Google Analytics, jQuery, and File Downloads

by Jake

First, let me say that Google Analytics is awesome. Anytime someone purchases a company and makes their industry-leading, $200-a-month product freely available, it’s a-ok in my book. While you won’t see any complaining out of me, there are a few aspects of the package that are less than desirable, but are simply the nature of the beast.

To understand the limitations, it’s important to understand that Google Analytics is javascript based and does all of it’s nice tracking on the browser side once a page is loaded. That’s fine, but it is difficult to track anything other than a standard web page. Because files (zip, word, pdf, mp3, etc.) can’t contain javascript and aren’t processed in a browser, you have to track these files by inserting special code on the links pointing to those files. Google has a help page explaining how to track these downloaded files (it also works for tracking links to anything, such as links to external sites or mailto links).

Google provides the following instructions on formatting these links:

<a href="http://www.example.com/files/map.pdf" onClick="javascript:urchinTracker ('/downloads/map'); ">

Important: if your pages include a call to urchinTracker(), utmLinker(), utmSetTrans(), or utmLinkPost(), your Analytics tracking code must be placed in your HTML code above any of these calls. In these cases the tracking code can be placed anywhere between the opening tag and the JavaScript call.

Well, I don’t know about you, but all that javascript in my link tags gives me the willies. If Google every changes their script (or something better comes along), have fun changing every single download link on your site. That’s every template, every article, everything.

So, I went looking for a way to apply this code dynamically into the appropriate links on my site, and sadly, I didn’t mind much. It was obvious that I was going to have to do a good portion of this on my own, and I might as well make good use of my new best friend, jQuery, while I was at it. (Note: I know some of the following techniques come from other, smarter people, but this became such a mismatch of ideas that I honestly am unsure who to give credit to. If you recognize anything that needs attribution, please let me know)

First things first, I didn’t follow Google’s guidelines for how to include their javascript, but everything seems to work great in my testing (I have been using this technique for a couple months now without incident or report of problem - across multiple sites). The following can be found in the section of every page on my site:

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
<script type="text/javascript" src="/javascript/jquery.js"></script>
<script type="text/javascript" src="/javascript/analytics.js"></script>

I’ve included the Google Analytics javascript, the jQuery javascript, and my own custom analytics javascript. It’s important to include the analytics.js file last.

Ok, now let’s take a look at what’s inside my file:

$(document).ready(function(){
    // This code needs to be changed to the code Google Analytics provides for your account
    _uacct = "UA-1111111-1";
    urchinTracker();

    // The slashes are to ensure the period is in the url, the $ is to make sure it is the end of the url, the i is to make it case insensitive.
    filetypes = /\.doc$|\.xls$|\.exe$|\.zip$|\.pdf$|\.mp3$|\.psd$/i;
    $("a").each(function(){
        // Track mailto links
        if ($(this).attr("href").match(/^mailto\:/i)) {
            var url = $(this).attr("href").replace(/^mailto\:/i, "")
            $(this).click(function() {urchinTracker("/mailto/" + url);})
        }
        // Track external links
        else if (location.host != this.host.replace(/\:80$/i, "")) {
            var url = $(this).attr("href").replace(/^http\:\/\/(www\.)*/i, "")
            $(this).click(function() {urchinTracker("/outgoing/" + url);})
        }
        // Track downloads (links with a given extension)
        else if ($(this).attr("href").match(filetypes)) {
            // The URL needs to be changed for each site this is applied to.
            var url = $(this).attr("href").replace(/^(http\:\/\/)*(www\.)*(permanentinkdesign\.com")*\//i, "")
            $(this).click(function() {urchinTracker("/downloads/" + url);})
        }
    });
});

And that’s it. There are a few things worth noting in this script. First,

_uacct = "UA-1111111-1";

needs to be replaced by the code that Google supplies to you (the numbers here have been changed for my protection). Second,

filetypes = /\.doc$|\.xls$|\.exe$|\.zip$|\.pdf$|\.mp3$|\.psd$/i;

is a variable containing a regular expression stating the file extension of all the file types I’d like to track. If regular expressions don’t make much sense to you (they didn’t to me when I started working through this), then you’d be wise spending some time learning how they work. They are very powerful and can help in a lot of nifty ways.

The next part of the script goes through every link on the page, applying functions that will fire when links that match our criteria are clicked.

$("a").each(function(){

This is the jQuery code that says, “Give me every ‘a’ tag, and for each one, run the following function.” There are three types of links I want to track (you can add others as you see fit). The first type is the mailto link.

if ($(this).attr("href").match(/^mailto\:/i)) {
    var url = $(this).attr("href").replace(/^mailto\:/i, "")
    $(this).click(function() {urchinTracker("/mailto/" + url);})
}

The first line of this part says, “If the href attribute of this link starts with ‘mailto:’ then do the following.” Line 2 rips the email address out of the link and applies it to the url variable. Line 3 adds the onclick function to this link. It means that anytime someone clicks on this link, it will show up as a pageview for /mailto/example@nospam.com in Google Analytics (yes, the email address will be what is actually set in the link, not example@nospam.com). The last half of this line should look eerily similar to the Google approved method shown at the top of this article.

The second type of link I would like to track is a link to an external site. I look for links in a particular order because I want to catch all links to external sites, even if they are linking to files, before I look for files on my own server. Otherwise, I could have other people’s files show up in my downloads list in Google Analytics. I search for mailto links first because I am unsure how these links work with the location lookups I do for external links, so I remove the uncertainty by looking for them first.

else if (location.host != this.host.replace(/\:80$/i, "")) {
    var url = $(this).attr("href").replace(/^http\:\/\/(www\.)*/i, "")
    $(this).click(function() {urchinTracker("/outgoing/" + url);})
}

The first thing you’ll notice is the “else if.” In plain english, this line says, “Ok, so this link isn’t a mailto link. Fine. If, however, the website to where this link is pointing isn’t the same as the website I’m currently on, do the following.” You’re sure to notice the .replace(/\:80$/i, “”) portion of this statement. That is a regular expression to make the way all browsers view this.host consistent with how they view location.host (basically, Internet Explorer adds :80 to the end of this.host, so we’re removing that if it exists).

Line 2 sets the url variable to the url of the external link, minus the http and www bits (for easy reading). Line 3 adds the onclick function, which should make sense at this point.

Moving on, I want to track links to files on my server (downloads, if you will).

else if ($(this).attr("href").match(filetypes)) {
    // The URL needs to be changed for each site this is applied to.
    var url = $(this).attr("href").replace(/^(http\:\/\/)*(www\.)*(permanentinkdesign\.com")*\//i, "")
    $(this).click(function() {urchinTracker("/downloads/" + url);})
}

The first line says, “Alright, this link isn’t a mailto link, and it isn’t an external link. If, however, the href attribute of this link ends with one of my specified file extensions, do the following.” Line 2 (line 3 if you count the comment) again sets the url variable, this time to the url of the file minus the http://www.mywebsite.com/ stuff. You’ll need to replace the “permanentinkdesign” portion of this line with the site that you’re using this script on. I have a sneaking suspicion that there is a better way to do this, perhaps by using something similar to this.host, but I couldn’t get it to work. I’m open to recommendations for improvements. Line 3 once again adds the onclick function.

And now, that really is all there is to it.

Design Decisions

posted by Jake

Speaking of design decisions, I’d been waiting for the next 37signals post in their series before linking to it. Unfortunately, this episode doesn’t have any pretty pictures to look at, but it’s always nice getting a glimpse at successful folks’ decision processes.

Design isn’t always visual, kids. Often it’s about organization and structure. Always it’s about focusing on what’s important.

Blueprint Grid CSS Generator

posted by Jake

Well, it looks like my excuses are dwindling. Check out this awesome script that generates a custom version of Blueprint’s grid CSS file based on your grid specifications. Did I say awesome?

Web Standards: Footnotes

posted by Jake

I like web standards. (X)HTML and CSS are what everyone reads about, but there are so many other things we do on the web that could be done in a standardized way. At its core, that’s what Microformats are about — formatting information in a standard way so it can be used easily from a multitude of programs.

I believe John Gruber’s method of marking-up footnotes on the web should be a standard of sorts. It’s the very best way I’ve seen to place this sort of information into a web page. If not a standard, it’s at least a great pattern to follow. Needless to say, I’ve adopted the formatting here, but I am still perfecting my method of entering the footnotes into my posts in Expression Engine. Another post for another time…

Designing the Tracker

posted by Jake

I love reading about people’s design processes. Specifically, I like seeing the thought that goes into certain design decisions. That’s why Garrett Dimon’s recent series on designing elements of his bug tracking software has been of particular interest to me. It’s excellent stuff, like most everything he writes, so be sure to go subscribe to his feed.

You know, my plan was to wait until he was through with the series before linking to it, but he could probably keep this up for quite a while.

The Man

posted by Jake

So, there I am, reading through a thoroughly enjoyable article concerning book covers, minding my own business, and he pops up again. Again! Yes, I knew Kevin Cornell was the man long before now, but come on. I would say it was all a clever trick, or perhaps magic, that made everyone, and I mean everyone, hire him, if not for the evidence of his talent.

Go ahead, take a look at his somewhat pathetic portfolio. You’ll see work for A List Apart, Daring Fireball, Stuff And Nonsense, dConstruct. That doesn’t even get into the web design he’s done. It says something when the top creative minds in the industry hire Mr. Cornell to create things for them. How do other illustrators (or web designers for that matter) even earn a living when there are guys out there like this lurking around… possibly anywhere.

In poking around the Bearskinrug site, I also learned that my previous joke about “humour” was not even remotely funny. Figures.

Design Found (In a Pill Bottle)

posted by Jake

No, I’m not linking to some drug that will help you design better. I’m pointing out good design in a small and obvious place. I ran across this article a while back, and it was brought back to my attention by Ace Jet 170 today. It’s odd how this impacts me differently at my current level of maturity in my design profession than it did when I first read it. Be sure to check out Target’s demo to see more aspects of the ClearRx prescription system.

If nothing else, this reminds me how design goes beyond making something look attractive to making it function attractively. Above all, design is problem solving, and problem solving is my favorite part of everything I do.

Unstoppable Animated Gif

posted by Jake

Naturally, the first thing I did when visiting Ethan Marcotte’s new weblog was figure out how the robot blinking was accomplished (answer: the lowly gif), but that ain’t all there is to see folks. Go ahead, just play around with your browser width. Make it really small, make it really large. Now resize the text. Repeat.

Oooh, that’s nice. In case you’re wondering, it’s a fluid, elastic layout with the added benifit of max-width. That’s what we call CSS chops. That still isn’t all, however. Every handful of refreshes, Mega Man appears in the banner. A man after my own heart (not even mentioning the about page description in the far right column of that page).

This brings up a familiar delima. I love feed readers. I love beautiful web design. If I look at everything in a feed reader, I miss the beautiful design. Arrggg. There is a handy “next” bookmarklet for Google Reader that takes you to the web page for your next unread item, which is great, almost. When checking out the Daring Fireball feed, I am sent straight to the linked page on the Linked List items and miss Gruber’s witty and insightful commentary (which is sometimes necessary for the linked page to even make sense).