Practicing What I Preach

I mentioned yesterday that I’m working on some major product improvements. They’ve been a long time coming. I’m taking advantage of this situation to institute a design pattern library. Each UI element we design is being implemented as a plug-and-play component with modifier classes that handle different uses. As we go, we will document each component, explaining when and how it should be used. Every library entry will include a screenshot and an HTML snippet. More complex components will include multiple examples to illustrate different states and contexts. We’re doing this on our development wiki where all of the developers will be able to access it. Eventually, it will be possible to assemble entirely new screens in minutes by simply copying and pasting code out of our pattern library.

If you would like to learn how to do this for your company, consider attending my workshop at Midwest UX 2014.

Design Pattern: List Sorting

There are many subtleties to the behaviors of tabular lists. Following this checklist will ensure that your lists conform to de facto standards and meet users’ expectations.

  1. Specify a sensible default sort based on the content and purpose of the list.
  2. A visual indicator should communicate the column by which the list is sorted and the direction of the sort.
  3. Make sure that alpha-numeric sorts handle numbers and special characters appropriately.
  4. Make sure that dates and times are sorted as dates and times, rather than as strings.
  5. Sorting should be case-insensitive.
  6. Test to make sure that all sortable columns are sorting correctly.
  7. Test to make sure that reverse sorting is handled correctly.
  8. If other functions affect the sort, such as the addition and deletion of items, or the editing of data within the list, make sure that the integrity of the sort is maintained.
  9. Specify an appropriate secondary sort when necessary.
  10. Test to make sure that the sort direction is also applied to the secondary sort. In other words, when the primary sort is descending, the secondary sort should also be descending.

Design Pattern: List Item Buttons

Most of the applications I work on display lists of items, be they documents, pages, data sources, people, messages, or whatever. These items are typically actionable in some way. Years ago, the best way to handle this in a web browser was to place a button for each action with every item in the list. For example, there would be buttons for edit, delete, and send. The result was a lot of buttons on the screen, which was not ideal from the standpoint of the visual design, but allowed one-click access. Additionally, each list item would have a checkbox so that bulk operations could be performed.

As HTML and CSS became more robust, I started hiding the buttons and displaying them when the cursor would hover over the row. This got rid of the clutter while still allowing one-click access to the most important functions. However, I didn’t like the fact that there was no indication that the actions existed until a row was hovered over.

My solution, then, was to display a light gray outline of one button on each row. This, I felt, was enough of an indication that something was there while still avoiding the clutter.

Design Pattern: File Management, Part 3

The first post in this series described the typical, yet minimal, approach to file management within an application, which leaves most of it to the operating system. Yesterday’s post was about a hybrid pattern that sees the application providing convenience features for working with multiple files. In the third and final pattern, the application takes on all file management responsibilities.

Dreamweaver is a good example of the third model. To do what it does, it has to have an understanding of an entire site. What are all of the files that are part of the site? What is its directory structure? Which files are linked to what other files? It therefore provides a UI for managing and navigating the entirety of a site.

Dreamweaver has users create a “site” by giving it a name, filling out metadata, and picking a location in the OS file system. It considers the selected location to be the top level of the site hierarchy, and all descendants are part of the site. The Manage Sites dialog lists all of the sites that Dreamweaver is managing and allows the user to create new sites, edit the settings and metadata of existing sites, make duplicates of sites, remove sites (this doesn’t delete files from the file system—it just tells Dreamweaver to stop considering them to be a site that it is managing), export, and import sites.

Once a site has been created, it can be viewed in the File palette, which presents only the portion of the file system that is considered to be part of the site (i.e. from the selected directory down). The user may choose which site to view, but can only view one site at a time. Within the File palette, they can interact with the file system pretty much as they would through the OS. They can create new folders and new files, delete them, open them, move them, etc. Any changes made within the palette are made directly to the file system. Likewise, changes made within the file system will be reflected within the File palette.

This model may then be coupled with either of the first two models, presenting open documents collectively in one window, or one document per window. Dreamweaver’s recent versions employ the tabbed window variant of the BBEdit model, but previous versions followed the Word model.

