Miro accessibility: Introducing keyboard navigation for board objects

Stefano Baldan
Miro Engineering
Published in
6 min readAug 2, 2023
A computer keyboard with an antique bronze key on top.
Keyboard support is a key aspect of accessibility.

Last month, Miro reached a significant milestone in accessibility by introducing keyboard navigation for all objects on the board. This new feature allows users to navigate around Miro boards using the keyboard instead of a mouse or trackpad, making boards more accessible to a lot of people with different needs.

To accomplish this, we were inspired by the familiar keyboard navigation logic found in standard web pages. Not only did we implement the logic in our boards, we also identified additional ways to adapt the concept to our infinite canvas.

Why is keyboard navigation important?

Accessibility is a core value for us at Miro, and keyboard navigation plays a vital role in making our platform inclusive for everyone. We understand that not all users can rely on a mouse due to vision or motor impairments, and other needs. By introducing keyboard navigation, we empower these users to navigate Miro using their preferred input device.

Here’s the cool part: keyboard navigation actually enhances the user experience for everyone — not just users with specific needs. For instance, power users and expert typers can now create new content and navigate across existing objects without switching between different input devices. It’s all about creating an environment that works for everyone, regardless of their abilities.

What made it possible?

Enabling keyboard navigation required a significant revamp of our keyboard input system. Together with our Design System team, we undertook a massive refactoring effort to standardize and centralize the way we handle keyboard shortcuts on Miro boards. This is one of the core elements that we now use to bring back contextual information and interactivity to the objects rendered in the HTML canvas.

Unlike regular HTML elements, which are fully described and accessible by the browser in the DOM, canvas objects are rendered as plain pixels on the screen, with no additional semantics. Having the ability to define custom keyboard shortcuts allows us to trigger arbitrary actions on the board with just a couple of key presses, including changing the selected objects according to a set of predefined rules. This is exactly what it means to perform keyboard navigation on board objects!

Let’s dive into the details of these navigation rules, exploring the logic that we decided to implement and why.

Linear navigation: explore the board like a web page

The World Wide Web has a very long and prolific history of standards and best practices on the subject of accessibility. As a result, our team has the luck and privilege of standing on the shoulders of giants.

For decades, native keyboard users on the Web have been accustomed to pressing Tab to move forward to the next active item, and Shift + Tab to move backward to the previous active item. Translating the same logic to Miro boards was therefore a natural choice. But in order to know what the next and previous objects are at any time, we needed to linearize our 2D space, establishing a unique order for all objects on the board. Several usability tests, involving both sighted and non-sighted users, pointed us toward the adoption of a natural reading order. In other words, people seem to like exploring the space of the board the same way they would read a written page. For most western cultures, this means moving from left to right, and then from top to bottom.

In a grid of perfectly aligned objects, natural reading order is easily accomplished by sorting all objects on the Y-axis, grouping them by rows, and finally sorting rows on the X-axis. However, doing the same proved to be a pretty complex task in the fuzzy 2D space of a Miro board, where objects can have very different sizes and alignments.

We obtained good results by considering two objects as part of the same row — not only if they share the exact same vertical coordinate, but also if there is any vertical overlap between them. This sorting logic can be implemented as a pairwise comparison, which is a much more efficient technique than checking all objects against all other objects on the board. Unfortunately, it is also unstable, which means that the sorting output can change depending on the initial ordering. Simply applying a stable pre-sorting step solves the issue.

2D navigation: move freely on the infinite canvas

Being able to navigate a Miro board like a web page is nice, but Miro’s canvas is not a typical web page — it’s an infinite 2D space where objects can be placed freely. Because of that, we also wanted to enable users to find the closest object to the left, right, top, or bottom of any selected object. We realized that using a simple Euclidean distance to find the closest object wouldn’t have worked, because it doesn’t account for directionality. We had to somehow find a way to adjust the distance, making it appear shorter for those objects aligned with the desired direction, and longer for those pointing towards different directions.

The dot product between two normalized vectors looked like a good candidate. It starts from 1 when the two directions perfectly converge, goes to 0 when they’re perpendicular to one another, and reaches -1 when they are completely opposite. Dividing the Euclidean distance by the dot product clamped between 0 and 1 gave us exactly what we needed: shorter distances for aligned objects, and infinitely larger ones for divergent objects. Some fancy math, but it does the trick!

Hierarchical navigation: conquer structured content

Imagine exploring a board containing thousands of objects, going through them one by one… Sounds like a nightmare, right? That’s where hierarchical navigation comes into play. To have quicker access to the information we need, we can leverage the fact that certain objects act as containers for other objects. Concrete examples include frames, Kanban boards, user story mappings, and selection groups. Think of it like having a folder structure on your board. When you enter a container, you focus only on the objects within it. Exiting a container takes you back to the objects at the same nesting level.

Objects in a Miro board are usually stored as a flat list, so we had to build this hierarchical structure on top of it. Our keyboard navigation currently uses only containers and contained objects to define its parent and child relationships, but other strategies could be explored in the future. Relationships among objects could be defined using other parameters and properties, such as the objects’ positions or colors. The hierarchical tree is recomputed whenever one or more objects on the board change, and it is cached in memory as long as the board remains unchanged to improve navigation efficiency.

Putting it all together

The aforementioned strategies for keyboard navigation are available for every object on the board, using the same intuitive set of shortcuts:

  • Tab or Shift + Tab allows you to navigate to the next or previous object in the current nesting level;
  • Cmd (or Ctrl on Windows) + the Arrow keys are used to navigate to the closest object in the desired direction, within the current nesting level;
  • Cmd + Shift + Arrow Down enters a container object, taking navigation one level deeper;
  • Cmd + Shift + Arrow Up exits a container object, moving navigation up one level.
Keyboard navigation demo of board objects in Miro.

Future work: building a more accessible Miro

We’re not stopping here. We are continuously improving the accessibility of Miro for all users. For individuals with low or no vision, we understand that keyboard navigation alone isn’t enough. We’re actively refining screen reader announcements, gathering feedback from native screen reader users, and making improvements based on their input. Our goal is to provide a top-notch, non-visual experience on top of our current visual output.

Furthermore, we’re exploring solutions to offer even more direct access for users with motor impairments. We’re investigating ways to unlock voice control access to board objects, providing an even smoother interaction experience. We believe in creating an inclusive environment where everyone can navigate and collaborate seamlessly.

Thanks for reading, and please share your feedback in the comments. Your input is very valuable to us, and will help us a great deal in our mission to improve accessibility in Miro!

--

--

Stefano Baldan
Miro Engineering

Frontend Software Engineer at Miro. I love coding, playing the mandolin, digital arts, and sports.