Validation form messages on keypress using pure CSS

Mateusz -

Custom and simple form validation with pure CSS. For this to happen we first need to prepare our form and styles.

<!-- -->
<form>
	<div>
    	<div>
          <input type="text" required placeholder="First Name" />
          <span>First name is required.</span>
        </div>
        <div>
	    <input type="text" required placeholder="Last Name" />
            <span>Last name is required.</span>
        </div>
        <div>
          <input type="email" required placeholder="E-mail" />
          <span>Please provide valid e-mail.</span>
        </div>
        <div>
          <input type="number" min="1" max="150" required />
          <span>Please provide valid age.</span>
        </div>
    </div>
    <p>All inputs are required.</p>
    <div class="button-wrapper">
       <button type="submit">Create</button>
    </div>
</form>
<!-- -->
form input {
  border: 1px solid #000;
  padding: .5rem;
  margin-bottom: 1rem;
  border-radius: 2px;
}

form:has(span, p) {
 color: red;
}

Not the prettiest one but for our purposes it will be just fine.

Form conditions

All inputs are required
E-mail should be valid
Age should be a number between 1 and 150

Form expectations

1. For the First Name and Last Name on keypress the validation message should be hidden and the green border should be applied
2. If an e-mail is valid, the validation message should be hidden and the green border should be applied
3. If an age is between 1 and 150 the validation message should be hidden and the green border should be applied
4. If the form is filled correctly “All inputs are required” message should be hidden
5. If the form is invalid, the Button should be disabled for click event and be red, otherwise the button should be enabled and should not be red anymore

First let’s deal with the first 3 expectations.

/* */
form input:not(:invalid) {
  border-color: green;
  border: 2px solid green;
}

form input:not(:invalid) + span {
  display: none;
}
/* */

Here we use pseudo class selectors :not and :invalid. The first one checks if an element matches the list of selectors given inside brackets. The second one, invalid pseudo class selector checks whether an input, or any another element such as a form or a fieldset value is entered correctly. So in our inputs we have validations like “required”, “email type” and “min” and “max” value for age.

We can read these styles with simple words. If an input is NOT invalid then add green border. Also, if an input is NOT invalid hide span element right next to our input element.

Now let’s add some code to deal with number 4.

/* */
form:not(:invalid) p {
   display: none;
}
/* */

Simply if the form is NOT invalid then select and hide our message.

The last one case, the button element.

/* */
form:invalid .button-wrapper {
 cursor: not-allowed;
}

form:invalid button {
  pointer-events: none;
  background-color: #f00;
  border: 1px solid #000;
  border-radius: 4px;
}
/* */

First of all if we want to change cursor style to for example “not-allowed”, we need to wrap our button inside a div. Because at the same time we want to block click event on this button. We can do this using pointer-events and set value to none but after that, pointer-events will block even cursor change on this element. That’s why we need some kind of an additional layer before blocking click event using pointer-events.

Back to our CSS. Again, if the form is invalid then add new styles to button-wrapper and button.

Summary

It is worth remembering that we have an option to create simple form validation using only pure CSS and HTML.