Category Archives: User Interface

Sibling Rivalry

While working on a new responsive menu, I soon realized the need to be able to close any menu that might be open should the user choose another one. In a wide layout it would look particularly messy and confusing to have multiple menus shown. In a mobile layout that wouldn’t be so bad since there’s an accordion effect. However, the more real estate you can give back to the user the better!

Fortunately, jQuery has a handy selector that will grab all the li elements at the same level as the currently clicked/tapped element:

$(this).siblings().each(function() {
 
 // Animate close
 TweenLite.to($(this).find("ul > li"), speedFactor / 2, { height: 0, opacity: 0, ease: Power3.easeIn });
 TweenLite.to($(this).find(".menuArrow"), speedFactor / 2, { rotation: -90, ease: Power3.easeInOut });
 TweenLite.set($(this).find("ul > li"), { display: "none", delay: speedFactor / 2 });

 // Indicate menu is closed
 $(this).data("menuOpen", false);
});

Similar functionality can and should also be applied to the page as a whole so that pointing somewhere else would close all menus. Or, for that matter, when the user selects an item. Here are the results:

menu_landscape

menu_mobile

Proud to be Back

Run DMCTo borrow from Run DMC:

Listen party people here’s a serious song
It’s right not wrong, I should say right on
I gotta tell you somethin that you all should know
It’s not a mystery it’s history and here’s how it go

While session history management has been around for a few years, it’s not something I’ve needed until recently. Necessity dictates working both with AJAX/Web APIs and SEO as well as the ability to share links via email or social media. And it may well have been that prior to now there could have been gaps in browser coverage. According to http://caniuse.com/#search=Session%20history%20management adoption is widespread. So even an SPA (single-page app) can reasonably mimic traditional web navigation without you having to hang your keister out in the wind as a developer.

After dinking around with a couple HTML5  history navigational examples, and getting bogged down with some unexpected results in my AJAX/WebAPI project I, er, back-tracked and built my own bare-bones navigational example. This covers both real and virtual pages, navigation within and without the page holding the virtual content (e.g. pasting a link or clicking on it from an email or tweet). Feel free to play around and see if you spot any inconsistencies or unexpected behavior.

Navigating from another page (Click on the Virtual page link, then hit any of the buttons or the link back to real.html and the back/forward buttons in the browser. )

See update below!

http://ststates.azurewebsites.net/real.html

Accounts for linking from outside the site:

http://ststates.azurewebsites.net/virt.html?page=2

Looking at Developer Tools > console in your browser will report the history state and what triggered a change (replaceState, pushState, or popState). View the source (including comments) and you’ll see that all three of these are needed to cover the various navigational cases.

Update

Well, not so proud when I found out that just using the out-of-the-box HTML5 implementation of session history management had a nasty problem: Changing the title would also change it in the history. So holding down the back button, for instance, would show the same link for different URLs, e.g. “?page=1” and “?page=2” would share a title. That would truly suck in a production environment where the title is supposed to match a slug.

So I turned to history.js, which solved that problem and (theoretically should work with HTML4, although I don’t have a convenient means of testing that). Additionally, it took care of the problem with Safari popping an event on loading and shortened my code by some 30 lines, simplifying the logic considerably.

http://ststates.azurewebsites.net/virt2.html?page=2

Less is (almost always) more

This morning, I came across a tweet linking to a National Geographic article on data visualization and eye candy, which I emailed to a few friends (when we want to carry on a more in-depth conversation Twitter just doesn’t cut it):

http://news.nationalgeographic.com/2015/09/150922-data-points-visualization-eye-candy-efficiency/

“Find a metaphor, start simple, and build up from there.”

One, who works at an economics research organization, replied with:

“We have lots of tools that allow relatively informed users to explore data and answer questions that they have, but few of our visualizations actually stick to a single story line.  We’re trying to improve the balance of exploratory tools vs. simple, compelling stories.”

My response:

