CSS :optional Pseudo-Class

The CSS :optional pseudo-class selects form controls that do not require a value before a form can be submitted. It is commonly used with <input>, <select>, and <textarea> elements to distinguish optional fields from required fields.

:optional Syntax

selector:optional {
  property: value;
}

The :optional pseudo-class matches form controls that support the required attribute but are not currently required.

Basic Example

input:optional {
  border-color: #006699;
}

Selects optional input controls, such as a text field without the required attribute.

Select Example

select:optional {
  background-color: #eaf6fc;
}

Styles a select control when the user is not required to make a selection.

Textarea Example

textarea:optional {
  border-style: dashed;
}

Applies a dashed border to an optional textarea.

No Parentheses

The :optional pseudo-class does not accept arguments and is written without parentheses.

How :optional Works

The browser determines whether a form control supports the required state and whether it is currently required. A supported control matches :optional when it is not required.

HTML Example

<form>
  <label for="name">Name:</label>
  <input type="text" id="name" name="name" required>
  <label for="company">Company:</label>
  <input type="text" id="company" name="company">
</form>

CSS Example

input:optional {
  background-color: #eaf6fc;
}

The Company field matches because it is not required. The Name field does not match because it has the required attribute.

Optional Does Not Mean Empty

An optional field matches :optional whether it contains a value or is empty.

Required State

A supported control with the required attribute matches :required instead of :optional.

Independent of User Interaction

The optional state is determined by the control's requirements, not by whether the user has focused, edited, or submitted the field.

Optional Input Fields

Many input types support the required attribute and can match :optional when that attribute is absent.

Optional Text Field

<label for="nickname">Nickname (optional):</label>
<input type="text" id="nickname" name="nickname">
input[type="text"]:optional {
  border-color: #006699;
}

The nickname field matches because it is not required.

Optional Email Field

<label for="email">Alternate Email (optional):</label>
<input type="email" id="email" name="email">
input[type="email"]:optional {
  background-color: #eaf6fc;
}

The email field is optional, but a nonempty value must still follow the email input type's validation rules.

Optional Date Field

<label for="date">Preferred Date (optional):</label>
<input type="date" id="date" name="date">

The date field matches :optional because the user is not required to choose a date.

Optional Checkbox

<label>
  <input type="checkbox" name="updates">
  Receive updates
</label>

The checkbox matches :optional because checking it is not required.

Input Types That Do Not Support Required

Some input types, including hidden, range, color, and button-related types, do not support the required state and therefore do not match :optional.

Select and Textarea Elements

The :optional pseudo-class also applies to <select> and <textarea> elements when they are not required.

Optional Select

<label for="layout">Preferred Layout (optional):</label>
<select id="layout" name="layout">
  <option value="">No preference</option>
  <option value="grid">Grid</option>
  <option value="flexbox">Flexbox</option>
</select>
select:optional {
  border-color: #006699;
}

The select control matches because choosing a specific layout is not required.

Optional Textarea

<label for="comments">Additional Comments (optional):</label>
<textarea id="comments" name="comments"></textarea>
textarea:optional {
  background-color: #eaf6fc;
}

The textarea matches because the user may leave it empty.

Required Comparison

<textarea id="message" name="message" required></textarea>

This textarea matches :required rather than :optional.

Optional State and Values

Adding a value to a select or textarea does not change whether it matches :optional.

The Required Attribute

The HTML required attribute determines whether supported form controls must have a value or satisfy a required selection condition.

Required Field

<input type="text" name="username" required>

This field matches :required because the required attribute is present.

Optional Field

<input type="text" name="nickname">

This field matches :optional because it does not have the required attribute.

Boolean Attribute

<input type="text" name="username" required="false">

The field is still required. The required attribute is Boolean, so its presence makes the control required regardless of the string assigned to it.

Changing the Required State

const field = document.querySelector("#company");
field.required = true;

Setting the required property to true changes a supported optional field into a required field. The browser updates its pseudo-class matching automatically.

Removing the Requirement

field.required = false;

Removing the requirement makes the field match :optional again.

Optional Fields and Validation

An optional field does not require a value, but values entered into it may still need to satisfy other validation rules.

Optional Email Validation

<input type="email" name="alternate-email">

The field can be left empty. If the user enters a value, the browser checks whether it follows the expected email format.

Optional Pattern Validation

<input type="text" name="code" pattern="[A-Z]{3}">

The field may be empty, but a nonempty value must contain exactly three uppercase letters to satisfy the pattern.

Optional Field Can Be Invalid

input:optional:invalid {
  border-color: #c0392b;
}

This rule selects optional inputs that currently fail a validation constraint.

Optional and Valid

input:optional:valid {
  border-color: #2e7d32;
}

An empty optional email field can match both :optional and :valid, provided no other validation constraint makes it invalid.

Required vs. Validity

The :optional and :required pseudo-classes describe whether a value is required. The :valid and :invalid pseudo-classes describe whether the control satisfies its validation constraints.

Styling Optional Field Labels

The :optional pseudo-class matches the form control, not its associated label. CSS can use structural selectors to style labels based on the optional state of nearby controls.

Using :has()

<div class="form-field">
  <label for="company">Company</label>
  <input type="text" id="company" name="company">
</div>
.form-field:has(input:optional) label {
  color: #006699;
}

The label receives blue text when its form-field container includes an optional input.

Adding an Optional Indicator

.form-field:has(input:optional) label::after {
  content: " (optional)";
  color: #666;
  font-size: 0.875rem;
}

Adds a visual optional indicator after the label text.

Explicit HTML Labels

<label for="company">Company (optional)</label>

