Search code examples
htmlcssformsvalidation

Lazy Evaluation of the :invalid selector


Normally the :invalid selector is evaluated instantly : The element will be styled immediately with :invalid for example if a value is required as soon as the page loads:

input:invalid {
  border: 10px solid red;
}
<form>
<p> Go red only after I focused and blurred away </p>
  <input required placeholder="you must type something" />
</form>

Would there be a workaround for this so that the evaluation happens only after the user interacts with the form? (typically, after the first focus / blur). I understand this is standard browser implementation behavior so we're likely looking for a workaround here.

Minimal JS is OK although I don't want to do JS validation.


Solution

  • Surely. Instead of setting the required attribute prematurely, you can mark items with something (a required class in this case) and program the events you want to trigger the adding of the required attribute (blur in this case):

    function myBlur() {
        this.setAttribute("required", null);
    }
    
    function myFocus() {
        this.removeAttribute("required");
    }
    
    for (let item of document.getElementsByClassName("required")) {
        item.addEventListener("blur", myBlur);
        item.addEventListener("focus", myFocus);
    }
    input:invalid {
      border: 10px solid red;
    }
    <form>
      <input class="required" placeholder="you must type something" />
    </form>

    In the example above I'm adding the required attribute on blur and removing it on focus, so it will not yell at users if they are removing the content while the item is being focused, but will be complaining whenever the item loses focus while not having a value.