That’s highly similar to the approach often taken with interactive mapping interfaces – either attempting to duplicate desktop GIS functionality or show a particular facet of data with spatial attributes. Finding the balance between them is tricky. Generally, end users want to answer one or two questions though.

The trails web app I linked to recently – https://helenamontanamaps.org/Html5Viewer/?viewer=trails – is about as far as I’d ever go towards the GISFunc side of things anymore (there are a few gee-wiz, that’s cool features like mixed transparency for the base layers…but are they really necessary in most cases? No way).

http://mapbrief.com/2015/01/09/daring-to-build-a-citizen-centric-homepage-the-philadelphia-story/ is one of the best pieces I’ve read on user-focused functionality.

Incidentally, I read that NatGeo article on my phone and many of the visualizations were too small to be intelligible. For some reason, this one on landslides stood out to me as good on the phone (although on my desktop monitor the map background is barely visible):

landslides

A couple days ago, one of these correspondents sent me a link to a draft page showing all kinds of data related to load times, download sizes, CMSes used, and number of subscribers for a raft of news publications. I can’t share that page in its current state but will say that I wrote back encouraging him to make it way simpler. Just ’cause Tableau gives you a kitchen sink toolbox doesn’t mean you have to use it.

 

Ah, the Suspense

Unless you’re going for pinpoint animation timings it’s really pretty straightforward to create timers on a web page…or so I thought. I threw one together – a simple countdown timer that would get passed a duration, a DIV in which to display the time, a formatter function to make the time pretty, and a callback. It worked well. That is, until I tried it on my Windows Phone and happened to exit the browser while the timer was running.

I came back to the test page and the timer picked up where it left off. In some situations, this would be fine. But in my use the timer is meant to be triggered (more or less) at the same time for a group of users (via SignalR). It would be bad if one user got a text message during a 5-minute session, suspended the browser temporarily to check it, and then got an additional 30 seconds or whatever to keep on entering items after the session ended.

Was this just a Windows Phone issue? Nope. I tried it on an iPhone 5S and had the same issue. It makes sense. Phones need to conserve power whenever possible so suspending running code in a browser tab when it’s invisible is logical. I fixed this issue by setting an initiated time, using Math.round(new Date().getTime() / 1000. Each time the timer interval is called (once per second) the current time is gotten (also in seconds) and then the difference is compared to the elapsed time. And, if necessary, the timer’s remaining time is adjusted (by subtracting the suspended time span from the overall duration).

I ran into another minor issue: Hitting the test button that triggered the timer again would result in multiple intervals running. I needed to clear the current interval first. In this case, I decided to store the current interval ID in the display element, using the jQuery data function. After all, it’s the element being affected by the code.

This is the sort of thing that might be papered over easily by manipulating the UI so the triggering mechanism, e.g. a button, can’t be used more than once. But baking this little fail-safe right into the code heads off any unanticipated uses down the road. For example, perhaps the timer might be reset every time a user guesses the correct answer in a game and moves on to another question.

Here’s the complete code for the timer:

See the Pen zxWwOM by Jon Nehring (@stonetip) on CodePen.0

JQuery HTML5 custom attributes

I came across what looks to be a good solution to managing UI elements (visibility, opacity, etc.) without resorting to burying styles in an attached CSS file. With HTML5, you can use custom attributes prefaced with “data-”, e.g:

<h1 data-groups="foo, bar">I have a session code</h1>

<p data-groups="bar">Enter it here to join a session</p>

You can extract that data, for example:

<div id="divNewSession" data-groups="foo">
var groupData = $("#divNewSession").data("groups");

Which would generally only make sense with something specific, such as a the DIV in this example. But you could also act globally on various elements that all share a data attribute, such as making them all invisible. You can even differentiate with keyword searches or a wildcard (contains) search:

// Any element with a data-group attribute containing "foo" will be affected
$("*[data-groups*='foo']").css("background", "black");

// Any element with a data-group attribute only containing "bar" will be affected
$("*[data-groups='bar']").css("background", "red");

Note the * after groups in the first example. This will act on any element even if the data-groups attribute contains more than just “foo”. Also pay careful attention to the use of double vs. single quotes. IE and Chrome didn’t care, but Safari did.

I like this approach because:

  • It’s easy to see the relationship between an element and an attribute
  • The relationship isn’t buried in an external CSS file or deep within a pile of javascript code
  • It doesn’t clutter up a CSS file with miscellaneous styles used just to control temporary states, e.g:
    #divNewSession { visibility: collapse; }
  • It’s flexible. An element might be affected in one case, ignored in another.
  • Use of a custom attribute avoids confusion or collisions with any other code or namespaces

Towards More Positive Ratings and Useful Feedback

The developers of  the Circa News app recently posted an article describing how they’ve successfully increased positive ratings and directed user frustrations to feedback instead. Note, as they point out, there’s no way to do this without having a good app in the first place:

tl;dr: 1) Build a great app, 2) Don’t annoy your users, 3) Ask nicely, don’t beg

