Validate forms with just CSS? Yes, it’s possible!
Form validation is often handled with JavaScript, but did you know CSS can do a lot of the heavy lifting?
It works thanks to 4 built-in pseudo classes:
:valid→ The input meets all constraints.:invalid→ The input fails validation.:user-valid→ The input is valid and the user has interacted with it.:user-invalid→ The input is invalid but only after the user typed something and left the field.
You can also define validation rules directly in HTML using attributes like required, type, and pattern.
CSS selectors combined with these pseudo-classes allow you to style form elements based on their validation state. You can show or hide messages, change input borders, or visually guide users as they type.
Regarding browser support:
:valid&:invalidhave more than 96%:user-valid&:user-invalidhave a bit more than 90%
This approach isn’t a full replacement for JavaScript validation, but it’s a powerful way to enhance forms with minimal effort.
Codepen link: https://codepen.io/theosoti/pen/ogNZzdJ
<div class="field">
<label for="email">Input Email</label>
<input
id="email"
required="required"
aria-describedby="input-message"
type="email"
pattern="[^@\s]+@[^@\s]+\.[^@\s]+"
/>
<ul class="validation" role="list">
<li data-matches="valid">🔵 Input <code>:valid</code></li>
<li data-matches="invalid">đźź Input <code>:invalid</code></li>
<li data-matches="user-valid">🟢 Input <code>:user-valid</code></li>
<li data-matches="user-invalid">đź”´ Input <code>:user-invalid</code></li>
</ul>
</div>
input:user-valid {
--state-color: green;
}
input:user-invalid {
--state-color: red;
}
input:valid + .validation [data-matches="valid"],
input:invalid + .validation [data-matches="invalid"] {
display: block;
}
input:user-valid + .validation [data-matches="user-valid"],
input:user-invalid + .validation [data-matches="user-invalid"] {
display: block;
}
input {
--state-color: black;
CSS validation patterns are excellent for immediate feedback, but they should complement real form validation logic. Keep messages clear and state changes gentle so users understand how to recover quickly.
For production forms, test keyboard order, disabled states, and validation messages with realistic labels. Native behavior should remain intact while visual polish improves.
If you liked this tip, you might enjoy the book, which is packed with similar insights to help you build better websites without relying on JavaScript.
Go check it out https://theosoti.com/you-dont-need-js/ and enjoy 20% OFF for a limited time!