yukey

precepts-we-love-the-keyboard.md

We love the keyboard๐Ÿ”—

A lot of modern UI is focused on the mouse and touchscreen.

Yukey isn't.

Yukey is for you who wants the keyboard to be extremely powerful.

Not just an afterthought. Not just tabindex navigation. And not just hotkeys for the poweruser who's memorized them. Yukey is for a keyboard that's deeply empowered, and always with affordances so that it's immediately usable even in low-familiarity situations.

keyboard capabilities must be obvious๐Ÿ”—

The number one step to making the keyboard empowered is deceptively simple: Exactly what the keyboard can do should always be obvious.

The mouse gets some natural affordances about advertising its capabilities. People mouseover on things and expect popups and tooltips, and they click anything clickable and see what happens. That's great; and none of it transfers trivially to the keyboard.

But nonetheless, if there's one thing any kind of usability demands: it's that interactable elements must look interactable; the ways to get to them must be obvious; and there should be as many affordances as possible that make it clear what interacting with an element will do. That whole list applies to doorknobs in the physical world and buttons in a UI, both the same.

So, for any aggregated piece of UI that can be interactable, Yukey's design has to run through these questions and make sure they have reasonable answers:

  • Where's the focus? Needs to be visible.
  • Is the focused element interactable? Needs to be obvious.
  • Interactable in which ways?
    • Toggle?
    • Activate and causes action?
    • Activate and makes a whole new piece of UI?
    • Can it also be interacted with for just more info, like a tooltip?
  • Interactable with what triggers?
    • Is the enter key gonna do stuff?
    • What's the norm for the spacebar, does it usually do the same stuff?
    • Is this text entry or nah?
    • Are there other hotkey norms that we'll train users to expect?
  • What's going to end up focused next if the arrow keys are used? Needs to be obvious.
    • Is the thing to my {direction} focusable? Needs to be obvious.
    • Is the thing to my {direction} interactable? Needs to be obvious.
    • If I move my focus to the {direction}, can I move it back to the {inverse_direction} afterwards, and if I do so, do I end up in the same place? This one is a little flexible, but weigh it.
  • Are there other focus jump affordances? Make them visible.

buttons always show their hotkey๐Ÿ”—

Hotkeys should always be immediately discoverable.

If the hotkey matches a letter in the button's label, that letter is a different color.

Otherwise, there's a visual position about 70% of the way over to the right where the hotkey letter is shown in the same significant color.

If a button is a complex button with more than one concept of activation, then it shows an icon with this meaning in the same 70% offset position.

keyboard actions must be high power and low finger-stretch๐Ÿ”—

Yukey's quest to make the keyboard ultra-powerful means that hotkeys are often single keystrokes. E.g., it's not "==alt-K==", it's just "==K==" when in a context where "k" is a valid hotkey.

Yukey is effectively what you might call "modal" (in the same sense that "vim is a modal editor").

