You have identified the exact failure, and it has a well-established answer: do not validate before the input could reasonably be complete.
The email field is the clearest case. Every valid address passes through a long sequence of invalid states on the way to being typed. Showing an error during that sequence is not information — the user knows they have not finished — it is just noise, and worse, it trains people to ignore the error area entirely. By the time you have a real error to show, the red text has become furniture.
The standard pattern that avoids this:
- Validate on blur, when focus leaves the field. That is the earliest moment at which "incomplete" and "wrong" are distinguishable.
- Once a field has shown an error, re-validate on every keystroke. Now live feedback is genuinely helpful, because the user is trying to fix a specific thing and wants to know the instant they have.
That asymmetry is the whole trick. Late on the first error, immediate on every correction.