Controlling Your Controls

Using disabling, hiding, message boxes, and more to control availability to actions and guide your users.

Now siezing control of your puny planet, you pathetic Earthlings. (Cancel Bt disabled).

The first rule for controlling the availability of controls is don’t. Don’t disable or hide the controls for an action. Don’t disallow the next step in the process until users complete certain “required” fields. Don’t prevent users from changing or deleting data objects for the user’s own protection. Don’t prohibit saving because it’s really unnecessary since nothing has changed since the last save. Don’t show an error message saying the user needs to connect with the service before using it.

Every time you limit control of an action, you’re adding a mode, whether you are removing availability of commands that are executed via menu items and push buttons or data object attributes and command parameters that are set via controls like text boxes and dropdown lists. Every time a mode is added to a UI, you’re also adding another state user has to notice and understand, or a processing step one has to complete, making things more difficult for the user. Limiting availability to an action reduces the app’s flexibility and removes control from the user, violating a basic principle of good user interface design.

There are only two good reasons to remove availability to an action:

  • It is logically impossible to complete the action without some prerequisite condition.
  • Business rules mandate a limit on the abilities of certain positions or groups of users

You should still design the UI to discourage unnecessary and ill-advised actions, but there are other means of doing that than shutting off a control. Unnecessary actions, such as saving a document that hasn’t changed, can be discouraged by providing an indicator when actions are and are not necessary, for example an annunciator that says “Saved” or “Unsaved” beside the Save Toolbar control. Another way to handle unnecessary actions is to just not worry about them. So the user saved when it wasn’t needed. What’s the cost? Maybe doing repeated saves makes the user feel better, like pressing an elevator button several times to make sure the elevator isn’t going to forget.

The best way to handle ill-advised actions is to let them happen but (a) make it clear what will happen (e.g., “I wonder what the button ‘Dematerialize Boss’ does”), (b) show exactly what had happened by showing the consequences in the window (”Gee, looks like I just dematerialized my boss”), and (c) provide a clear way to undo what happened (”Maybe I should click ‘Rematerialize Boss’”). This gives the user control (on the not-so-off-chance the user actually knows what she or he is doing), but makes mistakes easy to avoid, catch, and correct. If that’s not enough, including a verification message adds one more layer of defense.

Impossible to Complete the Action

Disabling or other means of controlling availability are generally necessary when the task is not in the right state for the action. For example, in order to send an email, a letter needs an address to send it to. To find text within a document, the text to be found needs to be specified. These are logical steps to the task of emailing and finding respectively.

Note I said when the task is not in the right state, not the application. Apps should be designed so any internal states are as compatible as possible with the tasks as the user sees it. For example, don’t disable Paste when a document isn’t in Edit Mode. Don’t even have an Edit Mode. Switching into Edit is not part of the task as far as the user is concerned. Don’t disable the Add button when the number of Format Conditions reaches the limit of three. Don’t have a limit of three.

Don’t disable Cancel or Close. Ever. Always provide users a way out. If you don’t, they’ll make a way out, pulling the plug if they have to.

This may mean re-working the feature to make the action work somehow. For example, in a form or spreadsheet, instead of disabling the Find button when there’s no text specify, let clicking it search for the next empty cell or field (that would be pretty handy for making sure all blanks are filled in on a form). You’ve disabled Paste in your app because the text box the user is trying to paste into can’t accept the entire file that’s currently sitting on the clipboard. Instead, paste something from the file, even if it’s just the file name (that actually would’ve solved a problem for me when I was using Microsoft Outlook once). Yeah, that can mean more work for developers, but that’s what developers do. They work so users don’t have to.

Mandated Limit

Sometimes your client divides users into groups, each with different responsibilities or rights, and there’s nothing wrong with that. Often it’s a good idea to build these different roles into the UI, modifying it for each user group. Managers approve travel requests, not engineers, so there’s no reason to give engineers access to the windows and controls to approve travel requests. Limiting access to the actions within each user group’s repertoire of tasks simplifies the UI for them as well as prevents users from (perhaps accidentally) overstepping their authority (e.g., engineers approving their own travel requests) or messing up something they don’t understand (e.g., managers deleting the latest stable build).

