Validating a form with CSS (no Javascript required)

Table of contents

Validating forms is one of the most boring tasks that we are used to do as web developers, just because it is something repetitive or maybe because forms are boring. They are quite useful but boring. Everybody knows it. The user that has to fill them knows it and the developer whom has to validate it knows it aswell. In fact, it is something known by the Marketing teams and so that their message to the UXs is “please find more flexible ways” to engage to user, such as just make the email needed to start using the product. The rest will come then.

Validate on the front

First of all, we need to clarify that the best way to validate a form is validating on the front and on the back because they are complementary. We will validate on the back to make sure that the data are as we were expecting so we do not put in a hurry the security of our system, and we use the front as a tool just to help the user to not fail when filling the form, avoiding the users get frustrated, and we will inform if one of the fields is incorrect (ie: date). In sum, we try to avoid they go away.

Build and validate a form with HTML

We can use HTML to create self-explained forms just the tags <fieldset>, <lengend> or <label>, and the attributes [placeholder], [autocomplete] or [aria-label]. Thus, we can create rules for validate the form without JavaSCript using the attributes [required], [pattern], [min], [max], [minlength], [maxlength], etc.

So we end up with a easy to understand form and the best of all iis that we can delegate the validation on the browser. The browser will evaluate if the information the user fills the fields with is valid or invalid, and will show a message according to the rules we would have previously settled. The caveat is that we could not styles these messages.


How the error messages looks like on Chrome


How the error messages looks like on Firefox


How the error messages looks like on Safari

Then the CSS does not valid the form

It is true, we can not say that a form could be validated only with CSS, but we can apply styles to the fields to make the process more cool. So, we can modify the appearance of the inputs where an interactions is happening or happened to make the user feel that the form is modern and kind of awesome.

Styling inputs

We just only need to know 4 key points:

input {
	// Placeholder
	&::placeholder {
		color: $c-placeholder;

	// Focus
	&:focus:required {
		border-color: $c-primary;
		outline: 0 none;

	// States
	&:required:placeholder-shown {
		border: 1px solid $c-border;
	&:required:not(:placeholder-shown):invalid {
		border: 1px solid $c-error;
		color: $c-error;
		box-shadow: 0 0 0 1px;
	&:required:not(:placeholder-shown):valid {
		border: 1px solid $c-success;
		color: $c-success;
		box-shadow: 0 0 0 1px;
	&:required:focus:invalid {
		border: 1px solid $c-error;
		color: $c-error;
		box-shadow: 0 0 0 1px;

Using the pseudo-class selector :required will let us modify only the required inputs preserving the not required unaffected. Then, we have to find the inputs not filled (not dirty) in order to apply a border style because when the inputs are empty the outcome of the validation will be invalid but it is not. Then, we create some styles to apply to the inputs filled (dirty) in the case of :valid or :invalid. Finally, we will take advantage of the native browser’s behaviour that focus the first of the invalid inputs and the create styles merging the required, focused and invalid.

Since the inputs are re-evaluated each time we make a change we could update the status from invalid to valid with an interesting and smooth effect without the need of listen to events with JavaScript


In this demo you could see it in action. A form being validated with HTML5 and CSS


We are fashion victims. We are used to load our applications with tons of third-party libraries or awesome frameworks just to make cool things or write less, but it is a non-sense when they are being used to solve easy problems or avoid using already browser-working native solutions.

We are fashion victims because we follow the tendencies that wraps the technology we work with and at the same time we do not follow its evolution.

Before start coding we used to evaluate which technology or architecture would fit better to our new project, and we should do the same when trying to solve little tasks. It depends on the form (when talking about forms) because it could be very complex, but from my point of view, it is incredible that we could only with 3 selectors make a form look and feel great as if was built with a JavaScript library. So, it is a smartert approach, isn’t it?

comments powered by Disqus

If you find it interesting

If you have any doubt or you want to talk about this topic, if the content or our profiles are interesting to you and you think we could something together, do not hesitate to contact us on twitter or trough the email address