If it works like email, usability is not a problem

Don't assume that users of your applications know too much about how to use it. With every new application, users pass through a learning phase that can be painful sometimes, especially if your application usability was not tested by an average user.

However, there is an assumption that you can always make about your users: they know how to use email. If your application looks a lot like an email client, you can be confident that users won't have usability problems with it.

I tried to mimic a mail client a lot while designing the administration interface of the sfBlogs application. I know of two other applications that follow exactly the same path:

MarsEdit is an OSX only application to edit and post content to your blogs. It's snappy, easy to use, and it looks just like Mail, Apple's default mail client on the Mac. If you're tired of the browser, MarsEdit is a great way to edit your blog offline with a familiar interface.

Marsedit

Multiply is a media sharing web application designed to "make it easy to create, share and discuss your blog, photos, and videos with more of the people you know, and fewer of the people you don't." It looks just like what sfBlogs would be if I had enough time and skill.

Multiplyshot

If you wonder how to design your next web application, think about a mail client. It might save you months of usability mistakes.

White Lines Make Separator Lines Stand Out

I seldom have a good graphical designer aside to give time for a free project. I have to do most of the designs for open-source projects I work on myself. Unfortunately, I'm really bad at graphical tasks, and I admire those who can imagine creative designs on their own. So I try to get a few insights from designs I like. One of the lessons I've learnt is to avoid separating zones with a single line of color. It makes the design flat and sad. Here is a screenshot from the sfBlogs application where separators are single lines of grey:

2009-05-14_1335

With an additional white line sticked to each separator, the whole zoning becomes much less schematic, and more finished. The single pixel is almost invisible for the human eye, yet it has a polishing effect that I've always loved.

White_lines

One thing that astounds me is that Google never uses this trick. Their designs use plain borders or backgrounds, and avoid this kind of eye candy. I love their web applications but really, they are hard to the eye.
 
Now does a more polished design offer a better usability ?

Use Overlay Badges

One thing that desktop applications have and that web applications don't use very much is the overlay badge. It's a piece of content overlapping some part of an icon. For instance, the OSX Dock uses red badges to display the number of unread emails:

2009-05-12_1720

You don't need to actually open the mail client to see if you have new messages. A look at the dock is enough, and the dock is always visible.
 
You can't write much in a badge - or else, it overlaps an important part of the screen, and hides the background content. But numbers require few characters, and can be displayed in badges quite easily. Apple reused the badges in the iPhone OS interface: every application can display a number of 'new' or 'unread' items in a badge on the top right corner of its icon.

2009-05-12_1726

A web application can take advantage of the same technique to show a number of items requiring attention on top of an icon, or on top of a tab. That's what I decided to do for the sfBlogs application, by adding the number of draft posts in a badge pinned to the top right corner of the "Posts" tab, and the number of comments yet to moderate on the top right corner of the "Comments" tab:

2009-05-12_1701

Those are not intrusive, require only CSS to be properly rendered, and carry little pieces of important information that an editor needs to be aware of at all times.
 
Few application developers spend time on the design of the administration interface of their applications. It's often the last thing to work on, and there is never time for it. The result is that administration interfaces still look almost the same as five years ago, with clearly separated zones, and not much attention paid to the positioning of elements. So break free of the square design of web applications, and don't hesitate to use overlay techniques when it makes sense.

Use A Timeline As Your Homepage

While designing the sfBlogs application, I wondered which panel should be displayed as the first page of the administration interface. The administration allows editors to add or review blog posts, to moderate comments, to create news blogs and invite other contributors. All the events occurring in any of these categories (a new post from a fellow contributor, a new comment on a post you've written, a change in the description of a blog you're following, etc.) can be of equal interest when an editor logs in the administration. In fact, because it is a multiple blog engine, the administration should emphasize on the contributions of people working on the same blogs as the editor. That's why I chose to display a timeline.

