It's time for Penpot to (almost) move away from the DOM

This is super interesting, and we’ll be giving a lot of thought to how we would adopt this at Fastr where we’re using Penpot as the design canvas and publishing directly to the web rather than in a developer handoff flow.

I’ve been keeping track in develop for the past few weeks since @diacritica pointed me to your exciting new direction here, but I haven’t been able to figure out exactly how you plan to tackle accessibility in the viewport.

Content accessibility for ADA / WCAG / EN 301 549 web standards is critical, and that’s always a thing I worry about when someone is switching rendering technologies. I know the DOM is awful and browser support for SVG isn’t great. wasm + canvas can be a pixel-perfect black box that’s an exciting new area to explore, but assistive tools are really slow to catch up to new rendering technology. For moral, equitable, and legal reasons we all need to be super respectful of that.

So how are you guys planning to tackle that and keep the viewport accessible to screen readers / assistive tools that a user may require to discover and interact with elements in the viewport? Will you continue rendering DOM text elements floated within the canvas? Will you be able to support tab-index for users navigating without pointing devices, to navigate and position non-text elements?

I think it might be possible to achieve accessibility by layering an invisible DOM over the viewport that is presented to screen readers and provides keyboard interactivity, perhaps call it an accessible_viewport that is designed along a parallel render path to viewport_wasm. Or will viewport be preserved indefinitely with a commitment that there’ll never be functionality in viewport_wasm that users of viewport can’t experience?

That last one seems like kind a bummer because you would have done all this work to get to wasm without really breaking free from the DOM, but that’s the core challenge here! Accessibility concerns make it really hard to be on the web and not use the DOM. :thinking:

2 Likes

Hi Ryan, I’ll try to give some clarity on your concerns.

I haven’t been able to figure out exactly how you plan to tackle accessibility in the viewport.

Our goal with the new renderer is to provide the same functionality (and that includes keyboard navigation and shortcuts) as with the current one, but offer better performance.

Accessibility has many aspects, however, and poor performance might leave a Penpot file unusable or very frustrating to work with. The new canvas-based engine is not about being “pixel perfect”, it’s about allowing people to work with complex designs without bad performance getting in the way of common operations like panning, zooming, dragging shapes, etc.

Accessibility in Penpot is an area, however, that we need to improve overall, and it’s not just about the viewport render engine.

I think it might be possible to achieve accessibility by layering an invisible DOM over the viewport that is presented to screen readers and provides keyboard interactivity

While this could work, but given our resources and our small team size, I’m afraid it’s out of our reach. We can’t afford to maintain two viewports at the same time.

1 Like

Our goal with the new renderer is to provide the same functionality (and that includes keyboard navigation and shortcuts) as with the current one, but offer better performance.

I love this goal, but the definition of “same functionality” must specifically include “navigation and access to screen readers.” And unfortunately that requires that you are presenting semantic DOM elements to the browser (at a minimum this includes aria labels, alt text on graphics elements, tab order that matches the visual presentation, and HTML text).

Performance is not a legally mandated requirement for accessibility, thus we can’t defensibly argue we’re improving accessibility by making an app more performant. But we (Kaleidos or anyone else who hosts Penpot) do incur specific legal liability in the US, Canada, and the EU if we offer a web application that can’t be navigated and understood by screen readers. And they only speak DOM.

I would love to know more about the specific accessibility uses cases you might be referring to. Expect a DM soon! Since this is a relevant topic of its own, I suggest we keep this thread to (mostly) discuss the technical work around this move.

Building up a separate DOM is the only way to achieve a11y on canvas at the moment, like Flutter is doing that (sample material_3_demo). And for the future AI could that :wink:

Hey @girafic I can’t find the separate DOM in that material demo you posted (just <canvas>). Could you send me a message (so we keep this thread on topic, as @diacritica suggested) to point me in the right direction? Thanks!

Btw, regarding this :

Building up a separate DOM is the only way to achieve a11y on canvas at the moment

Let’s keep in mind that Penpot’s viewport (what we are trying to render in a <canvas>) is a visual representation of data that is already available somewhere else in the DOM: in the layers tree, in the inspect tab in the SVG-based HUD overlay on top of the viewport (what renders the ruler guides, path node handlers, bounding boxes for selected elements…), etc.

Cheers,
Belén

@ladybenko in this example it’s deactivated by default, but there is a hidden button (with aria-label=“Enable accessibility”). You could activate that by typing $0.click() in the console or via screen reader (VoiceOver on Mac). Then you’ll see the generated content in flt-semantics-host.

1 Like