For a recent app we chose Twitter Bootstrap for a quick and simple UI. On a few screens (wizards, mostly) we wanted a popover that explained certain elements or choices in an unobtrusive way. This particular web app is for real estate agents (a superb non-geek test group, by the way).

For non-tablet users, it works nicely to use Boostrap’s popovers that appear when the cursor hovers over a link (or clicks the link). Whether they click or hover, as soon as the cursor moves away the popover disappears.

The intuitive aspect completely breaks (IMO) for tablet users, however. There’s no ‘hover’ in current touch UIs, and hence no way to trigger a ‘no longer hovering’ event to hide the popover. Clicking the link displays the popover -* but hiding the popover when using a tablet is non-intuitive and unfriendly because the user needs to click another link to hide the popover and there is no visual clue or hint to prompt that behavior.*

After testing a few alternatives with real estate agents we implemented our popovers as follows. You can see it in action on a test page at http://mondoflyers.com/uitest

  1. We use a slightly modified link style for popovers (we simply used a smaller version of our normal link style to suggest ‘sotto voce’ though some sites use a dotted underline to good effect).
  2. We require a click (not hover) to display the popover.
  3. When the popover is shown, we change the link style and dynamically prefix the link with “Hide:” so it’s clear to the user they can re-click the same link to hide the popover. (Okay, I admit, it’s a pretty crude hack  – arguably excusable only because it works nicely with users.)
  4. The popover is hidden if the user un-hovers (non-tablet users) or re-clicks the link. When the popover is hidden, the link text/style is restored. (Same mea culpa as above re: being a hack.)

Here’s our HAML for the sample links
#app/views/uidemo/uitest.haml.html

%p.popup{:rel=> "pop-click-bottom", :html => true, :title => "Popup", :data => {:content => "This is a sample popup. <i>This sentence is in italics.</i>"}}
Popup on bottom 

%p.popup{:rel=> "pop-click-left", :html => true, :title => "Popup", :data => {:content => "This is a sample popup. <i>This sentence is in italics.</i>"}}
Popup on left

%p.popup{:rel=> "pop-click-right", :html => true, :title => "Popup", :data => {:content => "This is a sample popup. <i>This sentence is in italics.</i>"}}
Popup on right

%p.popup{:rel=> "pop-click-top", :html => true, :title => "Popup", :data => {:content => "This is a sample popup. <i>This sentence is in italics.</i>"}}
Popup on top

Here’s (non-refactored, ugly, but easy to grok) javascript for one of the four popover handlers

#app/assets/javascripts/enable_popovers.js

$('[rel*=pop-click-bottom]').popover({trigger: 'manual', placement: 'bottom'}).mousedown(function(e) {
        var txt = $(this).text();
        w1 = txt.substring(0,6);
        if (w1 == "Hide: ")
        {
          $(this).popover('hide');
          $(this).html (txt.substring(6));
          $(this).css('color', '#08c');
        }
        else{
          $(this).popover('show');
          $(this).html('Hide: ' + txt);
          $(this).css('color', '#985DCC');
        }
        e.preventDefault();
}).mouseout(function(e) {
        var txt = $(this).text();
        w1 = txt.substring(0,6);
        if (w1 == "Hide: ")
        {
          $(this).popover('hide');
          $(this).html (txt.substring(6));
          $(this).css('color', '#08c');
        }
        e.preventDefault();
}).hover(function(){
  $(this).css('cursor', 'pointer')},
  function(){
  $(this).css('cursor', 'auto')});