However, building organizational limits into software can be overdone. Many things are better handled with organization policy, rather than controlled by software design. Policy allows more easily for organizational evolution and unanticipated processing exceptions which inevitably occur. Building into software a lot of specific limits on who can do what might sound like a great idea until no one in the organization can correct an invoice of a high-profile customer because the one person with the permissions has been abducted by aliens.

There’s an organizational cost-benefit to limiting user’s actions. It may prevent them from causing problems but it may also prevent them from solving them too. So you should adopt a skeptical attitude towards requirements to limit the users. What exactly is the problem it will solve? Is it hypothetical or has it actually happened? Sometimes a desire for control over users betrays a unjustified poor opinion of the users or their work ethic, rather than an actual problem.

Even for problems that have occurred, the answer may not be more control. For many organizations, the knee-jerk reaction to users doing something they’re not supposed to do is find a way to stop them. For example, say users are not completing various items on a form even though it would actually make their work easier by improving data quality. Your client might see this and order that those fields be made required.

Whenever users do something wrong, the first reaction should be to do the research to find out why they’re doing it, something a usability professional is well equipped to do. Do the users skip certain fields because they simply do not know how the fields are useful to them downstream? Maybe it’s a matter of providing a little documentation or training. Do they not understand the fields? Maybe you need to improve the labels. Do they not know where to get the information to complete the field? Maybe you can provide a look-up reference feature in the window. Are they rushing to avoid having the page expire? Maybe you need to increase the time-out interval. Note that if any of these are the reason users skip the fields, simply making the fields required will not actually help. Users will put whatever it takes for the system to allow them to get the task done. So much for data quality.

Means of Controlling Availability of Actions

There are three basic options:

  • Disabling, where the associated controls for the action remain visible but are inert to user input. This is signaled by giving them a dimmed or “grayed-out” appearance.
  • Hiding, where the associated controls are apparently removed from the window or page.
  • Messages, where the controls appear unchanged, but user input results in an error message and the input is discarded.

Each works best for different purposes.

Compared to hiding controls, disabling controls has the advantage of making the UI stable. Whatever the state of the system, controls remain in the same place with essentially the same appearance, making it easy for the user to find things by using the controls as landmarks. This is especially important in pulldown menus, where users acquire muscle memory for selecting familiar items. With the use of disabling, enabled menu items remain in the same place regardless of the availability of other menu items. Within a form, disabling prevents gaps between controls that hiding would cause, which might give users the false impression that the remaining controls are being grouped in some way.

On the other hand, hiding controls has the advantage of cutting down on clutter. Things that the user cannot do are not going to be there (even with a muted appearance) causing distractions. The more time a control spends not being available to the user, the less sense it makes to have it there getting in the way.

Put these two trade-offs together, and it’s clear that disabling should be used when the unavailability of the action is transitory, easily and frequently changed, where the cost of instability is high but the impact of clutter is low. Hiding should be used when availability is more stable, when if an action is unavailable, it’s likely to remain unavailable for a long time. Here’s when to use each in more detail.

Disabling

The fact that a disabled control is visible to the user indicates that the control is potentially available to the user, but just isn’t given the way things are right now. Thus, disabling a control should be used when the associated action is not possible or the associated attribute is not applicable for the given transitory condition.

For example, suppose your app is designed to communicate and establish relations with visiting aliens from the planet Sekdtilaa as they orbit the Earth in their vast, powerful, and entirely benevolent star cruisers. Translating from Earthling languages to this alien language (Sekdtillaiae) can only be accomplished by an incomprehensible computational algorithm supplied by the visiting Sekdtilayani (they use Lisp), but you’ve managed to put a user-friendly wrapper around it.

Dialog with Send Text Box and disabled Send Button.

