elm / virtual-dom

The foundation of HTML and SVG in Elm.
https://package.elm-lang.org/packages/elm/virtual-dom/latest
BSD 3-Clause "New" or "Revised" License
209 stars 80 forks source link

Node re-use carries over DOM state like :focus #170

Open wildlyinaccurate opened 4 years ago

wildlyinaccurate commented 4 years ago

When DOM nodes are re-used between renders, some of the state is carried over. I made a simple demonstration of this where the button retains its :focus state despite being written as .

Some of the DOM state (focus in particular) is important for accessibility. For people using assistive technology, it can be quite jarring to have the focus appear to move between elements like this.

wildlyinaccurate commented 4 years ago

For what it's worth, React has the same issue when re-using nodes within a component but not when using separate components. Does Elm have the equivalent of that second React example?

pdamoc commented 4 years ago

This is one of the cases where it is recommended to use a Html.Keyed.node. Here is your example fixed with this technique.

wildlyinaccurate commented 4 years ago

I think we're having the same conversation on Reddit. I'm aware that keying the nodes will force a re-render and fix the problem in my specific and contrived example. I don't think it's reasonable to expect Elm developers to a) know that this issue exists and b) know how to use Html.Keyed properly (using it too much affects render performance, using it too little leaks state between unrelated nodes).

What I was hinting at in my previous comment is that other virtual DOM implementations have implicit keying (or enforce explicit keying in certain circumstances) in a way that makes this a non-issue. I think it's reasonable for Elm to attempt to do the same. One way might be for Elm to implicitly key child views based on their function name.