Including the optional indicator directly in the HTML is generally more reliable for accessibility than relying only on CSS-generated content.

Form Structure Matters

Selectors such as :has() depend on the HTML structure. Keep each label and its control in a predictable container when using parent-based styling.

Related Pseudo-Classes

Several form-related pseudo-classes describe required states, validation, and user interaction.

Comparison

Pseudo-Class Matching Behavior
:optionalMatches form controls that support the required state but are not required.
:requiredMatches form controls that are required.
:validMatches controls that satisfy their validation constraints.
:invalidMatches controls that fail their validation constraints.
:user-validMatches valid controls after the relevant user interaction conditions are met.
:user-invalidMatches invalid controls after the relevant user interaction conditions are met.
:placeholder-shownMatches supported inputs or textareas while placeholder text is displayed.
:read-onlyMatches elements that are not user-editable.

Optional vs. Required

input:optional {
  border-color: #006699;
}
input:required {
  border-color: #c0392b;
}

These rules distinguish optional and required input controls.

Optional vs. Valid

input:optional:valid {
  background-color: #eaf6fc;
}
input:optional:invalid {
  background-color: #fdecea;
}

An optional field can match either validity state depending on its current value and validation constraints.

:optional Specificity

The :optional pseudo-class contributes a specificity of 0-1-0, like other standard pseudo-classes.

Specificity Examples

Selector Specificity
:optional0-1-0
input:optional0-1-1
.field:optional0-2-0
form input:optional0-1-2
.form-field > input:optional0-2-1
input:optional:invalid0-2-1
#contact input:optional1-1-1

Specificity Example

input {
  border-color: #ccc;
}
input:optional {
  border-color: #006699;
}

When both rules match and other cascade factors are equal, the :optional rule takes precedence because it has greater specificity.

Combined Pseudo-Classes

input:optional:invalid {
  border-color: #c0392b;
}

Combining :optional with :invalid increases specificity because both pseudo-classes contribute to the selector.

Practical Uses

The :optional pseudo-class helps distinguish optional form controls without adding extra classes to the HTML.

Optional Field Background

input:optional {
  background-color: #eaf6fc;
}

Applies a light blue background to optional input controls.

Optional Textarea Border

textarea:optional {
  border: 1px dashed #006699;
}

Uses a dashed border to distinguish optional textareas.

Optional Select Control

select:optional {
  border-color: #006699;
}

Styles select controls that do not require a selection.

Optional Field Indicator

.form-field:has(> input:optional) label::after {
  content: " (optional)";
  color: #666;
}

Adds a visual indicator to a label when its field is optional.

Optional Invalid Fields

input:optional:user-invalid {
  border-color: #c0392b;
}

Highlights an optional field when it has an invalid value and the user-interaction conditions for :user-invalid are met.

Limitations

The :optional pseudo-class describes a form control's required state, not its value, visibility, or overall validity.

Not All Inputs Are Eligible

Input types that do not support the required state, such as hidden, range, color, and button-related types, do not match :optional.

Optional Does Not Mean Valid

An optional field can be invalid if a nonempty value violates a validation constraint.

Optional Does Not Mean Empty

Entering a value does not stop a field from matching :optional.

No Automatic Label Styling

The pseudo-class selects the control itself. Labels require separate selectors or explicit HTML indicators.

Disabled Controls

A disabled control can still match :optional or :required according to its required state, even though disabled controls are not validated or submitted.

Read-Only Controls

Read-only controls may be excluded from constraint validation. Their required-state behavior should not be confused with whether users can edit them.

CSS Does Not Set Requirements

Applying :optional styles does not make a field optional. The HTML attributes and form-control behavior determine whether a value is required.

Best Practices

  • Use :optional to style form controls that support the required state but are not required.
  • Combine it with input, select, or textarea to target specific controls.
  • Use :required for required controls rather than relying only on visual styling.
  • Identify optional fields clearly in their labels or accompanying instructions.
  • Do not rely on color alone to distinguish required and optional fields.
  • Remember that optional fields can still fail validation when users enter invalid values.
  • Use :user-invalid when validation feedback should depend on user interaction.
  • Do not assume all input types support :optional.
  • Keep form labels associated with their controls using for and id.
  • Test forms with empty values, valid values, and invalid values.

:optional Example

This example compares required and optional form fields. The Name field is required and receives a standard gray background. The Company and Comments fields are optional and receive a light blue background and blue border.

HTML

<form class="optional-demo">
  <label for="demo-name">Name (required)</label>
  <input type="text" id="demo-name" name="name" required>
  <label for="demo-company">Company (optional)</label>
  <input type="text" id="demo-company" name="company">
  <label for="demo-comments">Comments (optional)</label>
  <textarea id="demo-comments" name="comments" rows="3"></textarea>
</form>

CSS

.optional-demo label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}
.optional-demo input,
.optional-demo textarea {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 10px;
  margin-bottom: 12px;
  border: 2px solid #ccc;
  background-color: #f5f5f5;
}
.optional-demo :optional {
  border-color: #006699;
  background-color: #eaf6fc;
}

Browser Result

Play in Editor

Note: The Company and Comments fields match :optional because they are not required. The Name field does not match because it has the required attribute.

Browser Support

Baseline: Widely available. The :optional pseudo-class is supported in modern versions of Chrome, Edge, Firefox, Safari, and other major browsers. It is part of the established CSS form-state selectors.

For current compatibility information, visit Can I Use? .

Specifications

The :optional pseudo-class is defined in CSS Selectors Level 4 as a form-state pseudo-class. It matches form controls that support the required state but are not required.

Selectors Level 4 - Optionality Pseudo-Classes