This is very personable:

circa_news_feedback

And a positive result:

 “The best part about the above experience is that for those users who are truly not enjoying their experience, they’re giving us their unfiltered feedback.”

I’ve placed buttons for both rating and feedback in the About or Info sections of my apps. The ratings have been good 4.5 stars on average, but light. I do get feedback via email from users asking for features or occasional fixes.

In either case, implementing something similar might trigger more of both – and in a way that doesn’t piss off the potentially favorable reviewer. It is a little sneaky to shunt displeased users off to feedback, but apps do live and die by ratings. If they want to, users can still find the rating button. It gives them a place to vent their frustrations and gives the developer a chance to redress the issues – a win for both.

Read more at https://medium.com/circa/the-right-way-to-ask-users-to-review-your-app-9a32fd604fca

Thanks to Barrett Golding (@hearvox) for pointing me to the article.

Designing a Versatile Logo

Good logo design has always been hard. The number one characteristic of successful logos – ones that stand the test of time – is simplicity. The best example is GE’s logo, which was created in the 1890s and revamped somewhat in 2004:

It’s only gotten harder with the advent of digital media and mobile device screens of all resolutions. On the other hand, tools have gotten better and for those who aren’t artistically-inclined more resources, such as typefaces and icons, are readily available.

Recently, I decided to create a web and app-based service called NoteVote. Basically, if you hate sitting through long meetings, this will be a tool you’ll like. While it may seem odd, one thing I do whenever coining a new name is to test how it will lend itself to branding. Someone else might jump straight into coding but at heart I’m a UI/UX guy.
The first things that came to mind were to include elements such as a note icon and a thumbs up icon, as well as both a logotype (a logo including text) and a stand-alone logo (suitable for app icons, favicons or uses where space is constrained). I also looked through my typefaces and chose to use Banda (the regular weight is free), which is a friendly, clean and well-spaced design (the kind you’d invite your mother to see).  My first iteration was this:
notevote_initial
I sent this around to a few friends – people with varied backgrounds (sculptor, web/app developer, English/writing professor, grass-fed beef rancher and one of my favorite people, Chrysti the Wordsmith – to see what they thought.

The artist was the first to get back to me and his comment was, “I wish there was an alternative yay or nay for the thumb; Facebook has made us all sick of looking at that icon, but I see why you like it—its a clean logo.” So…a few more iterations:

notevote_iterations

There are things I like about these. Yet, aside from the over-used check mark, what they lacked was the humanistic element. Other logos I’ve designed that have worked well have at least suggested that, e.g:
infused
So it was back to the thumbs up. “Talk to the hand!” 🙂 And from there, tweaking various aspects of the design. One thing I wanted to be sure of is that the line weight of the artwork was exactly the same as the fontweight. In Illustrator, this is as easy as converting a character to outlines, selecting a leg, and copy/pasting it, then looking at the reported width:
notevote_n
I also wanted the note icon to look square – like a Post-It. (Never mind that bending the corner is usually associated more with a sheet icon. Sometimes rules are meant to be bent). I started with a square, created the bent corner, then made three significant alterations.
  1. Both logotype and standalone variations
  2. Joining the hand and note icons
  3. Removing the upper left-hand corner

Variations are necessary because, as mentioned, a logo needs to be able to accommodate a variety of branding uses. Joining elements marries the design elements into a cohesive whole. This serves to unite the cognitive concepts expressed in the logo as well as differentiate it from similar designs. Removing the corner was done to counterbalance the break above the n in the logotype variation and to suggest both speed and the notion that once the note-taking part is done it takes a backseat to voting on the best ideas.

Surprisingly, the second proved the most challenging. I had something in mind similar to approaches like this (although I dug this up just now, well after the fact):

postscript_peewee

My first attempts were like this:

notevote_join_1
And that would be fine. I found, however, after printing it out and looking at it on my phone that it didn’t feel quite right. So I did this and digitized the inner curve:
notevote_curve_digitized
That’s some high-tech shinola, there, resulting in:
notevote_join_2
Other considerations are noted here:
notevote_logo_annotated
Going with a single color and ensuring that the artwork is using it properly – i.e. no masks, mixed RGB/CMYK or other colors – means it is effortless to change it to accommodate light or dark backgrounds and to avoid color clashes. The SVG version is tiny and can be used just like this in a web page, meaning it will never be jaggy, regardless of page sizing or screen resolution. Who wants to create endless raster variations?
<img alt=”logosrc=”images/site/notevote_logo_blue.svgid=”headerLogo” />
I hope this helps you with design considerations. Feel free to direct questions my way via  or http://notevote.uservoice.com/ which is also where you can sign up for the NoteVote beta.

Picking the Right Voice for Windows Phone

Recently, I had an interesting problem come up when testing localization (in French and Spanish in my case) in conjunction with letting the user choose a female or male voice in one of my Windows Phone apps (http://www.windowsphone.com/en-us/store/app/fn8/dd72d13d-1a7b-42c4-81d3-adbc98d4b002). The main part of the problem is basically financial, i.e. given the economics of app development it isn’t feasible to localize for many languages, let alone variants (cultures), e.g. whatever dialect of French is spoken in lower, mid-western Upper Volta. Additionally, given the inefficient workings of the Windows Phone store, it takes forever to submit (or even update) an app for each supported language. In my case, I have asked my translators to use a international a flavor as possible to cover as many markets as I can. Localizing into a language will still allow you to reach all the cultures that support the base language, e.g. localizing into Spanish will work for users in Spain (es-es) as well as Mexico (es-mx).

Part of the problem is technical. If you go this route, then when the user selects a gender for an installed voice, the app has to be able to match the appropriate voices from among those installed. With my first approach what I found when testing was that no voices were being selected at all in a device set to Mexican Spanish. The reason became immediately apparent when debugging:

The app was working fine in English because I was looking for a culture name and because en-us was the default culture for the app, it was finding that. But since the Spanish-speaking user is only getting a generic Spanish translation, the app was looking for a culture name of es-mx and blithely skipping over plain ol’ es.

So then I switched to grabbing the two-letter ISO language name instead. That made the app feliz in Español, but now on my device set to American English I was getting a male voice with a British accent when the radio button was set to female.

Another quick debug session and I could see that American voices Mike and Zira had some friends in the house I didn’t know about, including George and Susan from Great Britain and their friends Raul from Mexico and Stefan from Germany. All obviously there to enjoy Cortana’s predictions on the World Cup.

So here’s what can only be described as an amateurish hack to deal with this issue. Well, as my co-workers and I used to tell our boss in a previous job, all our code is “QDC – quick, dirty, or cheap. Pick any two.”

var twoLetterIsoLanguageName = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;

var currentCultureName = CultureInfo.CurrentCulture.Name;

IEnumerable<VoiceInformation> voiceInfos = from voice in InstalledVoices.All select voice;

var localVoices = new List<VoiceInformation>();

// See if any voices match the current culture specifically
foreach (var voiceInfo in voiceInfos)
{
 if (voiceInfo.Language == currentCultureName)
 {
 localVoices.Add(voiceInfo);
 }

 localVoices =
 localVoices.OrderByDescending(v => v.Language).ThenByDescending(v => v.Gender).ToList();
}

// No matches? Go for the generic language instead
if (localVoices.Count < 1)
{
 foreach (var voiceInfo in voiceInfos)
 {
 var primaryLangStr = voiceInfo.Language.Split('-')[0];

 if (primaryLangStr == twoLetterIsoLanguageName)
 {
 localVoices.Add(voiceInfo);
 }

 localVoices =
 localVoices.OrderByDescending(v => v.Language).ThenByDescending(v => v.Gender).ToList();
 }
}

App.StorageSettings.TryGetValue("VoiceGender", out _voiceGender);

_speechSynthesizer.SetVoice(localVoices.ElementAt(_voiceGender));

Drawing an Anatomically Correct Directional Arrow

It’s far down the list of issues I’ve ever dealt with, yet the ubiquitous directional arrow has always bothered me a bit because the blades are too thick. This is because it is naively rendered using the same stroke width. I took a look at it and realized that the proper blade thickness should be based on the blades’ angle. This can be determined mathematically by taking the square root of the cosine, e.g.

clip_image001.gif

So a line that was 3 pixels wide becomes 2.53 pixels wide (3 x .840896). Here’s a schematic showing the construction steps (click or tap to embiggen):

arrow_drawing_schematic_4

The effect is less pronounced at shallow angles, more so at steeper angles (with a corresponding need for correction):

clip_image003.png

Update:

The morning after originally publishing this post, I saw a proper example of one of these arrows…on a North American Van Lines moving truck. Who woulda thunk? But a little analysis of the logo with an arrow overlaid that has blades at a 37.5° angle shows their designer was, uhm, pardon the pun, thinking along the same lines:

NorthAmericanVanLines

NorthAmericanVanLines2

It’s very close to fitting the formula.

Make it Musical

When I first started taking guitar lessons, my instructor told me that while it would be hard at first to sound good (it’s still hard, bro) to “always keep it musical.” What he meant and what I try to explain to my son as he progresses as a guitarist is to make it sound like a song. Don’t get wrapped up in the mechanics or lose the beat.

Yesterday, I was with our other boy and we stopped into Staples to get some school supplies. This was my first opportunity to play around with both an iPad Air and the new Mini, which is the one I’d get if when I start doing cross-platform development for iOS. They are both really nice devices and very light. I had an iPad (3) and the Air blows it away. Yesterday evening toting my Surface to a book seminar I’m part of it felt heavy in comparison.

Yet this was also my first time really experiencing iOS 7. And one thing that struck me is that the animations seemed rather clunky. How could this be? The display tag below it proudly extolled the presence of the mighty A7 processor. It’s not a hardware issue. I was surprised how rough things like the transition between portrait and landscape are. Not to make comparisons too much, but Microsoft did a pretty good job on that in Windows 8.x.

It wasn’t until we were driving home that it struck me what it was. Whoever designed those animations failed to make them musical. I had happened to turn the radio on, which was set to NPR. While I’m not much of a Classical music fan, I appreciate certain composers and pieces. The overture from Verdi’s La Forza del Destino was playing. As it opened, I suddenly pictured in my mind animating tiles and color transitions in time with the music and reflecting the mood of the piece. Feel free to listen to it while you finish reading:

If you’ve ever seen Fantasia or Bruno Bozetto’s parody Allegro Non Troppo then you will have some idea what I am talking about. The next time you make an animation or transition, try setting it to music while you’re working on it. One thing these master composers had down is timing and mood.

In a subsequent post, I’ll show a recent example where I was setting animation and transitions to sound effects for an animated, vector-based splash screen. Ordinarily I wouldn’t add one to an app, preferring to get right down to business, but this is for a game and it’s  also meant to add a little branding and some personality. One thing I found is that visual perception effects the way the user connects sound and sight. Sometimes you have to futz with timing so that a sound either starts earlier or later.