Most of the successful "social" web applications feature a list of recent events as their home page. For instance, think about Twitter or Facebook and their 'news feed'. They both display what the people you're following have been doing recently, so that you can keep in touch with them. Trac does a similar thing but relative to a project, not a group of people. In Trac, the 'news feed' is called a 'timeline' but that's basically the same thing.

Why are timelines so popular? Timelines show all the news that you've 'received' from any person or group you're following. In a single line of text, you know when an event occurred, who the event concerns, and what the event is about. This should remind you of the most popular desktop application ever used (save the internet browser): the email client. The user interface of a timeline feels so natural because it is very similar to the standard way of dealing with the messages that you receive. Timelines deal with events as if they were messages addressed to you.

There is a little more to timelines than an anti-chronological list of one-line events. Timelines aggregate in a similar fashion events of various nature, so that you can read the whole timeline without being disturbed by an odd-looking event. To put it differently, timelines organize pieces of content that would be difficult to read all in a row into a natural, flowing interface.

sfBlogs is designed to allow multiple blogs per user, and multiple users per blog. I believe that seeing other people publish posts is a strong motivation to write something yourself. So a multiple blog engine must have a minimal "social layer" built in, to show what other bloggers are doing. The timeline is a perfect answer to that need.

2009-05-11_1203

As I implemented the code necessary to record and display events on a timeline, I had to settle down a few business rules. For instance, what should a "new comment" event look like, and who should see it in their timeline? I decided that a comment event should show the comment author, the first words of the comment text, offer a link to the comment moderation, and another link to the post the comment is on. If the comment is not yet approved, the event should display a "please moderate" prefix. A comment event should appear in an editor's timeline if the comment is published on a post written by the editor, or in a blog owned by the editor.

All the events have their own logic, and little by little the choices I made to keep the timeline small and meaningful started to turn a multiple blog engine into a social publishing tool. Any event displayed in an editor's timeline makes it easier to collaborate on a blog, or to take inspiration from someone else's blog. So my conclusion is this: A backend administration interface open to more than one user should display a timeline as its home page.

Incidentally, I had to develop a dedicated symfony component for dealing with events and a timeline, in an internationalized context. I believe that component could be reused outside of the sfBlogs application. Take a look at the source code and feel free to comment or reuse it for your own timelines...

Forms Are Evil #2: Validation

Developing a robust and usable form is a real challenge. Frameworks provide tools for that, and it eases the pain a little bit, but I still think that forms remain a bad experience for both the developer and the user. And one of the reasons is the need to validate the user input.

In a classical web form, the user enters data, submits the form, and then the server validates the data. It something is wrong, the form is displayed again, with the data originally entered still present, and with error messages showing the problems. For a form designed to edit a bug in a bug tracker, this could look like the following (thanks to Wufoo for the design):

2009-04-29_1524

Usability-wise, I find this frustrating because:

 - The user must fill the whole form before knowing that something is wrong
 - The design of error messages needs to be aggressive, in order to draw the attention of the user to the error messages, because it's the same page that displays again after submission
 - The validation is iterative (If I start by entering an empty title, I'll have a first error message saying that the title is required), and that often results in the need to submit the form several times
 - Some form controls lose the data entered by the user between two submissions (captcha inputs, password inputs), so these must be entered again and again)
 - If the form is below the "fold", the user must scroll down to see the problems 
 - For long forms, even if there is one small mistake, the user must still review the whole form and scroll way down since the submit button is at the bottom of the form

One good way to overcome all these shortcomings is to use JavaScript on the client-side to do the validation before submitting the data to the server. Not all the data validation can be executed on the client-side though. For instance, a captcha, or a username with a unique index all require a server validation. But then Ajax can come to the rescue to show validation in real time. A web form doing real-time data validation fells more like a desktop application, and provides a better user experience. 

Speaking of desktop applications, they usually don't bother to display a summary of errors on top of the form, and a detail of each error below each form input, a in the screenshot above. Most of the time, when there is a problem with data validation in a desktop application, you can either not submit the form at all, or an alert window mentions the problem before you submit it. And that is enough, because you just left the faulty control, so the application doesn't need to say more. Here is how Gmail, that tries hard to look like a desktop application, validates an email:

