CSS :valid Selector

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

Definition and Usage

The :valid pseudo-class matches a form control whose current value passes HTML constraint validation.

Pair it with :invalid for success and error feedback. Constraints come from attributes like required, type="email", pattern, min, and max.

Standard-track.

Baseline widely available since July 2015. Not deprecated, experimental, or non-standard.

Accessibility a11y

Do not rely on green alone for “valid.” Add text or an icon so meaning is not color-only (MDN / WCAG).

CSS Syntax

syntax.css
:valid { … }

Often scoped: input:valid, input[type="email"]:valid.

Selector Parts

PartMeaningTry it
:validCurrent value passes all constraintsTry it
type / requiredBuilt-in constraints that drive validityTry it
min / maxNumeric range constraintsTry it
:invalidOpposite state when a constraint failsTry it

How to Use :valid

Add HTML constraints first, then style the valid state.

  1. Put constraints on the control (required, type, min/max, pattern, …).
  2. Style :valid for success feedback.
  3. Style :invalid for errors.
  4. Keep a non-color cue (label text or icon) for accessibility.
GoalTypical selector
Any valid control:valid
Valid emailinput[type="email"]:valid
Valid numberinput[type="number"]:valid
Error state:invalid

Live Preview

Edit the fields. Borders update with real :valid / :invalid rules as you type.

Demo form

Email must look like an address. Age must be 18–60. Empty required fields are invalid.

Result

Green border = :valid · Red border = :invalid

CSS Examples

Each snippet focuses on :valid. Use Try It Yourself for a live editor.

Example 1 — Pair :valid with :invalid

Show success and error borders on the same form.

CSS
<style>
  :valid {
    border: 2px solid #15803d;
  }

  :invalid {
    border: 2px solid #b91c1c;
  }
</style>

<input type="email" required value="[email protected]">
<input type="email" required value="not-an-email">
Try It Yourself

How It Works

  1. Add constraints. type="email" and required define the rules.
  2. Match success. A real email address matches :valid.
  3. Match failure. not-an-email matches :invalid.
  4. Style both. Green vs red borders give instant feedback.

Example 2 — Style a Valid Email Field

Scope the pseudo-class to email inputs only.

CSS
<style>
  input[type="email"]:valid {
    border: 2px solid #15803d;
  }
</style>

<input type="email" required value="[email protected]">
Try It Yourself

How It Works

  1. Narrow the target. input[type="email"] limits the rule.
  2. Require a value. required makes empty invalid.
  3. Pass the format. A normal email string matches :valid.
  4. See the cue. The green border confirms success.

Example 3 — Valid Number in Range

Use min / max so only in-range values look valid.

CSS
<style>
  input[type="number"]:valid {
    border: 2px solid #15803d;
  }

  input[type="number"]:invalid {
    border: 2px solid #b91c1c;
  }
</style>

<input type="number" min="18" max="60" required value="25">
Try It Yourself

How It Works

  1. Set the range. min="18" and max="60" define allowed values.
  2. Enter a good number. 25 sits inside the range.
  3. Match :valid. The control gets the green border.
  4. Out of range fails. Values like 10 match :invalid (and often :out-of-range).

Edge Cases & Pitfalls

If validity styles surprise you, check these first.

empty

Empty optional fields can be valid

An empty optional input with no failing constraints often matches :valid. That is expected.

load

Styles can appear before the user types

Empty required fields match :invalid on load. Prefer :user-valid / :user-invalid when you want feedback only after interaction.

color

Do not use color alone

Add text or icons with green/red borders so color-blind users still understand the state.

server

Client CSS is not enough

Always validate on the server. Users can bypass HTML constraints.

required

Required ≠ valid

:required means mandatory. Validity still depends on the value passing every constraint.

Browser Support

:valid is a browser CSS pseudo-class for constraint validation. Node.js, Deno, and Bun do not evaluate it.

✓ Baseline · Widely available since Jul 2015

:valid

Supported in Chrome 10+, Firefox 4+, Safari 5+, Edge 12+, Opera 10+, IE 10+. Works with HTML5 form constraints.

97% Global support
Google Chrome 10+
Full support
Mozilla Firefox 4+
Full support
Apple Safari 5+
Full support
Microsoft Edge 12+
Full support
Opera 10+
Full support
Samsung Internet 4+
Full support
Internet Explorer 10+
Full support
:valid Widely supported

Bottom line: Safe for production forms. Pair with :invalid and accessible, non-color cues.

Key Takeaways

  • Role: matches controls whose value passes HTML constraints.
  • Common use: green success borders next to :invalid errors.
  • vs :required: mandatory vs actually satisfying the rules.
  • Pitfall: empty required fields look invalid immediately on page load.

One line: use :valid to style form controls that currently pass their HTML constraints.

Frequently Asked Questions

It matches form controls whose current value passes HTML constraint validation — for example a well-formed email, a number in range, or a filled required field.
Constraints such as required, type (email, url, number), pattern, min, max, minlength, and maxlength. If every constraint passes, the control matches :valid.
:required only means the field is mandatory. :valid means the current value satisfies all constraints. An empty required field is :required but :invalid.
Yes. Use :valid for success cues and :invalid for error cues so users get clear feedback while typing.
Optional empty fields with no failing constraints typically match :valid. That is normal HTML constraint behavior.
Widely available since July 2015: Chrome 10+, Firefox 4+, Safari 5+, Edge 12+, IE 10+. It is a browser CSS selector, not a Node.js API.

Next: [attribute]

Select elements based on the presence or value of HTML attributes.

attribute selector →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful