Skip to content

Styling

It’s a common practice to indicate error states with styles, usually with red outlines, red error messages etc.

Input border

input-validity is adding data-dirty attribute after first submit attempt, but it’s recommended to use :invalid CSS pseudo-class to add error styles when input is invalid.

<form action="/submit">
<input
type="text"
required
validation-message="#error"
/>
<div id="error" class="error-box"></div>
<button>submit</button>
</form>

Try to submit empty field and then add some value. Error styles will change to default automatically.

Styling error message

input-validity doesn’t control rendering of error message DOM element - it only update it’s content.

Let’s add some styles to our error message.

<form action="/submit">
<input
type="text"
required
validation-message="#error"
/>
<div id="error" class="error-box"></div>
<button>submit</button>
</form>

As you can see our error message element is visible even without any actual message. It’s recommended to use :empty CSS pseudo-class to handle such situations. No need for conditional rendering, adding or removing DOM elements, no templating.

<form action="/submit">
<input
type="text"
required
validation-message="#error"
/>
<div id="error" class="error-box"></div>
<button>submit</button>
</form>

Styling parent element

When you want to style parent element, for example indicate an error on the parent element such as card, fields group etc, it’s again recommended to just use CSS with :has(). This will reduce need for client side javascript, conditional rendering or class manipulation.

<form action="/submit">
<fieldset>
<label>Provide any value</label>
<input
type="text"
required
validation-message="#error"
/>
<div id="error" class="error-box"></div>
</fieldset>
<button>submit</button>
</form>

TailwindCSS

input-validity pairs nicely with TailwindCSS. Here’s above example styled with Tailwind

<form action="/submit" class="m-2">
<fieldset class="p-4 bg-gray-100 mb-2 rounded border-2 border-transparent [&:has([data-dirty]:invalid)]:border-red-600">
<label>Provide any value</label>
<input
type="text"
required
validation-message="#error"
class="mb-2 border-2 border-gray-200 data-[dirty]:invalid:border-red-600 data-[dirty]:invalid:focus:outline-red-600"
/>
<div id="error" class="empty:hidden text-red-600"></div>
</fieldset>
<button class="bg-blue-600 text-white py-1 px-2 rounded">
submit
</button>
</form>