Having a message to send is a task prerequisite for sending a message (assuming that a blank message has no meaning to the Sekdtilayani). Thus you would disable the Send button until the user enters some text to send. Once enough characters translatable into Sekdtillaiae are entered, the Send button enables.

Your app also gives users the option to log the exchange with the Sekdtilayani. The log file, with its default name has no logical meaning when nothing is being logged, thus you disable it unless the user selects the Log Dialog check box.

A disabled control may tell the user an action is potentially available, but (unlike a message box), it can’t explicitly say how to make it available. For this reason, disabling should only be used when it is clear what the user needs to do to enable the control. Usually, this means providing controls in the same window (or maybe its parent if its a modeless dialog box) that the user sets to change the app’s state to allow the action to be done. Sometimes, as when a background process needs to complete before the action can be done, all the user has to do to enable a control is wait a little while. In this case, you should provide a read-only control indicating the current state and/or an indication of when action will be available (e.g., a progress bar).

In any case, a user with typical knowledge of the task should be able to scan the window and say, “Oh, of course, it can’t work until this is done.” Don’t put users on an extended scavenger hunt looking across multiple windows (especially any that aren’t open) for something that enables the control. If the action is unavailable due to technical limitations of the system (e.g., quota of communications reached), provide an indication of that limitation near the disabled control (e.g., a counter of communications beside a label giving the quota). If such information cannot be provided, do not use disabling. In keeping with the dynamic availability that disabling should be used for, the process of enabling a control should be fast and easy. Certainly don’t use disabling when there’s nothing the user can do (not even waiting) to make the control quickly available.

The idea is that by mere appearance, a disabled control provides the user with the following information:

  • The action is possible.
  • Just not right now.
  • But the user can make it possible.

Other means of controlling availability don’t provide all that at a glance. Hide a control, and the user may never learn the app has the associated feature (e.g., when it’s in a pulldown menu). Use a message, and the user has to click the control to tell if it works.

In the case of controls for attributes, disabled controls provide users with a preview of what input to expect should the controls become available (e.g., a file name in the illustration above), while hiding the controls won’t. Disabled controls also provide additional clues to the meaning of the controls around them. Compare the following where an unavailable attribute it hidden:

Alien-Human Relations Aliens should Bug off, Observe humans unobtrusively, Answer questions from humans, Serve humans.

With this one where it is disabled:

Same as before but now Serve Humans includes dropdown set to

Specifically, disabling should be used when:

  • The user has yet to provide the input the action requires in the nearby controls.
  • The action is irrelevant based on the values of other attributes or parameters shown by nearby controls.
  • The action doesn’t make sense for the currently selected object class.
  • A background process needs to complete before the action makes sense.

Consistent Graphic Coding

For the meaning of disabling to be clear, however, the graphic coding for disabling has to be used consistently. This means that gray becomes a foreground color with special meaning. It should always be used to represented disabled and never used for anything else, otherwise users won’t know what gray means. As an example of what not to do, in Nvu, my HTML editor, here’s the toolbar icon for inserting a link:

Gray Nvu Link icon

–That’s when it’s enabled. Here’s Save when it’s enabled:

Gray floppy disk

And disabled:

Slightly more gray floppy disk

Try distinguishing them when they’re not side by side.

Microsoft Windows Explorer in XP gives the menubar of the inactive window a disabled appearance, even though it’s fully available (click-through is supported).

Menu dimmed for inactive Explorer window

This dilutes the meaning of gray, making it more likely that users will become confused. I don’t know what problem the Windows Explorer designers were trying to solve with the above, but they should have thought of something else. Now if click-through were not supported, that would make some sense (that’s the OSX standard). Or even better: if the active window were a modal dialog box, it would be cool to disable the menubar to indicate that.

Likewise, changing appearance on mouse-over has come to indicate an active control, so disabled controls should not change appearance on mouse-over. For example in the OSX standard, disabled pulldown menu items are not highlighted when they are disabled, a practice also followed by Microsoft Office apps even in Windows. That’s a good design. In forms, it helps a lot if the field caption acquires a grayed appearance along with the attribute control itself when the field is disabled, especially if the field happens to be blank.