2009-04-29_1606

Desktop applications also succeed better than web applications at dealing with incomplete input. For instance, imagine that you submit a form for editing a post in a blog engine without title. In a web application, you would usually get an alert saying that the post title is required. But is it really required? If the title is required for technical reasons but the user didn't give one, the program can probably create one on its own (like "Untitled"), and that makes the process of writing a post less painful. Desktop applications can also save incomplete form data as drafts. The validation only occurs when you actually submit the data. For instance, in a mail client, you can enter an incorrect email address to the recipients field and save the message for later. Only if you send the message as it is will you get an error message from your SMTP server.

I tried to apply these principles to the administration interface of the sfBlogs application. Adding a post to a blog requires no validation. Note that there are not many 'open' controls, and that the interface prefers to ask the user to choose from a list rather than type text in an open text input.

2009-04-29_1555

Let's get back to validation. Realtime client-side validation provides a better user experience than server-side validation. But, on the other hand, server-side validation is still necessary because:

 a) you must protect your system from corrupted data submitted without the form (a.k.a. hack attempt)
 b) you must provide an alternative for browsers not supporting JavaScript

I'll dismiss b) without any further explanation - it's 2009, and we are talking about usable applications.

But a) data security is a serious matter. So you actually have to validate input on the server side with the same rules as the ones you apply on the client side, in JavaScript. But you don't have to deal with redisplaying the form with nice error messages. A failed server-side validation necessarily means that the client-side validation was skipped, so the request is being hacked. In this case, just return an error code 500 and forget it.

And that's interesting because server-side validation doesn't have to deal with error messages and form refill anymore. That's one burden (and code duplication) off the developer's shoulders.

One step further. Data validation rules are shared between server and client side validation. To avoid code duplication, one solution would be to do all the data validation on the server side, but in Ajax. For that, you would need a lightweight controller with access to the form rules on the server side, that could return a validation status upon certain form events on the client side (change, blur, click on the submit button). An event-driven form validation framework, that would give the best user experience and the best developer experience, too. 

Now who wants to start writing this thing?

Introducing Code Usability

Usability guidelines can sometimes be of use in awkward places. I try to apply them to source code. 

The sfBlogs source code is published under an open-source license, and its main purpose is to be reused by other developers. Consider the source code as an interface, and developers as end-users of this interface. There, usability doesn't sound that awkward anymore, does it?

Of course, coding guidelines are there to make the code easy to read by everyone. But code usability goes somehow beyond. Let's see some of the differences.

Bad Code Comments

Documentation is sometimes overkill - provided that you name your classes and methods properly. For instance, code sample #1 is way shorter than code sample #2, but a developer can understand (and adapt) its code more easily.

    // code sample 1
    class sfBlogLogger
    {
      /**
       * Log a blog creation
       * @param sfBlog      $blog   The blog just created
       * @param sfGuardUser $author The user who created the blog
       */
      public static function create($blog, $author)
      {
        $log = new sfBlogLog();
        $log->setElements($author, $author, 'create_blog', $blog, 'New blog: "%object%"');
        $log->setObjectLink('sfBlogAdmin/blogEdit?id='.$blog->getId());
        $log->save();
      }
    }

    // code sample 2
    /**
     * myClass is there to log events happenning on a blog
     * I built this class because when I breate a blog, 
     * I want a new record to be created in the sfBlogLog model
     * So the class does it automatically, with static classes and all
     *
     * @author  me
     * @email   me@myaddress
     * @date    04/23/09
     *
     * @see sfBlogLog
     */
    class myClass
    {
      /**
       * Log a blog creation
       * This method creates an sfBlogLog object, asets is Elements based on the blog and author,
       * Sets the object link, and saves to the database
       *
       * Example:
       *   myClass::log1($b, $a)
       *
       * @param sfBlog      $b  The blog just created
       * @param sfGuardUser $a  The user who created the blog
       *
       * @author  me
       * @email   me@myaddress
       * @date    04/23/09
       *
       */
      public static function log1($b, $a)
      {
        $l = new sfBlogLog();
        // pass the author and the blog to the log object
        $l->setElements($a, $a, 'create_blog', $b, 'New blog: "%object%"');
        // set the link on the log object
        $l->setObjectLink('sfBlogAdmin/blogEdit?id='.$b->getId());
        // save to the database
        $l->save();
        // return nothing
      }
    }

