Elm is not treating DOM objects as the mutable nodes they are. Elm has this immutable abstraction of a node and it’s doing the mutations in a virtual dom implementation.
So, anything that looks like a mutation of the DOM is going to be achieved either by having the view be different in such a way that the virtual DOM generates that mutation OR through ports.
Your use-case here is actually more challenging than expected.
A custom elements approach is running into this virtual dom issue.
However, a ports approach where validity is updated on input change works.