Disabled Means “Not in Effect”

Really disabled means only what it means: that the action associated with the control is temporarily unavailable. However, this can also imply that the associated action or value is not in effect for the current state. The very fact that the controls are grayed graphically suggests a dormant state and the users’ eyes will tend to skip over such dimmed controls. The association between disabled and Not In Effect is reinforced by the use of disabling for attributes and parameters. For instance, in the Sekdtillaiae chat window above, a default file name for the log is shown even when dialog logging is off, providing a preview of the kind of input that will be needed if logging is turned on. By being grayed out, however, the user understands that the file is not currently in effect -it may not even exist unless logging is turned on. That’s what you want users to understand.

Failing to use disabling in this manner can cause confusion. Below is a detail for the advanced query dialogue for Ingenta Connect. I was looking for electronic content (something I could download immediately), but I wanted to narrow my focus for only certain years.

Unselected

Bzzt. Wrong. The From-To years drop downs only apply if the user is searching for Fax/Ariel content. If the From-To controls were disabled when Fax/Ariel were non-selected, I could’ve saved myself both time and confusion.

Conversely, you should not use a disabled appearance for anything that is currently in effect or relevant. Specifically, you should not use disabling to dynamically change an editable control to a read-only control. Consider for example, the selection of the sub-ether channel for communicating with the Sekdilayani. Suppose that once communication has started, the channel cannot be changed. If you disabled the entire channel selection dropdown control, users may wonder if the currently displayed channel is really being used or not.

Channel dropdown, both value and button dimmed.

A better solution is to apply the disabled appearance only to the elements that effect the change (the dropdown button, in this case), not the whole control.

Channel dropdown, value appears as read-only, button is disabled.

Making the control appear as read-only also helps. Sometimes you may want to completely swap the editable control with a read-only control, essentially making a “value contingent region,” which is described below.

Because disabling can mean Not In Effect, disabling should not be used for opposing commands, where one command reverses the other. For example, suppose the user can Connect, Disconnect, or Warm-up a sub-ether channel for communication. While disconnected, the channel logically cannot be disconnected again, and likewise for the other states, so one may think to disable the button corresponding the channel’s current state. This has the side benefit of the disabled state of the control indicating the state of the channel, although it requires an awkward kind of thinking (”I can’t do it, which means it must already be done”).

Push buttons: Disconnect (disabled), Warm-up, Connect

However, this practice should be avoided because, with generalization from the experience of attributes, the dimmed control may also indicate that the state is not in effect –not disconnected, in the above case (and not able to be disconnected either). The potential for confusion becomes clearer when other conditions for availability come into play. For example, suppose a channel cannot be connected until it is warmed up for some variable period of time. Until then, it makes sense to disable the Connect button. However, during warm-up, the Warm-up button would also be disabled, leading to ambiguity on the state of the channel.

Push buttons: Disconnect, Warm-up (disabled), Connect (disabled).

The solution is treat opposing commands more like attributes and use the different controls that naturally indicate values. Option buttons, checkboxes, toggling buttons, and toggling menu items are among the alternatives. Here’s toggling buttons, suitable in this case since a process is initiated by each control.

Toggling push buttons: Disconnect (off), Warm-up (on), Connect (off, disabled).

Hiding

User Groups

Hiding controls is a UI’s way of saying, “Don’t you worry your pretty little head about this,” used when the user doesn’t need to know the associated attribute or action even exists. It’s the preferred way to control availability among user groups. If a user’s role doesn’t involve using the control, don’t even show it. Changing jobs, getting promoted, or even merely re-logging in with different rights are all too involved for disabling to be used here.

Each user group should in effect (or in fact) have its own variant of the app, with different-looking controls, and maybe even entire windows added or removed. Layout of the windows should be optimized for a specific user group, even if it means some re-learning in the event a user changes jobs. If you find there are certain users who belong to more than one user group, then consider making them a user group of their own with combined privileges so that they have a stable UI (and they don’t have to login and out for multiple times just to do their job, which would be pretty dorky anyway).