With too many comment lines, a developer cannot see the whole class in the screen without scrolling, and that can be harmful to comprehension. Excess of comments is not as seldom as one might think. In fact, comments are often required to balance a poor code design or naming. Use the comments for what they are good for (code completion, non-trivial usage), and let the code speak by itself.

Split Up Code

Sometimes code smells bad. Experienced developers can recognize at first glance stinking pieces of code (too many indentation levels, too long files, too many method arguments, poor object-orientation, etc.). But making your code smell good is not enough to make it usable. For instance, breaking down a large file into smaller ones can make the code hard to read because it forces the developer to switch between files to get the whole picture. So you may need to keep a gentle scent to keep the code usable.

For instance, the new symfony routing system allows for very concise action methods:

    /**
     * Displays a list of blogs
     * Required request parameters:
     *   page       Page number (defauls to 1)
     */
    public function executeBlogs($request)
    {
      $this->blog_pager = $this->getRoute()->getObjectsPager(
        $request->getParameter('page', 1),
        sfConfig::get('app_sfBlogs_post_max_per_page', 5)
      );
    }

However, in order to get the big picture, you must look at the routing rule in the application's `routing.yml`:

    blogs:
      class:   DbFinderObjectsRoute
      options: { model: sfBlog, finder_methods: [recent] }
      url:     /blogs/all/*
      params:  { module: sfBlog, action: blogs }

I'm not sure that the two pieces of code above are more usable than this one:

    /**
     * Displays a list of blogs
     * Required request parameters:
     *   page       Page number (defauls to 1)
     */
    public function executeBlogs($request)
    {
      $this->blog_pager = DbFinder::from('sfBlog')->
        recent()->
        paginate(
          $request->getParameter('page', 1),
          sfConfig::get('app_sfBlogs_post_max_per_page', 5)
        );
    }

I have implemented a set of powerful routing objects in `DbFinder`, the Model requesting API I've been working on for quite some time now, but I'm not convinced that they make the code more usable.

Cleanliness

If a little code smell is sometimes better than a strict adherence to coding standards, keeping the code clean is compulsory to make it usable. Clean indentation, not too long lines, and coherent naming conventions, are necessary to avoid bad surprises for the developers who read your code.

New Conventions

If a convention exists for a particular task, you should use it, rather than introduce your own. Relying on existing knowledge eases the learning process, since there are less things to learn. "Do Not Reinvent The Wheel" is also a usability guideline.

When designing the DbFinder API, I tried to use as much as possible method names that would feel natural to developers with a basic SQL knowledge. The two following code snippets to the same thing, but the second one requires much less knowledge to be understood, and adapted.

    // With Propel Peer and Criteria
    $c = new Criteria()
    $c->add(ArticlePeer::TITLE, '%world', Criteria::LIKE);
    $c->add(ArticlePeer::IS_PUBLISHED, true);
    $c->addAscendingOrderByColumn(ArticlePeer::CREATED_AT);
    $articles = ArticlePeer::doSelectJoinCategory($c);

    // with DbFinder
    $articles = DbFinder::from('Article')->
      where('Title', 'like', '%world')->
      where('IsPublished', true)->
      orderBy('CreatedAt')->
      with('Category')->
      find();

Listen To User Feedback

Usability is not so much about a set of rules as it is about a way to constantly judge your work with the end user in mind. And the end user is not an abstract human being - at least, not after you release your product. Open source licenses favor user feedback, and that feedback is the precious ingredient you need to evolve towards a better usability. So a good rule of thumb for an open-source component that favors usability is to provide easy ways for developers to send feedback, feature requests or simple questions. It is also crucial to actually listen to the developers comments, and to take them into account for the future.

