Oct 29 2009

An auto-hiding menu bar with jQuery

Category: jQuery | UIMatt @ 04:52

What do you do with links/buttons/actions that are likely to be infrequently used, but should still be available to users anywhere in the system?  That’s the question I had to answer for the new InSpire search engine we’re working on at my day job.  The sort of links I am talking about are logout, preferences, help, and various admin commands (for administrators only).  These actions are not really part of the application per se, they are more part of the basic application framework that needs to be available to the user.  We didn’t want to take up valuable space in our UI with these things (plus we wanted to keep the UI as basic as possible), so where do you put these things?

I decided I would try an auto-hiding sliding menu.  The behavior I wanted was identical to the Windows task bar when the Auto-hide the task bar option is selected.  After a little jQuery and CSS magic, and some help from Jeff Robbin’s great article on an auto-hiding search box, I had a solution that works in IE 8, Firefox, and Chrome.

First, check out the demo.  The menu bar is themed using jQuery UI, so if your app uses jQuery UI, you will get a consistent look-and-feel.  Also note that my menu bar doesn’t suffer from the same bug that Jeff Robbin’s article does: when you mouse-over and mouse-out my menu bar very quickly a few times, it doesn’t get stuck in a show/hide loop.  Let’s look at the code to see why.  First, the markup and CSS:

<style type="text/css">
#siteMenuBar
{
    position: fixed;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 30px;
    margin-top: -27px;
}

#siteMenuBar > #menuContainer
{
    margin-left: auto;
    margin-right: auto;
    width: 100%;
    height: 25px;
    padding-top: 5px;
}

#siteMenuBar ul
{
    float: right;
    list-style-type: none;
    margin: 0;
    padding: 0;
    font-size: 0.9em;
}

#siteMenuBar li
{
    display: inline-block;
    margin: 0;
    padding: 0 5px 0 5px;
    margin-right: 10px;
}

#siteMenuBar ul:first-child
{
    float: left;
    margin-left: 10px;
}
</style>
...
<div id="siteMenuBar" class="ui-widget">
    <div id="menuContainer" class="ui-widget-header">
        <ul>
            <li><a href="#">Administration</a></li>
            <li><a href="#">Design Guidelines</a></li>
            <li><a href="#">Other Link</a></li>
        </ul>
        <ul>
            <li><a href="#">Preferences?</a></li>
            <li><a href="#">Logout</a></li>
        </ul>
    </div>
</div>

The markup is pretty clean.  There is an outer container for the menu, then an inner container for the actual menu.  The inner container is probably not necessary, but having it allows you the opportunity to do some neat style nesting.  The actual menu is implemented as two unordered lists.  The CSS floats one of the menus to the left, and the other to the right, giving you two groups to add menu items to. 

The styles are a little more complex.  The outer container is giving a fixed position at the top of the window, then positioned mostly off screen with negative margin.  This leaves a small handle visible that the user can mouse-over to show the menu.  The inner container applies a little padding to the menus and could be used to make the menu bar appear to be less than 100% of the window width (though in this case it is allowed to fully fill the menu bar area).  Next, the actual menus are styled and positioned.  Note that both are initially floated to the right, but using the pseudo-selector first-child, we bump the first menu back to the left. 

Now let’s look at the code:

var timeout = null;
var initialMargin = parseInt($("#siteMenuBar").css("margin-top"));

$("#siteMenuBar").hover(
    function() {
        if (timeout) {
            clearTimeout(timeout);
            timeout = null;
        }
        $(this).animate({ marginTop: 0 }, 'fast');
    },
    function() {
        var menuBar = $(this);
        timeout = setTimeout(function() {
            timeout = null;
            menuBar.animate({ marginTop: initialMargin }, 'slow');
        }, 1000);
    }
);

Note the timeout variable.  This is key in fixing the bug that exists on auto-hiding search box.  For flexibility, we also grab the top margin so that we can hide the menu back to its original state.

The real core of the technique is the jQuery hover handler.  We supply two functions: one to execute when the mouse hovers over the menu bar, the other to handle mouse out.  The first time the mouse over handler is executed, the timeout will be null, so it will immediately animate the menu bar, removing the negative margin and making it visible.  On mouse out, the setTimeout function is used to schedule the menu to be hidden one second later.  Note that I’m assigning the return of setTimeout to my timeout variable.  This is what prevents the menu bar from ending up in a bounce-loop like the search box.  It allows me to cancel the hide action.  If the bar is scheduled to be hidden and the user moves the mouse back over the menu bar, the mouse over handler clears the timeout.  Without that bit of logic, even if you move mouse back over the menu bar, the setTimeout function will hide the menu out from under the user, which can lead to that funky show/hide cycle. 

So, there you have it: a simple, clean auto-hide menu with jQuery.  This could easily be encapsulated in a jQuery plug-in for easy re-use (not really needed in my case though since the master page is responsible for rendering it).  Anyway, let me know if you have any suggestions!

Tags:

Oct 4 2009

Product Review: Balsamiq Mockups for Desktop

Category: UIMatt @ 05:57

It seems like I’ve been doing a lot of user-experience (UX) design at my day job lately.  It’s not an area I consider one of my core strengths.  Up until recently, I would actually say it was a major weakness, but I was fortunate enough to take a HCI (human-computer interface) class while working on my masters degree. That class got me pointed in the right direction (I think).  I still suck at matching colors and coming up with pretty graphics, but I like to think that I can usually come up with good ideas for how things should be laid out and what the user experience should be like. 