Avoid hiding controls for availability that is more transitory than the user’s identity. If you use hiding instead of disabling in such cases, users will be faced with more ambiguity when they look for the controls for an action they’ve done before but can’t find them. The users have to ask themselves:

  • Am I able to do the action in principle, but only after doing something else to make the controls appear?
  • Am I able to do the action now, but I just haven’t looked long enough for the controls?

The last question may not be all that easy to answer when the user is presented with multiple pulldown menus or tabs where the controls may be lurking. To simplify things, you want hiding controls to mean one thing: The user can’t do it.

Furthermore, using hiding when you should use disabling can be self-defeating. The advantage of hiding over disabling is that it reduces clutter. Clutter is bad because it’s distracting. However, making controls appear as part of normal use of the app constitutes animation which is also distracting. Switching from disabled to enabled is a more subtle form of animation. Disabling has less combined distraction from clutter and animation when availability is transitory.

Distinguishing Places and Things

Hiding can also be used to indicate different “places” and “things” in a UI. For example, here’s what a log for communications with the Sekdtilayani might look like.

Log entries: Sekdilayani only with Cruiser field.

The Star Cruiser field is visible for the replies from the Sekdtilayani but hidden (rather than disabled) for the transmissions of the Earthlings. This can be done because an Earthling transmission is a different class of data object than Sekdtilayani replies. It’s not like the user can do something to enable an Earthling transmissions to have a Cruiser attribute -it just isn’t part of the class. Earthling transmissions and Sekdtilayani responses might inherit some attributes from a common class, but they are also different classes. If you were to give a Star Cruiser attribute to Earthling transmissions (by, say, building a star cruiser), it wouldn’t be an Earthling transmission anymore (or at least, not an Earth-bound transmission anymore). Thus, a disabled Cruiser control is not appropriate here, and hiding is preferred.

The presence of certain controls gives each window and object class an identifying “face” helpful in recognition and orientation. Having certain characteristics, whether it’s menu items in a window or attributes in an object image, is what makes things what they are in the UI as far as the user is concerned. It’s the same with physical objects, where, for example, your body’s extremities don’t have disabled suction cups -they simply don’t have suction cups. It’s what makes you a human and not one of our cephalopodan friends, the Sekdtilayani. Users generally will not be confused by controls changing across virtual places or things, anymore than they are confused that a Sekdtillaiae blaster doesn’t have a “Take Picture” button the way a camera does. Quite the opposite, in fact. This extends to context menus and to overflow details when the master object may be various different classes. An overflow detail is a extension of the object image, so objects of different classes should appear with different attributes. In general, when the user selects a master object of a different class than the previous master object, the attributes in the overflow detail should change, applicable controls for the class appearing and non-applicable controls hiding. A multi-class overflow detail is also much like a value contingent region described below, where hiding is also often preferred over disabling.

Context menus should be considered a part of the object or place that was right-clicked, and should only include commands that apply to the object or place. In essence, the context menu should be regarded as a menu with the same name as the class of whatever was right-clicked. The only disabled menu items that should be on the menu are for commands that generally apply to the right-clicked class but don’t right now due to the current state of the particular object, which can be changed easily.

There is a certain amount of latitude to applying this rule. It’s up to the designer is to decide what constitutes different objects and places for the users, and design accordingly. Whatever the underlying data model, should Earthling transmissions be presented to the user as a different class from Sekdtilayani responses? Could Earthling/Sekdtilayani be instead presented as different attribute values of the same class? The answer depends on the usual design considerations: what makes the most sense to the user, what makes a consistent interface, what minimizes clutter, etc.

The key is to be aware that when a control is disabled versus enabled, you are telling the user the class is the same while the state is different, but when a control is visible versus not, you are telling the user the class is different. Once the design decision is made, be sure the graphic representation is consistent with that decision. For example, I’ve given Earthling and Sekdtilayani communications different icons to indicate they are different classes. Layout should also be consistent. For example, in a wizard, each panel is a different place, but does that apply to the navigation buttons? This has implications for whether you hide or disable the buttons at the ends of the wizard. For example, if each panel is its own window, a separate place, then the first panel has no Previous Button.