By the way, if you tested the sfBlogs plugin, please send me an email to tell me your impressions. Your feedback is really necessary for this experiment to go in the right direction.

Conclusion

I've barely scratched the concept of code usability in this post; if you want to know more, you can read a presentation I made a few months ago on the same subject: Developing For Developers.

sfBlogs screencast

I've recorded a small screencast to showcase the look and feel of the backend administration of the sfBlogs application. You may find it useful to understand the usability statements that I try to raise in this blog.

If you're interested in seeing the code, head to:
http://trac.symfony-project.org/browser/plugins/sfBlogsPlugin/trunk
For a ready-to-go demo app, or to:
http://code.google.com/p/sfblogs/
For the plugin code.

Pagination Controls

Web applications are full of lists of items, most of which are paginated. Pagination is compulsory to avoid long lists that would put both the server and the browser on their knees. But once you accept to limit the number of items displayed in a list, you must provide controls to browse through pages of items. Of course, there is one good way to do that, and google shows you the example:

2009-04-23_1102

The pagination controls offer a way to go to the first page, to the previous page, to the next page, and to some of the surrounding pages. They also indicate which page you're reading, and if you are not google (where the maximum number of pages is always 100), the pagination controls also display the number of pages and / or results. Here is another example from Google: the pagination controls proposed on top of email lists in Gmail.

Pastedgraphic

This set of controls is more concise, and offers only previous / next controls.

How would you design the pager controls for a blog home page? This home page displays the latest blog post titles and summaries. It's not exactly a list per se - meaning that each item takes more than a single line on the screen. A typical blog engine also offers a full-text search engine, archives and categories lists, so page navigation is not central. And since the emphasis of a blog home page should be on the content, the pagination controls should be reduced to the minimum, in order to reduce their visual impact on content.

Most blog engines display only two links at the bottom of a page. For instance, here is how Wordpress allows you to navigate page by page:
0pastedgraphic

TechCrunch uses a different vocabulary, but that's the same idea. One thing never changes: the previous page link shows a left arrow, and the next page link shows a right arrow. 

1pastedgraphic
Gone are the total number of posts, the total number of pages, and the index of the page you're currently viewing. After all, if you are on page 7 it means that you must have clicked the "older..." link six times, so you know where you are. Notice that there is no mention of the word "page". The controls point out to what you should expect expect when you click on them, and that's obviously a list of posts, not a page. 

There is one thing that disturbs me: if you ever arrive on a page that is not the first page (for instance coming from a search engine results page), nothing on the top of the page tells you that you are not viewing the first page. I'd prefer the "Newer..." link to be displayed on the top of the page, before the posts themselves. That's what I tried to do in the sfBlogs application frontend:

2009-04-23_1219

Web backends still use pagination controls a lot. For instance, this is how an administration module generated with symfony looks like:

2pastedgraphic

Now let's consider true lists of one line items, like the list of posts displayed in the sfBlogs application administration. As I pointed out in a previous post, fluid layouts are ideal for backend administrations, but they require the various zones of the screen to be resizable, and each zone needs its own scrollbar.

2009-04-23_1217


The purpose of this scrollbar is to display "more" items of the list - and that's exactly what the pagination controls are supposed to offer. So why add another control to do the same thing? The scrollbar IS the pagination control. In fact, you almost never find pagination controls in desktop applications. That's because they don't need to download a limited number of items at once over the internet, because the content is stored locally. So what if web applications used the same convention?

That's what Google Reader does: if you want more items, scroll down, and your browser will load more content into the item list. It's so natural that you don't even notice that Google Reader has no pagination control at all.

In an attempt to take the best from desktop applications usability, I did the same for the sfBlogs administration. Lists have no pagination controls, they use a custom autopager script based on jQuery and apply it to a DataGrid object implemented in symfony (for the server part) and jQuery (for the client part). Backend users never click on a pagination link, but the items load and display as they need it, without a click.

