How to make modeler keyboard accessible

Hi there,

I’m new to BPMN.IO. In my project, we’re trying to integrate bpmn.js as a custom BPMN modeler for our users. We’re also trying to make it as accessible as possible. Thus keyboard navigation is an important concern to us. We’re trying to reach the following goals:

  1. Let the user traverse though our BPMN model via TAB or CURSOR navigation
  2. Enable aria-labels to elements in order to support screen readers.
  3. Allow users to open our custom context pad and to traverse and select our custom actions via TAB+ENTER or TAB+SPACE.

I know that it’s possible to create custom elements and even hook into drawShape (see GitHub - bpmn-io/bpmn-js-example-custom-elements: An example of how to support custom elements in bpmn-js while ensuring BPMN 2.0 compatibility.). So I guess, it’s possible to add tabindex and aria-labels to shape elements too - somehow.

Handling key events however, turns out to be a bit complicated (hopefully I’m missing something):

Until now, I found out that after initializing the modeler, one can bind to keyboard events via

this.modeler = new Modeler({
      container: '#canvas',
      keyboard: {bindTo: document.getElementById('canvas')}
      additionalModules: [
      moddleExtensions: {
        camunda: camundaModdle
this.modeler.get('eventBus').on('keyboard.keyup', 10000, (event) => console.log(event));

However, reacting to keyboard events might be difficult that way, because we’re lost in terms of scope. It would be nice to attach keyboard listeners to shape elements or custom actions to get some closure/context.

I would be happy, if anyone could point me to some example, docs or API.

To add the keyboard listeners, you could use the existing Keyboard module. Then, to change the selection, check out the selection module in diagram-js repo.

I think this might be a really cool plugin!

Hi @robert. Welcome to our forum and sorry for a late reply on this one.

Regarding accessibility you have a very good point. There is potential to improve. I’ve personally already looked into parts of this topic a while back, albeit did not find a great solution.

Generally speaking, we should aim to have decent accessibility built into the tool rather than built on top of it. With your help, maybe we can get to a point where we can pick that up as a topic.

As it stands, the diagram editor is not really friendly to screen readers due to two aspects:

  • it not use browser native focus and navigation (this would give us tabbing out of the box), cf. diagram-js#281
  • it does not appropriately label elements using assistive hints

From my point of view we should try to re-use existing technology (i.e. browser / screen reader being aware of focusable elements and so on) as much as possible.

In this regard, an obvious first step could be to add browser native focus handling (i.e. give diagram elements a tabindex="0" property and hook into focus and focus lost events to put our selection on top. The challenges here:

  • How to handle multi selection?
  • How to navigate the diagram in a meaningful (i.e. semantic) way?

Another improvement, if we had browser native focus handling would be to add aria-labels.

  • What would be appropriate labels?

It would be great if you could confirm whether this is a direction that makes sense to you, or whether you were already able to sort things out by building a plug-in.


:1st_place_medal: @nikku

Hi @nikku and all,

sorry for not answering for so long. In the meantime however, in our project we’ve put some time and effort into finding a solution to your points

How to navigate the diagram in a meaningful (i.e. semantic) way?
What would be appropriate labels?

Disclaimer: In our project, we only use a subset of all capabilities. Though we think, our solution could be adopted.

We implemented a solution for a meaningful keyboard navigation and labelling that meanwhile got approved by our A11Y auditors. So now seems to be the right time to share it with you.

Keyboard navigation concept

First, we weren’t happy with the mentioned tabindex=0 approach, since the element order inside the SVG does not match the visible order. This leads to a more or less
chaotic/random ordering when it comes to iterating the diagram via keyboard. That’s why we set tabindex=-1 to all our diagram elements and wrote some custom keyboard event handling logic:
First, our auditors recommended us to use aria-role=application on our canvas in order to indicate that the following interaction would be a custom one.

<div id="canvas" role="application" aria-label="your bpmn control">

All interactive diagram elements that e.g. open a context menu must be of role=button.
When the user’s focus is on our canvas application, pressing ENTER activates interactive keyboard mode. Pressing ESC leaves the keyboard mode.
We defined and implemented the following custom navigation semantics:

Open context menu of element or select context menu action
Leave keyboard mode or close context menu
Navigate to target node of arrow
Navigate to source node of arrow or to source arrow of node
Navigate to next exit arrow of node
Navigate to previous exit arrow of node
Navigate to first exit arrow of node
Navigate to last exist arrow of node

This basically allows end user to navigate the diagram deterministically along the arrows starting with the start node.
Since the custom navigation semantics is not self-explanatory, we added the above description as an a11y hint to our application.

Labelling diagram elements

We introduced a custom legend for our BPMN with domain specific labels. Each node inside the BPMN refers to such a legend entry via aria-details.
Also aria-describedby refers to an element that is only visible to screen readers and describes possible keyboard actions, e.g. the description of an interactive node in our diagram “Left: to incoming arrow. Up/Down: to outgoing arrow (1). Enter: open context menu.”
Each element received a custom aria-label that provides more context about the current node inside the diagram:

  • What’s the type of node I’ve currently focussed
  • What’s the name of it
  • What’s the incoming or outgoing arrows

Accessible context menus

We decorated our context menus as role=menu containing children of type role=menuitem, and gave each menuitem an aria-label e.g.

<div class="djs-popup-body" tabindex="-1" role="menu">
    <div class="entry bpmn-icon-trash" data-id="delete" title="Remove" aria-label="Remove" role="menuitem" tabindex="0">

API Recommendations

Summing it all up, I think could focus on the following work streams in order to improve accessibility:

  • Make use of HTML semantics where possible. e.g. context menus could be implemented as native HTML menus.
  • Provide an easy way to parametrize aria-attributes, like role, aria-details, aria-describedby, aria-label of diagram nodes
  • Ensure the element SVG order corresponds to the visual order such that the text representation, screen readers (like NVDA or Jaws) read out, match the visuals.
  • Natively provide a keyboard navigation algorithm like the one above thus enabling users to interactively explore the diagram

P.S. Unfortunately we didn’t look into multi selection, since this isn’t really (yet) a requirement for our project.

Hope this helps.


Thanks for coming back and sharing your details.

I’ve linked it in related issues and will give your proposals a look. Maybe there is quick wins we can adopt.

1 Like