First wizard page, with buttons as part of page.

However, if the wizard is laid out to imply the separate panels are shown within a viewing port in a single window, then the first panel is displayed with a disabled Previous Button.

First wizard page, with buttons separated from page.

I don’t think it makes any difference to the users whether the wizard panels are each separate windows or things shown within a single window as long as the graphics are consistent with the type of availability you use.

Value-contingent regions

There is one situation that may use either hiding or disabling, and that’s what I call value-contingent regions, or what Luke Wroblewski calls selection-dependent inputs. Generally, disabling should be used when the relevance of some controls depend on the value of another determining attribute (like the Serve Humans option button in our Alien-Human Relations dialog above). In a value-contingent region, however, alternative controls are relevant for different values of the determining attribute. For example, suppose the following alternative options can be specified for each corresponding relationship selected with the Sekdtilayani:

Relationship Options
Bug off Timetable for departure
Observe humans unobtrusively Allowed observation activities
Answer questions from humans Topics (philosophical, political, technological, personal)
Serve humans Delicious sauces

For value-contingent regions, disabling starts becoming unattractive, especially when it’s more than one or two alternative controls, because it means at any one time most of your controls are disabled, taking up a lot of space with little purpose. Hiding starts becoming more attractive because one of its drawbacks -that it puts odd gaps on the form -is less of an issue, because now we are replacing one set of controls with another depending on the value of the determining attribute. When the number of controls swapped in and out reaches a certain threshold (oh, I don’t know, four per option?), it’s better to hide than to disable.

Hiding is often preferred for value-contingent regions with many controls, but you should design such a value contingent region to ameliorate the drawbacks of hiding. The connection between the region and the determining attribute should be signaled visually, something that is less important (but still very helpful) for disabling. Usually the best way to do this is to place a frame around the region and put the determining attribute at the top or left edge of the frame. The alternative sets of controls in the region should be treated as if they were separate mutually exclusive “panels.” Avoid tab imagery, however, which implies the alternative panels are “still there” and thus may still be applicable. Modifying the determining attribute should change the region immediately; there should be no Apply button.

Obsvere Nonintrusively Option Button selected, with adjacent panel of observation check boxes.

Try to consolidate the alternative attributes within a small region. Do not have hide-able controls scattered throughout window or page. Consider disabling over hiding if consolidation is not feasible without compromising other usability goals (e.g., a task-compatible order for the fields). Avoid including in the region any attributes that are common to all values of determining attribute. Keep the size of the region the same even if some values of the determining attribute have few controls. You want to minimize the disruption of controls outside of the region.

You want to strive for consistency in layout across the alternatives in the location and order of the attributes common to more than one determining value. You want of avoid shifting attributes around due to changes in determining attribute, but also leaving gaps between attributes where one is hidden. This is best accomplished by putting attributes that change the most at the bottom of the region.

Watch out for two attributes that may be confused across different alternatives, especially if they imply different actions if the user fails to notice the current determining attribute value. In such cases, it’s better to be inconsistent and put the confusable controls in different places. Remember, with experience, users will use the alternative layouts to recognize the determining value.

Messages

Error messages are the availability control method of last resort. Providing an enabled control that doesn’t in fact work is misleading and may lead users to fail to use controls because of mistaken assumptions on how things work. Enabling and hiding provide immediate feedback on when an action or attribute is available by the visual change that accompanies the change in conditions. When messages are used, the users must employ trial and error to see if they’ve done enough to make an action possible, thus making for a less efficient user interface. Also, some users regard error messages negatively, detracting from user satisfaction, and making the messages “polite” doesn’t help. Where disabling says, “Things aren’t ready for this,” and hiding says, “You don’t need to worry about this,” error messages say, “No, you can’t do that, obviously, dummy” (the last two words muttered under the app’s breath). Users familiar with the convention of disabling can feel tricked. I mean, if the computer knows I can’t perform an action, then why does it make it look like I can?