To conclude, let's try to understand why Google doesn't use the same technique on its own search engine (although plugins like CustomizeGoogle implement it in Firefox). I see several reasons:
  • Each new page displayed is the occasion to display new ad links. Even if 98% of the users stay on the first page, there is no reason not to get income from the following pages.
  • The Goooooogle pager is there since the first version of the Google search engine, and it's part of the Google brand. They simply can't get rid of it.
  • The Google First Page Of Results is extremely important for the SEO business, and companies spend a lot of money to appear on this page. 
If you don't need to fulfill these requirements, then consider using autopager scripts and getting rid of pager controls to improve your user experience in backend administrations.

Forms Are Evil #1: Filter Forms

In web applications, forms are a nightmare for the user, the project manager, and the developer. They are counterintuitive and error prone, they require a lot of work for submission, validation, and redisplay when the validation fails, and because of that they require a lot of specifications and tests.

(download)

Let's consider the forms commonly used to filter lists of results in backend administrations. The first screenshot shows a filter form used to filter a list of users. These forms are very handy to quickly reduce the number of items displayed in a list, but if you look closely they have several drawbacks:

  • They require a lot of manipulation. To fill in a text input, you must click inside the control, leave your mouse, type some text, and use the mouse again to jump to the next control or submit button. Dropdown lists are not much better: you must click once to open them, you must sometimes scroll in the list to find the item you want, and click on it to close the dropdown list. Option buttons are sometimes hard to click on - the label is not always clickable. And "rich" widgets (date pickers, rich text editors) often lack the final polish that makes a control truly usable. Filling in a form may look easy to you, but heavy users often drop form controls in favor of keyboard shortcuts, and unexperienced web users don't use them because they are scared.
  • "Open" fields (i.e. text inputs and textareas) are intimidating and prone to error. I know many people who dislike the keyboard a lot and make a lot of typing mistakes. Those people fly away as soon as they see a text field, because every time they use them, the forms displays again with an error message. Filter forms often display more than one text field - in fact, they provide one text field for every column you can search. Wildcards always use a different syntax ( `%` or `*` ?), they are sometimes implied and sometimes not, and logical keywords are most of the time unsupported but you never know. To sum up, each text field should come with a manual.
  • You must submit the whole form to see the results. So if you do progressive search, you must fill in one field, then submit, wait for the page to refresh, then fill in another one, then submit and wait again for the page to redisplay. If the server is slow, or if the filter form needs a scroll or a click to be revealed, that's painful. And the opposite strategy, to fill in every form fields and submit them all at once, often results with an empty list, and you must empty the fields one by one and submit the form again and again until you get what you want.
  • Form controls take a lot of visual real estate in the screen, and when you add in groups, separators, help messages, and error messages, the form displays so many visual elements that designers hide them by default. Users must click on a button to display the filter form, which adds another click to the list of actions required to use a filter form. 

There is one drastic solution to overcome these drawbacks: don't use a form to filter a list. In fact, most of the time, you don't need to. Look at Apple's Mail client for instance (the second screenshot attached to this post). You can browse your emails by date, folder, account, you can search in the message sender, title, content, cc, and yet there is not "form" filter so to speak.