The benefit to using the Dreamweaver model is that the application may provide unique functionality based on the connections between multiple documents that wouldn’t be possible (or at least not as usable) if file management were left completely to the OS. For example, if an HTML file is dragged from one folder to another in the File palette, Dreamweaver will ask if you want to change all links in the entire site to reflect that change. If you were to move the file using the OS, Dreamweaver wouldn’t know about it. Other applications that follow this pattern are Espresso and iMovie.

Design Pattern: File Management, Part 2

Yesterday, I described the most common pattern for file management in an application, using Microsoft Word as an example, where the majority of file management tasks are left to the operating system. The second model is becoming more common, seeing uptake in browsers and developer tools, especially on the Mac. It’s a hybrid in which file management responsibilities are shared with the OS. The application adds some file management features that make it more convenient to work with the files within the application. I’ll refer to BBEdit, a simple text editor, as I believe it was the first application I used that worked this way.

When multiple documents are opened in BBEdit, they are opened in a single window. The window has a pane on the side that lists the open documents. You may switch between documents by clicking on their titles in the pane, but you only view one document at a time. Of course, you also have the option of opening additional windows, each of which may contain a set of documents. You may then drag documents from one window to another. Documents may be closed from the pane, but that’s the extent of its functionality. All other file-related functions (opening, saving, deleting, etc.) are performed as they are in the Word model.

There are variations on this model. Some applications, like CSSEdit and the modern web browsers, use tabs to represent multiple documents, rather than a pane. Tabs can be dragged between windows or dragged out to create a new window. BBEdit and Firefox are both capable of remembering the set of files that were last open and reopening them the next time the application is launched.

The main benefit of this model is that it is quicker and easier to move between multiple, related documents, such as a set of HTML files and the corresponding CSS file, or an XML file and the DTD. Window management in the OS is sluggish and unwieldy by comparison. This pattern is therefore quite popular in software development tools.

In tomorrow’s final installment, I’ll describe a pattern through which applications claim complete control over their files.

Design Pattern: File Management, Part 1

There are three relatively common models for file management within an application. Over the next three days, I’ll address each in the context of an application that follows the pattern.

The first of the three file management methods is the most common. I’ll use Microsoft Word as a concrete example. Word has no internal view of the OS file system. You open a file one of two ways: by finding the file using the UI of the OS and then double-clicking it, or by using the “Open” command within Word. The first method relies on the OS knowing that the file belongs to Word and should be opened in it. In the latter method, Word calls on the OS to display a standard dialog used for finding and selecting a file.

Word can open multiple files at one time, and each file is displayed in its own window. Word relies on capabilities provided by the OS for window management. The user may open, close, minimize, maximize, etc. on a file-by-file basis. Word will also create new files, and can save files, either replacing the previous version, or saving a new file, again relying on the OS for a Save dialog to specify a location. Word will also allow the user to view meta information about the document.

Word has no concept of a collection of files. It works with one document at a time. The user performs all other file management outside of Word. File deletion is not handled within the application, nor are moving the file from one location to another, making duplicates, and the like.

Tomorrow, I’ll examine a hybrid model that has recently gained popularity, in large part due to contemporary web browsers.

Design Pattern: Soft Keyboards

Efficient data entry is arguably the most difficult goal to achieve in a mobile UI. On-screen keyboards, while not as efficient as touch typing on a physical keyboard, can be useful for short amounts of text, such as filling out a form. Tablets have enough screen real estate to display full keyboards, and smaller devices can display specialized data entry pop-ups. Typically, the operating system installed on the device will provide a keyboard, which may be good enough in some instances, but custom designed keyboards that address the needs of specific user groups have the potential to be much more efficient.

  • In a typical data entry form, there will be fields intended for specific types of data: dates, numeric values, time of day, locations, or “free” text entry. Rather than using a single, full-size keyboard to enter all of these, an efficient UI will provide data-specific pop-ups: a calendar pop-up for date selection, a pop-up specifically for entering the time of day, a numeric keypad, etc. These pop-ups can be smaller, obscuring less of the screen, and can make data entry quicker while also reducing errors.
  • When data entry pop-ups open, they should try not to obscure the field in which the data is to be entered.
  • Data entry pop-ups should be movable, so that if they do happen to obscure something that the user needs to see, they can be moved to another part of the screen.
  • As data is entered, it should be displayed in the pop-up, as well as in the field it is being entered into.
  • Buttons should be large enough to be very easily targeted by a stylus or finger. However, this should be balanced by the need to keep the pop-ups to as small a footprint as possible.
  • Pop-up keyboards must include access to special characters needed by the users.
  • Pop-ups should have a “clear” button. Keyboards should have a “backspace” button as well.