However, messages have one advantage over hiding and disabling that can override these concerns. An error message can instruct the user on how to make the controls available. Disabling tells the user a control can be made available, but won’t say how. Hiding tells the user squat. For example, TrueCrypt disk encryption software disables the Next Button in its Volume Creation Wizard when the double-entered passwords don’t match, unlike other apps (e.g., for web account creation), which typically provide an error message.

Two password text boxes with same number of asterisks, Next Button disabled.

This can be puzzling: as far as the user can tell, the same password was entered twice (this can’t be verified because the passwords are shown as asterisks by default). How is a user supposed to figure out the problem? The user might think the problem is that TrueCrypt doesn’t like the chosen password. Or maybe certain volumes require a key file (for which a checkbox is provided unchecked). How can a user tell?

Getting an error message will annoy and slow a user, but not being able to figure out how to enable an action will outright prevent task completion, so the impact is more serious. If users cannot figure out how to enable a control despite your best efforts, then a message may be the only alternative.

This ability of messages to provide user documentation is so significant that HFI guru Eric Schaffer (who I think is spot-on with most of his design advice) advocates only using messages. Recently, Joel Spolsky has also come out with a blanket endorsement of messages over hiding and disabling.

However, it should be pointed out that messages, while better than nothing, are not ideal for documenting.

  • They come too late, after the user has attempted the action, when it’s better if documentation appears just before.
  • They are disjoint from the context, appearing as textual instructions in a separate window. The user must read the message and translate it into actions back on the parent window. Certainly, if you haven’t or can’t provide a clear concise explanation for making an action available, then there’s no advantage to using an error message.
  • In recent years, many users have gotten into a habit of ignoring message boxes and closing them without reading them (for reasons to be discussed in a later post).

Error messages represent a snag in the UI. Anytime you find yourself specifying an error message, stop and re-think the design so that they aren’t necessary. However, the Schaffer Concern is undeniable, so simply switching from error messages to disabling is not enough. Whenever a control is temporarily unavailable, it should be easily apparent to the user by looking at the window what is necessary to make the control available. Before giving up on disabling and relying on a message to document this, consider other methods as described below.

Self-Documenting Disabling

There are two principles for making a UI self-document control availability that avoid the problems of using message boxes:

  • Tell the user what’s needed to make an action available before the user tries the action.
  • Make this information perceptually associated with the unavailable control.

In a very simple window, such as a basic Find dialog box, nothing special is really needed. The user can see the button is disabled before trying to use it, and the explanation, in the form of an empty text box, is right beside it. The only control other than the Find and Cancel Buttons is the Find Text Box, so that has to be where the problem is.

In more complicated windows, you can use proximity and layout to communicate relations among controls by putting the disabled controls proximal to the enabling control. Enclosing the controls in a frame, like discussed for value-contingent regions is a good idea too. If the controls that enable the disabled control are not in that window, put them there. At the very least put a read-only status indicator beside the disabled control to suggest what about the current state (as described by the status indicator) needs to be change to enable the control. For example, if connecting to the Sekdtilayani is done in a different window than sending communications, then include an annunciator of the connection status beside the chat Send button (disabled when there is no connection). Make the annunciator a link, and clicking it can open Help that explains the ramificaitons of being disconnected and what the user can do about it. You probably should also include a Connect button to open the window to create a connection if it doesn’t exist.

Chat window, Send button disabled, Disconnected link and Connect button beside it..

However, layout should be done firstly to be consistent with the task, so you can’t always have the enabling control proximal to the disabled controls. When that is the case, try other graphic effects to connect the disabled control with the enabling controls. For example, put red asterisks beside required fields and put “* = Required” beside the disabled command button, thus making an association between the disabled controls and the enabling controls by visual similarity (all have red asterisks beside them)