So how can you replace your current filter form with alternative controls?

  • Start by grouping all the open text fields into a single one. It's not up to the user to choose in which "column" of your structured data a search should occur. It's up to the application. Apple's Mail client offers a single search field, and text typed in this field is searched in every text part of the (email) content. That search may return more results than several text fields restricted to a single content part, but most of the time the first result is the one the user looks for, so you don't mind returning more.
  • Remove the submit button and show results-as-you-type. This "spotlight"-like behavior has the advantage of removing one control (the submit button) and letting the user know when he has given enough information to find what he wants. It also allows the user to experiment with the search interface (testing AND / OR keywords for instance) without leaving the search field. Since a single search filed takes little space, you can put it always at the same place in every page without risking to clutter the screen. How about the top right of the window, where users usually look for it? Of course, you will have to do some Ajax to implement that, but good libraries doing this are everywhere.
  • Transform dropdown lists into lists of links. Think about the list of folders in the right side of mail client. It is much more convenient to use than a dropdown, because one click immediately refreshes the list to show only the items in that folder. You don't need to open the dropdown, choose the item, and validate the form. Also, the list of links can convey more information - like the number of results you can expect to see if you click on the link. All your dropdown lists should be grouped in a "filters" panel, and represented more or less as folders.
  • Some filter form controls may not easily be converted either to a single text field, or to a list of links. Take a date filter for instance. Traditionally, filter forms offer two date widgets to allow you to enter a time interval. Well, this can also be designed as a list of links. Take the most common time interval queries and make a list of them:
  • This week
  • This month
  • Last month
  • Before last month

Granted, you won't have the same accuracy as with two date widgets, but it will be overall much simpler to use. Think of this date widget "linkification" as the way Apple do interfaces, as compared top the way Microsoft do interfaces; Apple's way offers less control, but answers 80% of the needs immediately. If the user ever needs to find something by date and if the proposed filters are not enough, changing the list ordering or actually parsing it will lead her to the result anyway.

If some filter controls can't be easily turned into a list, maybe there is an alternative way. Think about a list of comments in a blog application for instance. A good filter for this list would be the post that the comment refers to. The problem is that, as the number of posts increases, displaying a link for each post will take much of the vertical space and force other filters down the 'scroll limit'. There is an alternative solution: don't offer to filter on one post in the comments list, but offer to link to the list of comments related to a post from the page showing the details of a post. The filter is indirect, but it works.

All in all, you should be able to remove filter forms altogether in most cases. For the administration interface of the sfBlogs application, I tried to follow these principles. There is only one search field to rule them all, and all the other filters are designed as list of links - check the last screenshot for glimpse of the UI.

Fixed content, fluid application

When you design a new project, the same question inevitably arises after the first few sketches: Should the design keep a fixed width, or should it take advantage of all the available window space and be "fluid"?

The answer often depends on the website purpose.

Content websites always use a fixed width layout, to tweak readability to the maximum and keep as much white space as possible. The following websites all offer a fixed width, because they focus on content:

Counterexamples: Google News, Wikipedia I've always found these two not very easy to read...

Web Applications try to behave as much as possible as desktop applications, where fixed width doesn't exist. Those applications tend to stack as much information as possible on the screen, and for that purpose you need all the screen real estate available. So exit the margins, the fixed width, and enter the fluid layout. Check the following web applications as an example:

To get a bit further, let's focus on scrollbars. Content websites try to keep only one vertical scrollbar on the right side of the window, while web applications don't mind to show several scrollbars. This allows for more complex relations between the pieces of data displayed on the screen, and that's what an application needs: to relate actions and information together, and to maximize the productivity.

Be aware that "fluid" must come with "customizable", because the information displayed in each of the zones of a fluid layout may be ùade unreadble when the screen is resized. So every zone in a fluid layout that displays dynamic content should be made resizable.

If that reminds you of the concept of frames, that's because it is exactly that. But frames break the navigation history and multiply the number of requests necessary to display a single page. Fortunately, frames can be simulated through JavaScript, and that's what libraries like Yahoo! UI Layout, or JQuery Splitter offer.

To sum up:

  • Maximize readability for content through a fixed layout
  • Maximize productivity on applications through a fluid layout
The sfBlogs application follows these principles: the frontend module focuses on displaying blog posts and comments, and offers a fixed width layout. The backend module is used to edit, moderate, and customize the blog engine and content, and it fits in a fluid layout with resizable zones.

By the way, if you want to test this sfBlogs thing, you can just checkout an example application from Google Code. Provided you have PHP5 and MySQL, it should take only five minutes to get it up and running.

Now the real question is: What if my website offers both long content and very interactive features ?

(download)