CSS Form Validation with pseudo-classes
Tags: css, forms, webdev, validation
Published: 2020-11-05 00:06:40

Everyone has come across that "boring" form that forces you to fill in a field and marks it with a bright red to show what was missing, or that the filling is wrong. "Wrong!"

It is boring, but it is increasingly necessary. You can no longer receive data that is invalid. This ends up involving high costs, mainly with the advance of e-commerce and virtual services.

There are now several tools to ease validation and include classes in forms to show errors visually. Several frameworks and libraries have this functionality, in several programming languages. However, I see little mention of the native way CSS offers to address the most common needs.

Believe it or not, CSS has pseudo-classes available only for the visual validation of forms. If you have well-crafted HTML code, using pseudo-classes to your advantage will be quite simple.

### How does it work?

There are attributes in HTML that identify the data type a given field accepts, as well as its status and mandatory filling. Based on these it is possible to treat their appearance.

```html
<!-- Required text field -->
<input id="name" type="text" name="nome" value="" required />
```

For this to work, it is good to remember that there are not only buttons, checkboxes, radios and text fields. There are also other fields, each with its own characteristics and validation, even though they appear the same as a text field.

Below is a list to remember these fields.

```html
<!-- Campos -->
<input type="text" />
<input type="color" />
<input type="checkbox" />
<input type="date" />
<input type="email" />
<input type="file" />
<input type="month" />
<input type="number" />
<input type="password" />
<input type="radio" />
<input type="reset" />
<input type="search" />
<input type="tel" />
<input type="time" />
<input type="url" />
<input type="week" />
```

In the list above I did not include buttons, image, hidden and range, as they are not useful for this example. Let's go straight to the pseudo-classes that can be used for the visual validation of the fields.

#### :required

It will affect a field that is mandatory, that is, that has the `required` attribute. As an example, imagine the following HTML.

```html
<input id="password" type="password" required />
<label for="password">Password</label>
```

To add a required warning text, just make a style like the one below:

```css
input:required ~ label::after {
  content: " (required)";
  font-size: 0.8em;
  color: #000;
}
```

Done. Any label after a required field will have a (required) in its text. In the example above, I didn't use classes, just the name of the markup in the CSS, for the sake of simplicity. The others will follow the same style.

#### :valid and :invalid

Each field, as previously mentioned, has a validation made by the browser itself, according to its type.

```html
<input id="email" type="email" required />
<label for="email">E-mail address</label>
```

Above, an "email" type field is used for an e-mail registration, instead of a normal text field. As we used the right type for the data to be informed, we are free to use its standard validation to change its appearance according to the data filled in:

```css
/* Campo com dados válidos */
input:valid {
  border-color: #090;
}

/* Campo com dados inválidos */
input:invalid {
  border-color: #900;
}
```

With the styles above, the border of the element will be green if the data is valid and red if it is not. Remember that if it is empty and mandatory, it will be considered invalid.

#### :optional

```css
input:optional {
  border: 1px dashed #ccc;
}
```

If the field is optional, the pseudo-class :optional can be used to show this to the user visually.

### Conclusion

Here's a sample of what you can achieve with just a little CSS:

<iframe height="365" style="width: 100%; height: 80vh;" scrolling="no" title="Campos" src="https://codepen.io/elvessousa/embed/gOPRdaE?height=265&theme-id=dark&default-tab=html,result" frameborder="no" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href='https://codepen.io/elvessousa/pen/gOPRdaE'>Campos</a> by Elves Sousa
  (<a href='https://codepen.io/elvessousa'>@elvessousa</a>) on <a href='https://codepen.io'>CodePen</a>.
</iframe>

Perhaps you were unaware of these pseudo-classes or just never used them. The fact is that they have their use cases. Of course, this is just the visual part of the form validation. CSS will not check data before sending it. And if that happens one day, I will be worried!

There are limitations if the data to be sent is very specific, such as number of documents or cards, for example. Therefore, use the validation tool of your choice: the good thing is that you will use it only where you really need it, removing unnecessary logic from your project.

The focus will be more on checking data and information messages than on appearance.

### Links
- [Original post on my blog](https://blog.elvessousa.com.br/en/post/form-validation-css)
- [Can I Use CSS Form Validation](https://caniuse.com/#feat=form-validation)
- [CodePen I made with examples](https://codepen.io/elvessousa/pen/gOPRdaE)

---

If this article helped you in some way, consider [donating](https://www.buymeacoffee.com/elvessousa). This will help me to create more content like this!