# リアルタイムバリデーション表示のCSS実装

> 入力し終えてから初めてエラーを表示するメール入力欄。:user-invalidと:has()により、JSなしで「入力前に怒らない」検証UIを作ります。

- カテゴリ: フォーム
- URL: https://www.css-dictionary.com/recipes/validated-input/

## HTML

```html
<form class="signup">
  <div class="field">
    <label for="email">メールアドレス</label>
    <input type="email" id="email" required placeholder="you@example.com" autocomplete="email" />
    <p class="error" role="alert">メールアドレスの形式で入力してください</p>
  </div>
  <button type="submit" class="submit">登録する</button>
</form>
```

## CSS

```css
.field {
  width: 280px;
  margin-bottom: 12px;
}

.field label {
  display: block;
  margin-bottom: 4px;
  font-size: 13px;
  font-weight: 600;
}

.field input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border: 1px solid #cbbfa5;
  border-radius: 6px;
  background: #fff;
  font: inherit;
}

.field input:focus-visible {
  outline: 2px solid #b0413e;
  outline-offset: -1px;
}

.field input:user-valid {
  border-color: #4a7c59;
}

.field input:user-invalid {
  border-color: #b0413e;
  background: #fdf3f2;
}

.error {
  display: none;
  margin: 4px 0 0;
  font-size: 12px;
  color: #b0413e;
}

.field:has(:user-invalid) .error {
  display: block;
}

.submit {
  padding: 8px 20px;
  border: 1px solid #b0413e;
  border-radius: 6px;
  background: #b0413e;
  color: #fff;
  font: inherit;
  cursor: pointer;
}
```

## 仕組みの解説

:invalid はページ表示直後の空欄にも一致してしまい「入力前から赤い」フォームになりがちです。:user-invalid はユーザーが操作を終えた（フォーカスを外した）後にだけ一致するため、体験を壊さずに検証結果を出せます。エラーメッセージの表示は、親要素側から .field:has(:user-invalid) で子の状態を参照して切り替えます。正しく入力し直すと :user-valid で緑の枠に変わります。

## 実装のポイント

エラー文はrole="alert"にすると表示された時点でスクリーンリーダーが読み上げます。文言は「何をどう直すか」まで書くのが親切です。

## AIに依頼するときの文例

required付きメール入力欄のバリデーション表示を作ってください。:user-invalidで入力後のみエラースタイルを適用し、:has()で親要素からエラーメッセージ（role="alert"）の表示を切り替えてください。JSは使わないでください。

## 使っているプロパティ

- [pseudo-user-valid](https://www.css-dictionary.com/property/pseudo-user-valid.md)
- [pseudo-has](https://www.css-dictionary.com/property/pseudo-has.md)
- [border](https://www.css-dictionary.com/property/border.md)
- [display](https://www.css-dictionary.com/property/display.md)