One of the valuable practices that I picked up was using rough mockups to prototype the UX.  When I say rough, I mean it.  I’m talking about prototypes drawn with simple lines and boxes in MS Paint.  Many people don’t even go that far and will instead stick to paper-and-pen.  I’ve even read about design sessions where they literally use paper, glue, and odds-and-ends lying around the office to come up with new UIs.  The benefit to taking such a low-quality approach to the prototypes is that it helps people focus on the interaction and experience instead of tripping over issues like button color and fonts. 

While MS Paint works, and I’ve done quite a few mockups using it, making a mockup in Paint  is not a fast process.  It involves a lot of copy-and-paste, and a lot of try-this-didn’t-work-undo-it.  Fortunately there are tools to help you build rough mockups.  Today, I’ll be doing a review of one: Balsamiq Mockups.

About Balsamiq Mockups

Mockups is a tool for creating mockups with a pen-and-paper feel, but using a more productive drag-and-drop approach.  There are a variety of versions available.  There is a free (but limited) web version, a desktop edition, and plug-in versions for a variety of wiki and bug trackers.  According to their site, the current version features over 75 controls, 150+ icons, and a slew of keyboard shortcuts, which I’m still trying to learn.

Impressions

I have been using the online version of Balsamiq Mockups for a few odd things over the last couple of months, but I only recently took the plunge and got the desktop version (thanks to Balsamiq giving me a license so that I could fully evaluate it!).  Mockups is an Adobe AIR application, so not surprisingly, the web version and the desktop version feel almost identical.  The bulk of the UI is across the top while the canvas occupies most of the remaining space below.  In the desktop version, there are tabs across the bottom for each open mockup.   Getting started is easy: simply drag a control onto the canvas, and you’re off!  Controls like labels and text boxes that can hold values will immediately go into edit mode.  Clicking on an existing control brings up a floating panel with fairly standard options: move to front, move to back, group/ungroup, etc. 

For advanced users, there is also a quick-add box that allows you to type the name of a control and add it to the canvas.  Once you have a good feel for what controls are available to you, you will probably find that this is faster than hunting for controls with your mouse.

Things I liked…

Overall, I was very pleased with Mockups.  Building a prototype UI with it was significantly more efficient than my old method of sketching things out in MS Paint.  I found that most of the controls that I wanted to use where built-in and flexible enough (for the most part) to support what I wanted to prototype.  Unlike the web version, the desktop version supports multiple open documents via a tabbed interface, which is really helpful when you’re fleshing out multiple screens for an application and want to quickly switch between them. 

One of the cool things about Mockups is how open and flexible Balsamiq is with its development.  They issue new releases almost weekly (as can be seen here), and bugs, suggestions, and questions can be submitted easily through their Get Satisfaction portal.  They also have a community-driven site for sharing mockups and new controls called Mockups To Go

Another area where the openness of Mockups shines is the native file format.  Your mockups are stored as XML and can easily be consumed by other applications.  In fact, there are numerous 3rd party tools that you can use to help take your mockups to the next step, such as Napkee and a tool to convert from Mockups to Image Maps.

One other nice thing I noticed is that I can actually drag-and-drop files on Mockups to open them.  Drag-and-drop works for both the native BMML files as well as XML exports from the web version of the tool.

Things I didn’t like…

First, and this is very nitpicky, I only counted 74 controls, not the 75 that are claimed (and yeah, I double-checked my tally twice).  Maybe the 75th icon doesn’t show up under “All”?  Fortunately the controls available via Mockups to Go more than makes up for the missing 75th control.

Probably the biggest annoyance I encountered while using Mockups was controls randomly shifting slightly when selected. Sometimes things appear to move by a few pixels even though they’re really still in the same place.  When selected, sometimes controls would appear to jump down and to the right by one or two pixels.  Tapping “left” to nudge it would cause it to bounce back up where it was before.  I know it isn’t actually moving since it doesn’t register with Undo/Redo.  NOTE: I didn’t notice it until just now, but this is actually a well-known bug, described by this issue.  I hope it gets fixed soon, because it is very annoying

Another random annoyance was the options panel.  While it manages to stay out of the way most of the time, I did frequently find that its default placement was very much in the way.  Especially when working in or near a corner of the canvas, the panel would seem to inevitable be right where I didn’t want it to be.  While you can drag it out of the way, it seems like it could position itself a little more intelligently.  I also question why the panel is needed at all.  Why not make it a context-sensitive toolbar or “ribbon” instead?  There seems to be plenty of free space available in the existing toolbar at the top of the application.

Another thing I noticed was that I sometimes received “file exists” warnings when saving a mockup even when the file actually didn’t exist yet.  Apparently mockups does not pay attention to the file extension, so trying to save “Mockup.bmml” into a folder that contains “Mockup.xml” will cause these incorrect warnings to occur. 

Suggestions

After making over a dozen different mockups, I have come up with a few things I’d like to see.   First, I’d really like to see some sort of toolbar or ribbon-like interface instead of the floating control properties panel.  Second, creating a tab for a new mockup can currently be accomplished by right-clicking on an existing tab and selecting the appropriate option, but I’d love to see a Firefox-like “+” button for adding a new tab with a single click.  Also related to the tabs, they currently order themselves alphabetically, but this isn’t always the way I want to order my open documents.  Being able to reorder them would be a nice, simple addition.

A final suggestion: consider lowering the price.  At $79, it’s too high for my impulse-buy reflex.  If it was priced at $30, for example, I probably would have bought it without spending more than a few minutes playing with the web version.  As it is though, $79 isn’t expensive, but it means that I have to think a little harder before buying it.

Final Thoughts

I still haven’t decided if Mockups is for me.  There are alternatives, such as Microsoft Sketchflow, and I need to spend time playing with those to decide which tool is really the best fit for me.  I do strongly recommend that anyone needing to do UI development consider some sort of tool for doing quick mockups, and Balsamiq Mockups is definitely an option to consider.

Tags: