Tutorial

Styling Form Inputs in CSS With :required, :optional, :valid and :invalid

Published on September 2, 2020
authorauthor

Alligator.io and Andy Hattemer

Styling Form Inputs in CSS With :required, :optional, :valid and :invalid

Introduction

When it comes to validating the content of input fields on the frontend, things are much easier now than they they used to be. We can use the :required, :optional, :valid and :invalid pseudo-classes coupled with HTML5 form validation attributes like required or pattern to create very visually engaging results. These pseudo-classes work for input, textarea and select elements.

Input pseudo-classes

Here’s an example of the pseudo-classes at work. Let’s start with this HTML markup:

<form action="#">
  <input type="text" placeholder="First Name" required>
  <input type="email" placeholder="Email" required>
  <input type="text" placeholder="Nickname">
  <input type="text" placeholder="Favorite pizza topping">
</form>

And let’s apply the following styles:

input {
  border: 2px solid;
  border-radius: 4px;
  font-size: 1rem;
  margin: 0.25rem;
  min-width: 125px;
  padding: 0.5rem;
  transition: background-color 0.5s ease-out;
}
input:optional {
  border-color: gray;
}
input:required {
  border-color: black;
}
input:invalid {
  border-color: red;
}

Here’s the result:

See the Pen vYGeLYw by alligatorio (@alligatorio) on CodePen.


In the demo above, <input type="email" is an HTML5 input type that tells browsers to expect an email address. Because we are also using the required attribute, modern browsers will only set the input to :valid when a valid email is entered.

Adding the :focus pseudo-class

Let’s make things even more interesting by also styling according to the focus state and add a background image and color depending on the validity state and only when the input is in focus. We’ll use the same HTML markup.

Here’s our updated CSS:

input {
  border: 2px solid;
  border-radius: 4px;
  font-size: 1rem;
  margin: 0.25rem;
  min-width: 125px;
  padding: 0.5rem;
  transition: border-color 0.5s ease-out;
}
input:optional {
  border-color: gray;
}
input:required:valid {
  border-color: green;
}
input:invalid {
  border-color: red;
}
input:required:focus:valid {
  background: url("https://assets.digitalocean.com/labs/icons/hand-thumbs-up.svg") no-repeat 95% 50% lightgreen;
  background-size: 25px;
}
input:focus:invalid {
  background: url("https://assets.digitalocean.com/labs/icons/exclamation-triangle-fill.svg") no-repeat 95% 50% lightsalmon;
  background-size: 25px;
}

There are two key changes in the above CSS:

  1. input:required:valid applies a success state only to required inputs. Because technically, optional inputs are always valid.
  2. input:focus:valid' and 'input:focus:invalid apply to inputs only when they are focused.

And here’s the result:

See the Pen gOrGPxP by alligatorio (@alligatorio) on CodePen.


You could be tempted to add content instead using ::before or ::after on the input, but unfortunately that’s not possible on input elements. One trick would be to have a sibling span element that has content added depending on the validity of the input. Something like this:

input:focus:invalid + span::before { ... }.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Alligator.io

author


Default avatar

Community Builder

Then: Learned to build the internet on DigitalOcean Community. Now: Building DigitalOcean Community on the internet.


While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
1 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

As a beginner I found this really helpful and I still want to learn more. Can you help me with some tutorial on how to apply Adding the :focus pseudo-class in a <select><option disabled selected>Select categories</option><option>CSS</option><option>HTML</option></select> after choosing an option to its dropdown and change somehow the border color? Thanks!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.