(That being said, Yukey's modes should be a lot more obvious than e.g. Vim's, because Yukey does a lot more visual emphasis about where your focus is, and the "mode" isn't a mode so much as just a property of where your focus is.)

more norms๐Ÿ”—

Yukey introduces several norms that, once you've seen one Yukey interface, means you can navigate all Yukey interfaces more rapidly.

activation๐Ÿ”—

Many elements are activatable. Nuff said.

the enter key does activation๐Ÿ”—

Also nuff said. The Enter key doing activation is common.

Yukey is not pointlessly weird, so the Enter key also does activation in Yukey.

Except in multi-line text entry. There, the Enter key adds a linebreak.

so does the spacebar๐Ÿ”—

The spacebar usually triggers activation, just like the enter key (at least, as long as whatever's focused isn't a text input area).

Whacking the biggest button on the keyboard should usually do the most highly-afforded action in context. That's usually whatever the Enter key is already doing. But text entry dominates: if we're doing text entry, then that's what we're doing, and the space key is for inserting spaces.

info pops๐Ÿ”—

One norm that Yukey standardizes, specifically to counter the "mouse has tooltips, keyboard has whoops" problem:

On almost any element that's activatable, and also many that are purely informative: the hotkey i means "info, please", and does something similar to raising up a tooltip.

what goes in info pops?๐Ÿ”—

User's choice.

It's a whole element. It can contain a short sentence or phrase, or a whole... anything.

But broadly, it should probably be on the short end of the range.

what doesn't go in info pops?๐Ÿ”—

An info pop should used for novel details about the element in question, not reiterations of general interaction guides.

For example, an info pop should not:

  • Name hotkeys. Yukey has a whole visual language for that already.
  • Describe global norms. E.g. it makes no sense to describe what Escape does, nor what arrows do. Norms are learned once; narrating them per-element is noise everywhere.
  • Describe what Enter/activation does in generic terms. Enter is activate. This falls under the same admonition against describing global norms, but further: As a UX story in your application, if what activation of an element will do isn't clear, then explaining it in the info pop isn't the right place: a clearer label should be used, or the button is simply too dangerous -- fix that; don't try to hide warnings in the lower-visibility margin notes!
  • Narrate what focus or hover does. By the time the tooltip is open, focus or hover already happened. Describing what already happened would make no sense.

major element types๐Ÿ”—

Yukey introduces some significant element types that may be unusual, but provide an easy and powerful way to compose interfaces while offering massive clarity for understanding how the keyboard can interact with them with nothing more than a first glance.

the megacolumn๐Ÿ”—

Yukey's main UI practice:

Make a whole aggregate UI section act like a single megacolumn.

What's that mean?

  • The granularity of the focus is the row.
  • There is logically one column. (Visually, there can still be two: label and input widget.)
  • There is exactly one interactable element per row.

Limiting? Perhaps. But consider what it gives us:

  • Everything is functionally selectable by using just the up and down arrow keys.
    • That immediately solves most of the capability discovery problems; bam, done.
  • And that means everything else on the keyboard can be seen as usable for the row's interaction. (Left, right, enter: great, sliders, toggles, activation: all clear.)
    • And that means we can route those inputs directly to the inner element of the row, without faffing about with any more selection questions. Isn't that nice?
  • If the whole primary unit of UI on the screen is just one megacolumn... it's just so simple.
    • Seriously, users will love this. They won't even realize how relaxed it makes them, but it does.

And make no mistake: the megacolumn concept can also still be quite flexible. For example: a tree can be still be navigated and treated (mostly, if not entirely) like a megacolumn! The fact that there are visually varying left indents is fine; in terms of the keyboard interactions, there's still a clear ordering of elements, and the up and down arrows can navigate on that basis, and that means a whole lot of good UX that's usable without surprises.

Now. If there's one piece of the UI that's clearly the main gig, at any given time, and that thing is a megacolumn: then, that pretty much guarantees that the user will be able to see and understand where the focus is, and how to move and use it; and also, when we write the code, we've got very little work to do, because everything going on is basically just norms. Isn't that sweet?

what if there's REALLY two controls in this row??๐Ÿ”—

First of all, usually, no, there's not.

But let's say there is. Suppose we've got a piece of UI that contains a list of things. Each item in the list is activatable. But also, each item is removable.

Alright. We can still do most of a megacolumn.

  • Up/down arrows move the focus.
  • In each row, there's the main interactable element, and also a small red X element on the right.
  • Those elements should have the exact same height, so it's obvious they're in the same family.
  • Those elements should not have large gaps between them, so it's obvious they're in the same family. (If there's dynamic content, then that whole area had better have a border, a background, an ellipsis: something.)
  • When switching between rows, the main element should always get the focus. (We don't want it to be too easy to trigger the deletion action.)
  • The right arrow key should move the focus to the deletion button. (This is what the user does if they don't know there's any other hotkeys in play.)
  • If the user correctly guesses that the 'x' key or 'delete' key will trigger delete of a row, then hooray, they're happy.
  • If the user doesn't guess this, but moves the focus to the delete button and presses i, then we make a popup and tell them.

The core concepts of the megacolumn still hold.

a column of megacolumns?๐Ÿ”—

If there's one section of UI that is all about one object, but it has lots of properties, some of which are tightly related to each other, and it's a whole... situation...

Like let's say that list, described in the last section, but this object has two of those lists, and some other properties, too. What do we do?

Still just use a single megacolumn. Just do it.

Use visual gaps, vertically, between sections. But let focus jump across the gap to the next selectable element, exactly as per usual of a megacolumn. It'll be fine. There's a 93% chance that letting the focus jump the gaps will be unsurprising to a user versus whatever other more nested/complicated/stateful thing that's probably your next alternative idea.

tables๐Ÿ”—

Sometimes one legitimately has a 2D table of data.

For a 2D table, megacolumns aren't it anymore. Yukey does indeed have a table component.

It's made with all the usual precepts still in force:

  • The focus? Needs to be visible.
  • What's going to end up focused next if the arrow keys are used? Needs to be obvious.
  • Does a cell have additional interaction capabilities? It needs to look like it.
  • Would it have a tooltip if it was mouseover'd? Then there'd better be a hotkey that does the same.

What changes vs UI parts that get to use the megacolumn approach is that in a table, the left and right arrow keys... you guessed it! They move the focus across cells.

And that means? Yep, sliders don't get to auto-activate with the right and left arrow keys. If there's a slider in a cell in a 2D table, then the user would have to activate the cell before interacting with the slider, and deactivate it explicitly when done and wanting to go left or right in the table, too; or, we'd have to remap other keys to do the slider thing (and then have to figure out how to make that obvious, which... well, so, that's quite nontrivial, so usually this resolves to a "no, then").

But one step further, what do we do with that? Ding ding! Don't put sliders in 2D tables! Because why would we do that, really? It would probably look terrible! And all those decades of UX researchers about "no more than one input region per row" would also be rolling over in their graves! The thing that's hard to do is a thing we shouldn't do anyway; copacetic.

Focus containment and lifecycle๐Ÿ”—

Yukey has a concept of "focus" that is... mostly the normal one. But we have a lot more ways to move it around, rapidly.

Focus is spatial within containers๐Ÿ”—

This has already been hammered a lot in this document: the arrow keys generally do what you'd expect, spatially.

Megacolumns do this, etc, etc.

Focus is tabindex between containers๐Ÿ”—

When there's top level Yukey components, they have tabindex focus.

So, if you put two megacolumns next to each other, you can tab between them.

Each such component remembers where the focus was inside itself, so if you tab back to it, the focus is... where it was.

Focus is a stack within complex elements or modals๐Ÿ”—

Where there are nested components that can receive focus, or where modals are used, then focus acts like a stack that is pushed and popped.

(Modals are... modals. You know them when you see them. The most common example of nested components that can receive focus, if you're following our suggestion to accept the megacolumn into your heart rather than overuse nesting for complex components, is probably text edit elements.)

So in mechanical detail:

  • Activating a component that can receive focus pushes onto the stack, recording the place focus came from.
  • Disengaging that component is a pop: focus returns to where it came from (the row that opened the card, the summary row that popped the overlay, whatever).
  • Pop targets can die (the opener unmounted, the row vanished): in that case, pop skips dead entries and keeps unwinding to the nearest live one.
  • The number of times focus should land on "nothing" approximately zero. Focus falling to <body> is pretty much always a bug, unless truly every piece of UI is gone.
  • When a component is created by some activation event, that new component should (probably) cause a focus push and receive the focus. If the user's action summoned it, their attention is on it; focus follows attention. (Conversely, passive appearances -- data arriving, ambient updates -- should never steal focus. If it did, that would be effectively a race condition in the UI, which we abhor.)
  • Disengaging a component that's a modal generally closes it.
  • The Escape key always has the job of disengaging focus from a component (causing a pop). (The Escape key always has this job; the user should never have to hunt for a close or disengage affordance.)

misc focus details๐Ÿ”—

  • The Tab key should not leave the page and wander into browser chrome. It's odd to me that this is normal in (some?) browsers. I've never in my life wanted it. Yukey makes Tab navigation confined to the page by default.

docs/precepts-we-love-the-keyboard.md ยท 14.4 KiB ยท f791bafcc9