Archive for the ‘Usability’ Category
How web designers can do their own HTML/CSS: Read Foundation Website Creation
Last month, 37signals published a short but sweet post about why web designers should do the HTML/CSS implementations for their own designs. The bottom line is, as we’ve all been saying for a long time now, that the Web is not the same kind of medium as other mediums like print. It is a fundamentally different kind of canvas than most web designers are used to using. As a result, if you as a web designer are not intimately familiar with it, you’re not going to do great work.
designing for the web is a lot less about making something dazzle and a lot more about making it work. The design decisions that matter pertain directly to the constraints of the materials. What form elements to use. What font sizes. What composition. What flow. Those decisions are poorly made at an arm’s length.
I’ve worked with many web designers in the past who only did abstractions and then handed over pictures to be chopped and implemented by “HTML monkeys”. It never really gelled well. The things that got strong attention were all the things that Photoshop did well. Imagery, curvy lines, and the frame. All the around stuff, never the it stuff.
In other words, to do great web design you have to design in the Web, not in some other medium for the Web. I mean, serious magazine firm employs designers who don’t understand how to work with page layout programs like InDesign. Why, then, do so many web design agencies employ designers who don’t know how to work with web technologies, or even how to use programs like Dreamweaver? It doesn’t really make any sense, and it’s no wonder that the resulting implementation is rarely top-notch work.
But if you’re a graphic designer who doesn’t know much about Web technologies, what are you to do? Well, as a first step, I think you should pick up my new book, Foundation Website Creation. It’s available from all good booksellers (and probably some crappy ones) as of today. The book is targeted towards all manner of web professionals, including graphic designers and website producers, who want to learn more about what it takes to actually implement a site.
If I do say so myself, the chapters on XHTML and CSS are exceptionally thorough. The book doesn’t try to turn you into an exceptional programmer. Instead, it will explain the foundational concepts you need to know to understand how XHTML and CSS actually work, and in so doing will enable you to use the tools you already know to solve problems and get things done.
I think this book will be an excellent starting point for lots of designers and other web professionals. However, it is not going to take you from zero to hero—no book can. That’s why I recommend that, after you read Foundation Website Creation and have a solid grasp of what the technology can do for you and how it actually does it, you next take a look at these excellent books:
- DOM Scripting by Jeremy Keith — if you’re a designer that needs to add a behavioral layer with JavaScript and Ajax to your pages, you need to read this book next.
- Mastering CSS with Dreamweaver CS3 - if you’re familiar with Dreamweaver and want to keep using it to create standards-based web sites, then I recommend you follow Foundation Website Creation with this book by Stephanie Sullivan and Greg Rewis to take your Dreamweaver skills to the next level.
As always, most of all, have fun. Because if you’re not having fun, you’re not going to make good web sites no matter what you know.
Note: As of this writing, the book listing on Amazon still publishes the wrong author list, which is very frustrating but out of my hands. At least the image of our book’s front cover lists the correct authors.
I’m getting a book published and it’s called Foundation Website Creation
For those who have been wondering what is keeping me so busy these days, the answer is that I’m working on the final stages of a book that is getting published as one of three co-authors. Not only am contributing three chapters (the technical chapters on (X)HTML and CSS, specifically), but I am also technically reviewing the entire book.
My co-authors on the book, called Foundation Web Standards Foundation Website Creation (you can pre-order now) and published by Friends of ED, an Apress company, are Jonathan Lane of Industry Interactive, Inc. and Joe Lewis, who blogs at Sanbeiji.com. I’m not going to say much more until after the book is released in late July.
For the eager, here’s the description of the book posted on the Friends of ED website:
Foundation Website Creation explores the process of constructing a web site from start to finish. There is more to the process than just knowing HTML! Designers and developers must follow a proper process to flush out goals and objectives and determine requirements both prior to, and during project development.
Large Web projects are rarely completed by a single person. Producers, project managers, designers, developers, writers, and editors all play critical parts in a project’s evolution. This book provides an overview of the entire process, and also shows project development from the perspective of these different roles. It introduces the key concepts and duties performed by every member of such a team, and gives you the skills necessary to tackle projects like a professional.
It’s quite exciting getting a book out, and it’s quite a bit more work than I’d have ever originally thought. That being said, it’s extremely rewarding. There’s a lot more work I need to do on it between now and the time it gets released to publishing, so, well…back to work I go.
Now you all know where I’ve been spending my time writing.
TEDTalks: Inspirational, incredible, and moving ideas
For those not yet familiar with it, TED is an invitation-only annual conference of some of the brightest and most talented individuals in all fields of Technology, Entertainment, and Design. For the first time (in February 2006), the presentations were recorded and broadcast to the world once per week at the TED.com web site.
I’ve just spent the past three and a half hours at the site watching the presentations and I’ll have to blame them for making me sleepy at work tomorrow. Nevertheless, they are some of the most compelling and fascinating presentations I have ever seen in my life. I highly, highly recommend that you spend a few moments to check them out.
For those interested in Human-Computer Interface design, you absolutely must view Jeff Han’s talk on an “interface-less” touch-screen-like display which will very likely obsolete the traditional mouse and keyboard.
For those interested in global health and economics, you absolutely must view Hans Rosling’s talk on the myths of the third world.
And for those who just want more proof how much Apple Computer rocks our socks, you must view David Pogue’s excellent presentation on the woes caused by software frustration (and it’s partially set to music).
My personal favorite (so far) was Sir Ken Robinson’s almost stand-up comedy approach to explaining to us why the current state of the world’d public education systems will not serve us for our future.
New Amazon Guide: So You’d Like To Become a Front-End Web Design Guru
With a bit of free time over breakfast, I was fiddling with my personal site and looking over my bookshelf. I decided to make an Amazon guide to “becoming a front-end web design guru” based on many of the books in my ever-expanding collection. So without further ado, here it is, my guide to becoming a front-end web-design guru, featuring the most varied and useful set of 20 books I have ever read:
The Grim Truth
Let’s face it. These days, any Joe-shmo with Microsoft FrontPage can call himself a web developer or designer. But web surfers can tell the difference between a professionally designed site and a site designed by your dentist’s brother’s roommate’s best friend’s boyfriend. To be professional, you have to design with web standards in mind, focusing on usability and accessibility. And it has to look good — really good.
The Tools You’ll Use
First, you’re going to need to stock your toolbox. Start with the basics. Learn how to manipulate page layouts with (X)HTML and CSS by reading Eric Meyer on CSS: Mastering the Language of Web Design. Occasionally, you’ll need a dash of JavaScript Design. Finally, learn what works best by Designing Web Usability : The Practice of Simplicity.
Building It Right
The Zen of CSS Design : Visual Enlightenment for the Web (Voices That Matter) is possible for you! Building professional web sites means Building Accessible Websites (With CD-ROM). No matter how good your design may be, it won’t mean anything if it doesn’t load quickly, so don’t forget to always Speed Up Your Site: Web Site Optimization. Then put it all together to create Bulletproof Web Design : Improving flexibility and protecting against worst-case scenarios with XHTML and CSS. But you’re not done yet! Help people find your site by giving it Search Engine Visibility.
Really Good References
While you’re doing all these things, don’t be afraid to let curiosity get the better of you. Expand upon the projects in the previous books by doing things differently, doing things your own way. As you tinker, you’ll come across situations in which you don’t know how to do something. For those situations, use the following must-have references to quickly look up information about a particular technology.
For (X)HTML: HTML & XHTML: The Definitive Guide, Fifth Edition
For CSS: Cascading Style Sheets: The Definitive Guide, 2nd Edition and CSS Cookbook
For JavaScript: JavaScript Definitive Guide
Helpful Bonus Books
Read The JavaScript Anthology : 101 Essential Tips, Tricks & Hacks to learn even more about what you can do with JavaScript and how to solve real-world problems with DHTML. Get more usability insight from Homepage Usability: 50 Websites Deconstructed and Don’t Make Me Think : A Common Sense Approach to Web Usability (2nd Edition). Arm yourself with an arsenal of Web Standards Solutions: The Markup and Style Handbook (Pioneering Series) to take on The Real Business of Web Design.
Learn all the Secrets of Successful Web Sites if you’re involved with larger-scale project management, or if you’re of the entrepeneurial bent, find out How to Start a Home-Based Web Design Business, 2nd (Home-Based Business Series) or How to Be a Successful Internet Consultant.
Relevancy Messages Catching On?
I wonder if my relevancy message tests will ever catch on. I already use them to great effect on my own sites, but I’ve yet to see them anywhere else on the web.
That said, I just ran a google search for “relevancy messages” and my PHP test page for dynamic relevancy messages came up in the first page as the ninth result. That’s pretty encouraging, considering there were 315,000 results.
I’d be very interested to hear from others who are using this technique, similar techniques, or are interested in implementing such usability enhancements on their own sites.
See more progress on: make my mark in web development
Update: Turns out, if you remove mentions of the word ‘ad’ from the previous search, my PHP test page jumps up to the sixth spot. Makes sense, since it’s mostly marketing folks who are interested in “increasing ad relevancy” and the like. Come to think of it, why can’t my technique be used to place ads? Now there’s a thought….
Using Good URL Design to Create a Breadcrumb Navigation System In PHP
One fundamental aspect of any good navigation system is a mechanism to let users know where they are in relation to the rest of the content. On the Web, one of the most popular and thoroughly studied ways to reflect this information is in a so-called breadcrumb navigation trail or bar. This navigation bar lists the categories and subcategories (or sections and subsections) of the page which the user is browsing.
(Quick-minded readers will be quick to point out that the term breadcrumb navigation trail, which originates from the Hansel and Gretel story, is not entirely accurate. In the story, Hansel and Gretel left a trail of breadcrumbs as they wandered through the forest so they could retrace their steps back home. On a web site, the breadcrumb navigation trail reflects the current page’s position in the site hierarchy, not the path the user has taken through the site.)
Defining the Requirements of Breadcrumb Navigation
When I started looking for ways to easily implement a breadcrumb navigation trail on my web site, I immediately saw the potential complexity of the project. The hierarchical navigation system needed to:
- Accurately reflect a page’s position in the hierarchical information architecture of the site and not the physical location of the page in my web server. (This is important for me because I’m constantly moving things around.)
- Present a nicely formatted label for each level of depth.
- Automatically adjust itself for new pages, so I would never have to deal with it when adding new sections to my site.
- Not require any “heavy” database or large application to use and scale.
Additionally, the module should:
- Produce semantic, valid HTML marked up as a list.
- Link all elements in the list to their appropriate page level.
- Not link the last level, which should display the current location of the user in the site. (We don’t need a link back to the same page we’re already on.)
Searching for Inspiration
The first thing I, like any good programmer, went to do was search for existing code. Unfortunately, there is an appallingly small amount of information on implementing breadcrumb navigation out there. Sure, they’ll tell you what it is and what it’s good for, even convince you why you should have it, but as for actually implementing it goes…sorry, you’re on your own.
Every tutorial I found on the matter was decidely sub-par or completely failed to meet my requirements, listed above. Most sites stated the need for databases to create truly scalable and customizeable breadcrumb trails. Of course, nothing can compete with a fully integrated RDBMS solution, but with intelligent information architecture you can come pretty darn close.
Using the URL to Our Advantage
Thankfully, there is already a system of hierarchical navigation readily available to us. In fact, there are two!
- Directory trees on your web server. The folders in which your files are stored are probably already sorted somewhat logically and categorically.
- The URL of the requested page. The address bar in your browser drills down through these categories to get to the final page.
Both of these systems provide a basis from which we can draw upon to create a simple, self-organizing breadcrumb navigation system on a web site of almost any size. However, there are a few problems with the first method. (If you want to implement that method anyway, here’s a tutorial based around using a directory tree.)
- It doesn’t scale. If you’ve got a huge web site, you’re not going to keep all that data on static files on your web server. It would also be a full-time job to categorize and sort that content on said server! Oi, vey!
- It’s dependant on your organization system. If you’re anything like me, you don’t necessarily have folders within folders within folders just to store files, and if you do, you probably change them around pretty often to suit your needs. Unfortunately, basing breadcrumb navigation on your view of your information as opposed to your visitor’s view of the same information is a recipe for disaster in all but the smallest web sites.
Thus, the only remaining solution was to rope the URL of the page into service to serve as the basis for a breadcrumb navigation system. Even so, there is one huge obstacle to overcome with this method. The URL itself must not be attached to a physical filesystem on the web server.
Otherwise, we’re just basically using the filesystem hierarchy, which we’ve already seen is not adequete for our needs. So we need a way to abstract, or detach, the URL from the filesystem itself. Enter mod_rewrite, stage left.
Abstracting the URL from the Filesystem
Abstracting the URL from the filesystem is the critical step to enabling truly scalable, self-organizing breadcrumb navigation using such a simple foundation. This is essential because the URL of your page is the thing that will always be live; if the URL changes, so has your page! This change will then be reflected automatically in the breadcrumb navigation trail.
There are a number of other benefits to abstracting the URL of a page away from the physical filesystem it represents. I’ve even talked about some of them before when I blogged about playing with Apache and when I suggested tips for improving search engine rankings of CMS-generated content.
The basic prerequisite for a good URL schema, however, is solid information architecture. This means having a well-defined and clear structure to your site so information is easily findable and properly labelled, categorized, and placed within the system you use. Only after you create a sound URL design schema free of any unsightly cruft which succinctly encodes the hierarchy of your site will you be able to leverage them to their fullest potential. (Phew, that was a mouthful!)
So, since this is not a post about URI design (see these resources for articles on that), let’s assume you’ve done all that and are ready to implement your schema. The tools you’ll need are:
- The Apache web server.
- Its
mod_rewritemodule. - Access to the server configuration file or the ability to use
.htaccessfiles. - Later on, you’ll also need PHP, for the coding thing.
To make things simple, I’ll use my site as an example.
For my own site, I have several sections (“About,” “Services,” “News & Weblog,” etc.) and several top level pages that stand on their own (“Home,” “Contact”). Additionally, each section has an index page to ensure that no hierarchical level of my site is without its corresponding landing page.
This was going to be represented with straight-forward URLs that looked like this:
- The “Home” page would have this URL:
http://www.maymay.net/maymaymedia/ - So-called “top-level” pages would look like this:
- For the “Contact” page:
http://www.maymay.net/maymaymedia/contact/ - For the “About Us” page:
http://www.maymay.net/maymaymedia/about/ - For the “Services” page:
http://www.maymay.net/maymaymedia/services/
- For the “Contact” page:
- Second-level pages would have URLs such as these:
- For each service:
- http://www.maymay.net/maymaymedia/services/web-programming/
- http://www.maymay.net/maymaymedia/services/web-accessibility/
- http://www.maymay.net/maymaymedia/services/web-site-optimization/
- For each “About” page, for instance:
- http://www.maymay.net/maymaymedia/about/accessibility/
- http://www.maymay.net/maymaymedia/about/philosophy/
- http://www.maymay.net/maymaymedia/about/technology/
- For each service:
My files are stored pretty simply on my web server. Some pages, like the “Contact” page are stored in the maymaymedia directory but not in their own sub-directory. Other pages, like the “Services” and “About” pages, are stored in the services and about directories, respectively
This created filenames like maymaymedia/contact.php and maymaymedia/about/index.php. That .php stuff had to go!
Writing Your .htaccess File
Using the magic of mod_rewrite, a few relatively simple lines added to your .htaccess file is all it takes to turn these filenames into these beautiful cruft-free URLs.
Creating the sections was easy enough. Some of the work was already done by keeping the pages in their own directory (such as “Services,” for me) so I didn’t even have to do anything. Of course, to be safe, I could future-proof my site to abstract these directory trees using additional lines in my .htaccess file, but for the sake of simplicty we’ll leave it as is.
Here are a few relevant snippets from my .htaccess file:
RewriteEngine On RewriteBase /maymaymedia/ […] RewriteRule ^about/technology/?$ /maymaymedia/about/tech.php RewriteRule ^about/philosophy/?$ /maymaymedia/about/philosophy.php RewriteRule ^about/accessibility/?$ /maymaymedia/about/access.php […] RewriteRule ^services?/web-site-optimization/?$ /maymaymedia/services/wso.php RewriteRule ^services?/web-programming/?$ /maymaymedia/services/webprogramming.php RewriteRule ^services?/web-accessibility/?$ /maymaymedia/services/accessconsult.php […] RewriteRule ^contact/?$ /maymaymedia/contact.php
These merely map simple URL’s onto the appropriate files for the specific page on my server, creating the nice breadcrumb-like URI structure we can now use to automate the process of generating our hierarchical navigation bar.
There are two main points to keep in mind when creating such URL schemes.
- Use a standardized syntax.
Don’t mix and match symbols. Choose one syntax and stick with it. I used a hyphen (-) to simulate spaces, since spaces are not allowed in URIs. You could also use the underscore (_) if you wanted, but hyphens don’t require users to press the shift key.
- Make the URL descriptive.
Since we’re going to be using these URLs as our breadcrumb navigation labels, they need to be as descriptive as possible. Keep them short enough to easily type but long enough to provide context. For instance, I could have used
wsoinstead ofweb-site-optimizationbut how many people know that that’s what WSO stands for?Besides, including the whole phrase boosts our search engine rankings by embedding our keywords into the URL itself! A nice bonus which also enhances usability.
If you’re really worried about optimizations (for instance, because you’ll have to write all your links like
href="/services/web-site-optimization/") then you can use a redirection script and point your links at something likehref="/r/wso/"which would then automatically redirect to the expanded URL.
Coding the PHP Breadcrumb Navigation Bar
Now we’re ready to leverage the inherent advantages of good URL design to create our scalable PHP breadcrumb navigation script. I use a special PHP script called navbar.php to dynamically generate all of my navigation, so that’s where the code will go. navbar.php can then be SSI‘ed or include()‘ed on our page template so it will be present in all the pages we create from here on out.
The breadcrumb navigation script needs to do a few things. The code flow looks like this:
- Grab the requested URI and break it into its path components.
- Initialize (or remove) the first (“top”) element.
- Count the remaining elements.
- Check for trailing slashes on the last element, and remove it if necessary (such as if its empty or it’s just a query string).
- Loop through all the elements, placing them within
<li></li>HTML elements as well as<a></a>if we are not at the last level.
Stepping Through the Code
First, we start our HTML by providing a header (which we can later set to display:none; in our CSS) and starting the list element. Due to the specific nature of my site structure (the site starts in a sub-directory of my main site), I also chose to always print the main “Maymay Media Home” link. You don’t have to do this.
<h3>Hierarchical Navigation</h3> <ul id="hier-nav"> <li id="hier-homeLnk"><a href="/maymaymedia/" title="Maymay Media Home">Maymay Media</a></li>
Next, we start the PHP magic, grab the URI the browser requested and break it on the slashes with explode().
<?php
$url_parts = explode('/', $_SERVER['REQUEST_URI']);
Now the $url_parts variable contains an array, each element of which is a segment of the path from the requested URI. Since a URI request always starts with a leading /, the first element of our $url_parts variable is an empty string. That’s somewhat useless for us, so we’ll get rid of it.
array_shift($url_parts); // first item always empty in URLs
In my particular case, the second element will always correspond to the maymaymedia sub-directory I have my site in. Thus, the second element of this array is also useless to me, since I chose to always print this “top level” link before we even started the conditional code. Thus, I get rid of the second element, too. (You may not want to do this in your script!)
array_shift($url_parts); // second item unneeded since always contains "maymaymedia" due to my site structure
Now we need to count how many elements are left in our array which will tell us how many list items we need to make and where to find the end of our array so we can identify the last element. Remember, we’re going to need to check if the last element is empty or not because we don’t know if the visitor entered a trailing slash in the address bar.
If the last element is empty like the first one then we don’t need it. We also don’t need it if all it contains is a query string, so in either case we can pop it off the end of our array and decrement the variable we use to store the size of our array.
$num_parts = count($url_parts);
// remove last element if empty or if a query string
if (empty($url_parts[$num_parts-1]) || $url_parts[$num_parts-1] == '?'.$_SERVER['QUERY_STRING'])
{
array_pop($url_parts);
$num_parts--; // decrement to keep track
}
Now we have all the data we need to construct our breadcrumb navigation list. The first step is to start the second list item and insert a separator (I chose a “>” character), and then to format our URL strings into a more human-readable format. Basically, that just means replacing all of the “-” characters with spaces, and then capitalizing the first character of all the resulting words.
for ($i=0; $i<$num_parts; $i++)
{
echo '<li> > ';
$p = ucwords(str_replace('-', ' ', $url_parts[$i])); // format 'things-like-this' to 'Things Like This'
(Of course, advanced CSS coders will note that inserting a physical character in the HTML markup is unnecessary since we can use a CSS rule such as #hier-nav li:before { content: ">"; } to create this presentational separator instead. Unfortunately, Internet Explorer does not support this level of CSS yet, so we must resign ourselves to use a physical character in the markup for now.)
Then we make a quick check to ensure we’re not at the end of the trail. If indeed we’re not, then we need to turn our text into a link and point it to go to the appropriate level. Otherwise, since we’re at the end of the trail, we just print the text and end our list item.
Creating the link looks complicated, but it’s really not. Our array stores all the path components for us, so all we need to do is slice off the end of it so all that remains is the first elements we’ve already looped through.
Once we’ve done that, we merely reassemble our URL by reversing the formatting process we used before. Namely, we implode() our array to turn it into a single string connected with the slashes, replace all spaces with dashes (-), and then turn the whole thing lowercase. We can do all of it on one line.
Also note that due to my particular site structure I’ve hard-coded the links to point to the root directory of this site. You’ll probably want to remove that on your own script.
// only link if not last time through loop
if ($i != ($num_parts-1) )
{
echo "<a href=\"/maymaymedia/".strtolower(str_replace(' ', '-', implode('/', array_slice($url_parts, 0, $i+1))))."/\" title=\"Go up to $p\">$p</a></li>";
}
else // last time through loop, so don't do the link
{
echo "$p</li>";
}
}
?>
</ul>
That’s it! After closing our list element, we’re done, and we now have scalable breadcrumb navigation based on an intelligent URI schema on every single page. Was it good for you too?
Additional URI Design Resources
(Some segments shamelessly swiped for my own easy reference from Pixelcharmer.)
A list of resources that argue for and suggest best practices in URI construction.
- The User Interface of URLs (Paul E. Hoffman, 1995)
- Cool URI’s Don’t Change (Tim Berners-Lee, 1998)
- URL’s as UI (Jakob Nielsen, 1999)
- URL’s URL’s URL’s (Bill Humphries, 2000)
- How to Succeed with URL’s (Till Quack, 2001)
- Making URLs accessible (Peter Seebach, 2001)
- User-Centered URL Design (Jesse James Garrett, 2002)
- Designing URIs (2003)
- In German: Usability Inside | URL-Design (January, 2004)
By the way, here’s the difference between the two: What is a URL? What is a URI?
Targetting Relevance in Long Web Pages with the CSS :target Pseudo-Class
The Importance of Context and Relevance
Context and relevance are two of the most important aspects of effective communication. If the context of a message is not understood then the commuication will likely be disregarded, or worse—misinterpreted. If the message isn’t relevant to the topic at hand then it will be useless to everybody involved.
In order to ensure that a message is successfully received and has the desired effect, one must first ensure that the context for that message is properly set up and that the message itself is relevant to the subject matter.
An excellent example of a scenario where a loss of context and/or relevance can easily cause communication problems is receiving email messages. Surely everyone has recieved an email that they simply don’t know what to do with or why they’ve gotten it. (By the way, for some unbelievably insightful tips on composing effective email messages, read this article [via 43 Folders].)
The same thing can—and does—happen on the web. For example, let’s say you’re reading a page which has a link in its text to another page. You decide to follow the link but once you’ve arrived at the new page you find yourself staring at an enormous amount of other text that doesn’t have anything to do with why you followed the link in the first place. Suddenly you’re confused, you feel lost, and you quickly push the “Back” button of your browser.
What went wrong here? Context was lost; the destination page had no relevance to the source page. If it did, you couldn’t find it because it wasn’t clearly identified. This is a confusing and frustrating situation, and one that I’m willing to bet happens way too often on the web.
On my own blog, I frequently link to entries I’ve previously written. Sometimes these entries can be quite long, and I’m not always referencing the entire entry in my link. But by pointing the link to a specific “intra-page” anchor by using a fragment identifier and clearly marking the relevance of this information in both the link itself (with a descriptive title) and in the landing page (with what I’ve come to call a relevancy message), context is preserved and confusion is eliminated.
To see what I’m talking about in practice, check out my experiment pages. It’s a demo of the problem and relevancy messages in action.
CSS2 The Rescue
There’s only one problem left. How does one insert text into the landing page which will be viewable when someone follows a specially-crafted link to it, but not when they arrive at the page via any other link? Though it is possible to program this into your pages using PHP or another web scripting language, CSS level 2 offers a much simpler and maintainable solution: the :target and :before pseudo-classes.
When used in combination, the :target and :before pseudo-classes can be used to generate text on a page at a specific point in the document when your page is linked to in a certain way. By using an additional CSS2 function, attr(), we can also generate customized text for each landing spot within the document. Let’s take a look at each component separately.
The HTML You’ll Need
Let’s say you’re writing about apples. In your text, you link to a previous article you wrote about oranges. Your link in the article on apples might look like this:
<a href="oranges.html" title="Oranges have a thick, white pith beneath their skin." >oranges</a>
And your text in the article on oranges might look like this:
<p>[…] The skin of an orange is thick, porous, and varies in color from deep to light orange. There is a bitter-tasting white pith underneath the outter-most layer of the fruit's skin. […]</p>
In order to link directly to the paragraph mentioning the orange’s pith you need to insert a named anchor just after the opening paragraph tag where that content was written. You also need to append this name to the URI of the link, as a fragment identifier. The resulting HTML for the link might look like this:
<a href="oranges.html#skin" title="Oranges have a thick, white pith beneath their skin." >oranges</a>
The resulting HTML for the paragraph about oranges might look like this:
<p><a id="skin"></a>The skin of an orange is thick, porous, and varies in color from deep to light orange. There is a bitter-tasting pith underneath the outter-most layer of the fruit's skin.</p>
The CSS You’ll Need
Once the HTML is in place, you need to create a style rule to generate the text you’ll want to display before the paragraph. Your style sheet might look like this:
a:target::before { content: "Here's what I referenced with my link on the last page: "; font-size: larger; font-weight: bold; }
You can even take it one step further. By adding a title attribute with some helpful text in your named anchor, you can actually display that text (specific to the reference you’re making) instead of the generic “Here’s what I referenced…” text. The CSS for that would look like this, and it would display whatever you write as the title for each named anchor you use:
a:target::before { content: attr(title); }
Limitations
The major drawback to this technique is that you need to change the code of the destination document for it to work. Specifically, you need to insert named anchors (though you can also target any element by giving it an unique id), and you need to insert a style rule. (However, see below for another experiment that will let site owners allow people to get around this limitation.)
Another major drawback is that it requires a fully CSS2-compliant browser. That means Internet Explorer 5 and 6 (both Macintosh and Windows versions) will not show the special content on the destination page. They will, however, move focus to the point in the document at which the anchor resides.
Looking to the Future
I have been playing with this technique recently on my blog (can you find the links I’ve used this on? ;). The obvious benefit is creating a far more seamless transition from one page to another and maintaining the same context across web pages. This is invaluable for me and my readers in particular, since I tend to enjoy writing and end up writing far longer entries than I probably should. (Even though I use headings to divide my entries into logical chunks, it’s still good to have another trick up my sleeve to help usability!)
However, this technique is ripe for expansion. For instance, I have created another experiment to dynamically generate the content of the CSS rule based upon a variable in a GET querystring. (It uses three lines of PHP, and that link itself is a proof-of-concept.) This will allow people to write links that point to my documents and insert their own special relevance-describing blurbs in front of the fragment they’ve linked to. (Yes, I realize this may pose XSS security problems, I’m still just playing with the concept.)
Exploring all of this is a lot of fun. The crux of this technique relies upon accessible and clever hypertext copywriting to enhance usability when linking to web pages and referencing information across pages or, one day, sites. As is the case with most things Web, simple is better.
I’m very eager to hear about comments on this technique. Are there dangers I haven’t seen yet? Can you think of another way to use it that I haven’t mentioned here? Are you already using it on your own site? All feedback welcome. :)
Who Actually Clicks Click Here?
- Remove Product Confirmation Web Dialogue
- Originally uploaded by maymaym.
- Added to the photostream on 26 Feb ‘05, 3.29pm PST.
I have been experimenting with my coffee purchases as of late and found myself changing some of my Gevalia shipments around. After removing a product from my delivery list, I was asked to confirm the action. I was also given the choice to restore the product or add a new product.
Curiously, they used the hypertext copy …to add a new product click click here
, with the last two words made into a link to the product-adding page. This is the epitomy of the so-called “click here” mentality, where the very phrase “click here” has been so objectified that it is used as a noun unto itself.
To make matters worse, there was no title attribute for the link which may have served to mitigate the uselessness of the instructions. Adding to the confusion is the fact that the clearer instruction on how to restore the product was not a link. Instead, that button is way over on the other side of the page.
So, the morale of the story is that nobody’s actually going to click a “click here” link the first time around. They first have to decipher what it will actually do and sometimes that’s even more confusing than it was in this example.
Instead of such meaningless anchor text, it is always better to turn the verbs of a sentence into a link. In this case, I would have said something like “The product will no longer be sent with your future shipments. You can still restore this product if you’d like to continue receiving it, or you can add a new product instead,” with the emphasized text being the links for the respective actions. For extra credit, change “The product” into the actual name of the product I’ve just removed.
Clear, unambiguous, and personable text that’s easy to read with just a quick glance. That’s what hypertext copywriting is all about. More to the point, I gaurantee you that more folks would actually order additional products that way, too.
Attention-Starvation Economy
It is a shame that there is only 24 hours in the day. I figure I need at least 8 hours of sleep per night (on average, anyway) and that leaves only 16 left for web-surfing if I did nothing else at all. Of course, that’s unrealistic, so the real estimate I give it is more like 6 hours a day—and I’m a web-aholic!
Most of the time I spend surfing the web is actually done within my newsreader. My subscription list contains several hundred news sources of interest from around the web, and so it’s no wonder that I’ve been having trouble keeping it up with it all. The other day I finally got around to reclassifying that gargantuan list into a more palpatable format, very reminiscent of Jeffrey Veen’s “happy little folders” with categories ranging from “Must Read” to “Missable.” Now I don’t feel so bad if I can’t get to 90% of the items on my reading list this century.
Today, as I was reading Joe Clark’s Zoom-Layout article on A List Apart, a notification of new posted items in some of my feeds took my attention away from Joe’s article and momentarily had me contemplating whether or not I should abandon it in favor of the new item.
Now, Joe, you’ll be glad to know that I resisted the temptation and finished reading your article (as well as some of the discussion), but that moment of hesitation has really got me thinking. There are all sorts of various notifications popping up on screen at any given time, and there are simply so many bits of information that one can be alerted to. It’s no wonder the webbed world has gotten as impatient as it has.
If the content of Joe’s article had not been as engaging and interesting as it was, I may have clicked on the notification and never returned to finish it. The implications of this attention-starvation economy for a business site is quite frightening. Moreover, business folk are doubtlessly unfamiliar with this form of competition.
If A List Apart had been a printed magazine, I would have been flipping through pages as I read Joe’s article on my sofa, instead of at my computer desk on my laptop’s screen. The motivation for getting up—whether for another magazine or a cup of coffee—is relatively small, at least until I had finished the article. But on the web, competing content is so utterly easy to access that the motivation for going to it increases exponentially as the quality of the current content the user is exposed to decreases.
Or in other words, this is why usability is getting to be big business, or at least should if e-commerce companies know what’s good for them. Not that this is any form of groundbreaking discovery, but it has never hit me so plainly as it has today. And I’m a big advocate of experiencial learning.
Fun with Apache Redirects
I absolutely love Apache. A while ago I ranted about the annoying prevalence of uneccessary redirects some sites make you click through. This topic comes up pretty often even today, although the issue of annoying HTTP “404 Not Found” errors has been mitigated somewhat by people wising up and creating helpful error pages. (Which I’ve been meaning to revise and improve on this site.)
Usually, the existene of broken links and the like is brushed off by saying something like, “We are undergoing a re-organization period,” usually followed by a request to “please bear with us” for the duration of said period.
Well, I know a thing or two about organization. In fact, I probably know more than most because I re-organize my my desk, my computer, my Web site, and even my refridgerator fairly frequently. As Danica will no doubt tell you, I like to make sure I am keeping things as effecient as possible.
In terms of serving up web pages to visitors, it means that I can reorganize and restructure my site as much as I’d like and you wouldn’t even know that I did it. The main tools I use for this are Apache’s Redirect directive (implemented via mod_alias) and the various, insanely powerful features offered by mod_rewrite (documentation). I’ve used these tools several times while working on this site but none of these examples even scratch the surface of what is possible.
-
While moving the site from Blogger to WordPress, I also decided to change the blog’s address so that I had a shorter URL, devoid of any hint of the old site. Naturally, since I didn’t want to break incoming links, I used a
Redirectto bounce visitors to the right address. Additionally, I tagged the redirect with the keywordpermanentwhich emits a “301 Moved Permanently” HTTP response header so that decent clients will no longer request the old resource’s address. The full line in my.htaccessfile looks like thisRedirect permanent /bpd/blog/ http://www.maymay.net/blog/
although I could have written it with the status code instead of the keyword like this:
Redirect 301 /bpd/blog/ http://www.maymay.net/blog/
-
At the same time, I also decided to give some common aliases to the
/bpdsubdirectory, so I started redirecting requests for things like/bipolardisorderto/bpdas well. -
I wanted to make a few “static pages” such as the About Meitar page, but I wanted a cruft-free URL for them as well. The simple solution was to start Apache’s mod_rewrite and map a nice-looking URL to the file I wanted to serve.
# turn mod_rewrite on RewriteEngine on # restrict the following rule to /bpd/ RewriteBase /bpd/ # set /meitar or /meitar/ to meitar.php (or similar) RewriteRule ^/meitar/?$ meitar.php
Most recently, I was asked if there is some way Apache could automatically “redirect HTTP to HTTPS” transparently. Sure enough, this is a piece of cake:
RewriteEngine on
# is request not on HTTPS?
RewriteCond %{HTTPS} !=on
# if so, redirect it (the [R] flag) and stop processing (the [L] flag)
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]