Design Pattern: Persistence Pays Off

Contextual forms are great! At least, they are better than dumb, non-contextual forms. When I make a selection in question 2 that makes five other fields on the page inapplicable, those fields should be disabled or hidden. Ah, but what if I filled out those five fields and then answered question 2, such that those fields don’t apply? The information in those fields isn’t needed, so it can be pitched, right?

Let’s make this theoretical situation more concrete. I am ordering merchandise off of a website, and I have entered my credit card information, including my billing address. Now the site needs my shipping address, and there is a checkbox labeled “same as billing address”. Now, let’s say I enter my business address, because I won’t be home to receive the package. Then I decide that my wife will be home, so I check the box. The information from the billing address fields is copied over into the shipping address fields and the fields disable. Now I remember that my wife is going to be out all day with her Girl Scout troop and I uncheck the box. What happens next?

If you persisted the data for the unchecked state, the business address replaces the billing address and I continue on with my purchase. If you didn’t persist the data, the fields re-enable, leaving me to type my business address all over again.

This is a simple scenario, but the lesson becomes more pertinent as the size and complexity of the form grows. It’s a simple matter to persist data based on the state of a form widget. Doing so can save your users time and frustration.

Design Pattern: Undo/Redo

Undo and Redo are common, well-understood functions, but that doesn’t mean you can become lazy about specifying them. The developer assigned the task of implementing undo may not have given it so much thought as you have.

For example, there is a user interface I designed for building regular expressions (regex) that visualizes them in a flowchart, allowing the user to drag parts of the expression to rearrange them. The flowchart is coupled with an area containing form fields where values are entered. This area is contextual, displaying different fields depending on the selection in the flowchart. If simply told to add undo and redo, there are many undesirable choices that a developer might make.

He could choose to only add actions in the flowchart portion of the UI to the undo stack. This would result in a broken experience for the user, as only some of their actions would be undone, leaving their regex in a nonsensical state. Or, he might decide to include all actions, including every character typed into a field. Then, to undo back to a particular state, the user would have to hit the undo button repeatedly, undoing a single typed character with each press. Rather, loss of focus on the text field should define the scope of the state saved to the undo stack. There are other applications in which time or number of characters would be a more appropriate measure. How many actions should be stored in the undo stack? What happens when the action being undone affects something not currently displayed in the UI?

Once you begin analyzing it, an undo/redo feature is a complex, nuanced interaction that must be designed for the specific context in which it is being employed.

Design Pattern: Multi-select

Selecting multiple items from a list was a tricky interaction in the past, especially on the web. The standard multi-select list widget leaves a lot to be desired. For one thing, the user must realize that they can select multiple items and know to hold down a modifier key to do so. Even when you know how to use it, it is easy to accidentally select something you didn’t intend to, or accidentally deselect everything you had selected. Typically, the list box is small enough on a page that a portion of the list is scrolled out of view, so you have to scroll up and down to check your selections. Overall, it just feels temporary. I feel the need to do something to finalize the selections—it’s just so tenuous. Checkboxes are fine for short lists, but a large checkbox list can be unwieldy, and you have to scan the entire list to see what is selected and what isn’t.

For many years, I’ve been using two list boxes side-by-side—one containing the list of items to select from, and the other to contain the selected items. Buttons between the list boxes move items from one to the other. This makes the selection more concrete, and clearly shows which items have been selected. While this was certainly preferable, it could be a bit tedious, requiring you to click to select within the list, and then click to move the selected items to the “selected” list.

More recently, I’ve improved upon the pattern, dropping the standard form widgets entirely, and utilizing the power of CSS and JavaScript.

The lists are contained within scrolling Divs. As the cursor hovers over a row, it highlights, and the arrow displays, communicating the action that will occur if clicked. Clicking anywhere within the row moves the item to the other list immediately, obviating the need to press an additional button to complete the action.