When graphics are not enough, you have to use text. Such text needs to be near to the disabled control, not in some general explanation area the user is going to skip over. Text in a status bar is usually worthless. Schaffer himself suggests using tool tips to provide a brief explanation of why a control is disabled or how to enable it. Being applicable to all controls including pulldown menu items, I’d like that to become a GUI standard for anytime disabling is used, and indeed some kind of standard for this is long overdue. Until then, however, using tooltips doesn’t have great discoverability -users won’t necessarily think that hovering the mouse over a disabled control would do anything. Maybe it would help to put an “?” or some such icon in or beside the control to encourage user interaction.

For particularly challenging cases, you may want to put the text explaining the disabling right under the disabled control. This, of course can only be done for disabled controls in the work area of the window, not in pulldown menus. To minimize real estate consumption, keep the explanation short (e.g., a two- or three-word phrase) and make it a link where clicking it opens Help to a detailed explanation on how to enable the control.

Guided Activation

Of course, by the time you’ve gone through all the work to add controls and messages to document why a control is unavailable, you could’ve simply presented the user with necessary means to make it available, rather than sending them elsewhere. This is the guided activation approach to dealing with unavailable actions, essentially a fourth approach but also a variation on the “make it work somehow” theme. An unavailable control is neither disabled, nor does activating it yield and error message. Instead, a dialog appears that prompts the user for the input necessary to carry out the action. Can’t chat with the Sekdtilayani because the connection is down? Then clicking the Send Button should first open a dialog box to re-establish the connection. If necessary, attempting an unavailable action can trigger a wizard to walk the user through the necessary prerequisites.

We see guided activation in Microsoft Office’s approach to the Save menu item. If the user has never specified the document’s name or location, then selecting Save opens the Save As dialog box, allowing the user to provide this information. In other apps (such those following the OSX standard), the Save menu item is disabled when the name and location have not been specified, forcing users to use the Save As menu item, an unnecessary deviation from what the users usually do.

Ideally, when using Guided Activation, you should change the menu item or button caption to end with an ellipsis (…) so at least your expert users can anticipate that the command will open a dialog when it normally doesn’t. Expert users may also learn to use the presence of the ellipsis to cue them to provide the information in the primary window first, where it may be easier to do than in a dialog or wizard.

Summary Checklist

Problem: Choosing among disabling, hiding, and messages to best control availability of actions.

Potential Solutions:

  • Make the action always available
    • Use status indicators to discourage unnecessary actions.
    • Use verification and undo to prevent permanent damage from unadvisable actions.
    • Control user behavior through organizational policy, not software.
    • Alter app design to make actions always possible in some way.
  • Make the action unavailable if
    • It is logically impossible for the current state of the task.
    • It’s best to encode organizational limits on the actions certain users are permitted to do.
  • Use disabling when
    • The user can make the action available.
    • Availability is achieved through controls in the same window or its parent.
    • The user can easily figure out which control do this.
  • Use toggling controls for processes currently in effect.
  • Use read-only text boxes for applicable but unchangeable attributes.
  • Use hiding
    • For Controls that are never available to the user in his or her current position.
    • For indicating different virtual places or things with different attributes or capabilities.
      • Make sure visual design is compatible with the use of hiding.
    • For replacing large numbers of controls, as in value-contingent regions.
  • Use layout, symbols, and text to explain unavailability, especially disabling.
  • Use messages when there no other means to indicate graphically or textually how to make an action available.
  • Consider guided activation to solicit necessary input for unavailable actions.

What Happened to July’s Post?

Well, I wasn’t partying with the Sekdtilayani, if that’s what you’re thinking. I chose this topic in June because I was sure it would be a short, fast post, which it had to be since I’d be away for vacation for a good chunk of the month. Of course, I’m always sure my next post will be short and fast, until I write it. Anyway, as you probably guessed if you’ve made it this far, this turned out to be one my longer posts, so it plain wasn’t done in time for posting for July. Frankly, I suspect summer posting in general will tend to be erratic. I’ll refund the difference to you.

Comments are closed.