egui’s web implementation is purely canvas with no DOM (apart from how it handles text input), so for now it’s completely invisible to screen readers. But even once AccessKit supports the web (and even pretending it wouldn’t be a performance sink that undermines half of the purpose of the canvas rendering approach in web apps), it will still be heavily inferior to something done with DOM for almost all types of content.
Some examples: text rendering is awful on some common browser configurations (mine included—Firefox on Linux/Wayland, rendered at 2× scaling and downsampled to 1.5×; the text is extraordinarily fuzzy, and it’s rendering in its own font because I suppose it’s bundling a complete font, shaper and renderer—since I force my own font selections so only the generic font-families work, and I also block all web fonts at fetch time); the font rendering technique means no fallback which means things like emoji would only render if they provided a font that supported that (at present they don’t, and it’s just a nasty technique all round, you want to be able to use local fonts); links are fake, so various interactions can never work correctly (e.g. Ctrl+click and middle-click should mostly open a background tab, and right-clicking should give you the normal context menu); scrolling can’t be done properly and will thus inevitably be extremely obnoxious on most devices; mobile-style pinch zoom cannot be supported.
⸻And I’m just mentioning some of the unfixable problems with this approach; there are more things that are wonky or painful apart from that: things that could be fixed, but where it’s not surprising that they’re broken because that’s a common problem when you throw away almost all of the stuff the platform gives you and try to implement it all from scratch.
I very strongly recommend against using this general approach at all on the web. The web platform just doesn’t provide the primitives required to make it anything other than miserable.
(I’m not speaking against egui for platforms other than web, only for web. The fact of the matter is that functionally you’re fine building a native app with native tech, a native app with web tech, or a web app with web tech, but that building a web app with native tech is a terrible idea that will always be inferior, in important, unfixable ways.)
On the other hand you have Figma and Google Docs as examples of canvas-based applications that work well enough. I admit there are additional challenges to using egui on a Web context, but when you're building a highly interactive application (!), the benefits can outweigh the drawbacks.
When building DOM-based applications that require frequent updates I've always ended up working around browser limitations in awkward ways, e.g. minimizing re-rendering by using redux's relesect.
I decided to use egui because I get to use Rust for the entire stack, but also because it lets me ship a native app without an entire (slow to init) browser.
I can’t speak about Figma, never having used it.
Google Docs I have just now tried. It isn’t like egui.
egui throws away everything the browser gives it, other than a text input element and a canvas element, and does all the rendering itself and dumps it to the canvas as a bitmap.
Google Docs is full DOM for everything other than rendering the document, and it still uses the browser’s text layout and painting facilities. (I say this because I have my browser set to only use my chosen fonts—so for English text, there are only the default font, serif, sans-serif and monospace—and I observe that it renders and shapes everything in my chosen default font, and am mildly disappointed it doesn’t even do a sane fallback, e.g. “Courier New” to monospace, and “Sans Serif” to sans-serif.) Almost all of my criticisms of the egui approach are avoided. Scrolling works fine, because it’s using the DOM for that, so it’s just normal scrolling. Links work fine, because it uses normal links (these are in tooltip-like things when you move the cursor to the link in the normal text flow).
(I retract my remark about mobile-style pinch zoom not being possible in canvas-only, because Google Docs does support it. I can now imagine how it’s done and I’m not sure why I didn’t see it before.)
But I would also remark about Google Docs since I’ve now tried it in edit mode for the first time since canvas rendering: ugh it’s slow. Low throughput, high latency, high jitter. This on a very fast (Ryzen 5800HS), near-idling laptop with a 165 Hz screen and 2× devicePixelRatio. Just try holding a letter down (I have a 40ms repeat rate), and compare the result to the same actions on contenteditable: the difference is stark. It also gets keyboard caret navigation behaviour wrong for my platform (Linux, Firefox), and its behaviour doesn’t match my vague recollection of Windows’ either. (I mean things like where Ctrl+Left and Ctrl+Right stop—whether at the end of one word or the start of the next, and whether to consider punctuation as part of another word or a word on its own; that kind of thing.)
> On the other hand you have Figma and Google Docs as examples of canvas-based applications that work well enough.
At what cost?
Google Docs is run a by a trillion-dollar corporation, they have the resources to rebuild it in canvas.
Figma isn't based on canvas, it's based on WebGL. And here's what Figma had to say about it: "Pulling this off was really hard; we’ve basically ended up building a browser inside a browser... We’ve implemented our own rendering engine" [1]
Good luck getting text to render properly on your own.
Just because there are two great examples made at great cost doesn't mean it's scalable to all other apps.
[1] https://www.figma.com/blog/building-a-professional-design-to...
> Figma isn't based on canvas, it's based on WebGL.
Aren't they the same thing?
And egui also talks about challenges with rendering on browsers using WebGL and WASM: https://github.com/emilk/egui/tree/master/crates/eframe#prob...
Often when people say "Canvas" they mean "CanvasRenderingContext2D", which still lets the browser do all the text rendering. With WebGL you need to do all that yourself.
Just in case it isn’t obvious, egui is WebGL based (like Figma)
> Aren't they the same thing?
Ah. In my mind Canvas refers to the 2D API, https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API
Which is different and separate from WebGL, https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API
(There will be a third different and separate API, WebGPU: https://www.w3.org/TR/webgpu/)
> And egui also talks about challenges with rendering on browsers using WebGL and WASM
Ah. It's good they are aware of this.
> And I’m just mentioning some of the unfixable problems with this approach
I agree that using a canvas instead of leveraging existing accessibility supplied by HTML/CSS/JS and the DOM is an accessibility nightmare.
However, I disagree that canvas accessibility issues are "unfixable". Difficult? Yes. But not unfixable. In my view, the <canvas> element works best in partnership with its wider environment (HTML/CSS/JS and the DOM), not as a replacement for it. With that in mind, we can start to tackle the accessibility issues you raise - fonts, links, interactions, etc.[1][2]
I have an ambition to one day become intelligent enough to understand/code in Rust, and I'm really glad to see that people are thinking about accessibility as a fundamental part of UIs being developed in Rust.
[1] - Which is what my JS 2d canvas library tries to do: https://scrawl-v8.rikweb.org.uk/
[2] - My thoughts on <canvas> accessibility, and how I try to fix them using my library: https://scrawl-v8.rikweb.org.uk/learn/eleventh-lesson/
I am specifically speaking of egui’s strongly canvas-only approach. It doesn’t want partnership with its wider environment, it wants to replace it. In that approach, these issues are fundamentally unfixable.
I’ll focus on the two most obviously significant issues:
① Scrolling. The only complete solution is to draw within scrolling elements. To treat scrolling content distinctly, and allow the browser to act as the compositor. This would require rebuilding egui from the ground up; its current philosophy is just completely incompatible.
② Links. The only complete solution is to use actual link elements. My complaints about scrawl-canvas’s handling of links <https://news.ycombinator.com/item?id=22887235> when you submitted it here 2½ years ago still apply: to get it right, you’ve got to use actual links, placed in the right place, so that that’s what the cursor is actually interacting with the whole time. The difference here from scrolling is that they can be transparent elements on top of everything else. On reflection, I think it might be theoretically possible for AccessKit to achieve this itself in the simplest cases, but that would certainly break egui’s conception of how things should work, and it can’t work generally because of event handling, the possibility of a non-rectangular hit box, and the fact that egui is a compositor (you could have a window completely covering your link).
And so I say: these are unfixable issues in egui’s design.
(I also report strongly negative experiences with every canvas-plus-DOM approach I’ve encountered. They never get everything right, and the duplication required to get things as close to right as possible almost always leaves me wondering why you bothered with the canvas parts in the first place.)
For native, it's pretty awesome, and it's nice that you can get a hint of what it can do by checking out the web demo.
I agree. I just wish that it was paired with a banner along the lines of “this demo works on the web, but egui is focused on other platforms and you probably shouldn’t use it for the web” paired with a link to an article detailing the problems and how unsuitable it is.