おい、最近フォームのバリデーション実装で、赤線の波線やエラーメッセージの出し方に頭を悩ませてないか?「あー、JavaScriptでリアルタイムに正規表現回して、スパン要素を動的に挿入して…」なんて泥臭いDOM操作、まだ自前で頑張ってたりしないだろうな。
確かにそれも一つの手だが、実はモダンCSSには、ブラウザのネイティブな文法チェック機能をそのままフックしてスタイリングをブチかませる、ヤバい機能がひそかに用意されている。それが今回解説する `::grammar-error` 擬似要素 だ。
現場の中級エンジニアなら「CSSで文法エラー?」とピンと来るかもしれない。今回はこのマイナーだけど知っておくとドヤ顔できる仕様の裏側と、実務での現実的な落とし所を、シニアの俺がみっちり叩き込んでやろう。
—
`::grammar-error` 擬似要素とは何か?
一言で言えば、「ブラウザが『おい、ここ文法おかしいぞ』と検知したテキスト範囲」に対して、ピンポイントでスタイルを適用できる超尖った擬似要素だ。
身近なところで言うと、メールの入力欄、あるいはリッチテキストエディタ、さらには `contenteditable` な要素の中で、スペルミス(`::spelling-error`)や文法ミス(`::grammar-error`)があったときに、OSやブラウザが自動で赤や緑の波線を引いてくれる機能を見たことがあるはずだ。あれの見た目を、なんと俺たちの手でコントロールできるようにするための仕様がこれだ。
どんな仕組みで動いているのか?
ブラウザの裏側の話をしよう。
ユーザーがテキストを入力すると、ブラウザ(あるいはOSのテキストエンジン)はバックグラウンドで言語解析(スペルチェックや文法チェック)を行う。そこで「おや、この構文はおかしい」と判定された文字列のチャンク(範囲)に対して、ブラウザが内部的に特別なフラグ(マーカー)を立てる。
CSSの `::grammar-error` は、その内部フラグが立ったテキストノードの範囲をセレクタとして捉え、スタイルを上書きするためのフックなのだ。
—
使えるプロパティの「厳しすぎる制限」に注意しろ
さて、ここで現実的な話をしよう。「おっ、じゃあ派手に背景色変えたり、アイコンを絶対配置したりして派手にエラーを目立たせてやろうぜ!」と思ったそこのお前。
残念、それはCSSの仕様(Selector Level 4)によって厳しく制限されている。
セキュリティやプライバシー(ユーザーが何を入力しているかをCSSで過度に変形・抽出させないため)、そしてブラウザの描画パフォーマンスの観点から、`::grammar-error`(および兄弟分の `::spelling-error`)で使用できるCSSプロパティは、極めて限定的だ。
基本的には以下のプロパティ群しか効かないと思っておいた方がいい。
- `color`(文字色)
- `background-color`(背景色)
- `text-decoration`(下線・波線の種類、色、太さ)
- `text-shadow`(テキストの影)
- `text-emphasis-color` などのテキスト装飾系
派手なレイアウト変更やボックスモデルの改変はできない。「テキストの装飾をブラウザ標準のものから、うちのデザインシステムの色に合わせる」くらいの心構えでいるのが、実務における正しいマインドセットだ。
—
現場で即コピペして試せる実践コード
百聞は一見にしかずだ。実際に手を動かして挙動を確認してみよう。
以下のコードをそのままお前のローカルの `.html` ファイルに貼り付けてブラウザで開いてみてくれ。
文法・スペルチェック疑似要素のテスト
※注意: ブラウザやOSのネイティブな辞書・文法エンジンに依存するため、環境によってエラー検知の挙動が異なります。特に日本語環境では発動しにくいため、検証時は英語等で試してください。
このコードをブラウザ(ChromeやSafariなど)で開いて、英語の変な文言(例: “He go to store yesterday.” などの文法ミス)を入力してみろ。OSやブラウザがそれを検知すれば、設定した通りの深紅の背景色や波線がスーッと浮かび上がるはずだ。JSを1行も書かずにこれが実現できるのは、なかなかロマンがあるだろ?
—
実務で使う上での「厳しい現実」とシニアからのアドバイス
さて、ここまで読んだアグレッシブな後輩なら、「よっしゃ、社内のCMSのテキストエディタ案件でこれ全面採用しようぜ!」と言い出すかもしれないが、ちょっと待て。チーフとして、現場の冷徹な現実も伝えておかなければならない。
1. 環境依存の塊であること
`::grammar-error` は、ブラウザが内蔵している、あるいはOS(macOSのテキストシステムやWindowsのSpelling APIなど)が提供しているチェッカーに完全に依存している。つまり、ユーザーのOSやブラウザの設定、言語環境によって、同じコードでも挙動が全く変わる。
2. 独自のカスタム文法ルールは仕込めない
「うちの会社の固有の専門用語を文法エラーとして検知させたい」といったビジネスロジックベースの制御は、このCSS単体では不可能だ。あくまで「ブラウザがエラー認定したもの」にしかスタイルが当たらない。
じゃあ、いつ使うべきなのか?
- 汎用的なリッチテキストエディタや、ブログ投稿画面などの「標準的なブラウザのネイティブ機能の見た目を、自社ブランドのデザインシステムに調和させたい」というケース。
- 過剰なJavaScriptのオーバーヘッドを嫌い、アクセシビリティやネイティブの機能を最大限に活かしたい極限のパフォーマンスチューニングの現場。
こういうピンポイントな要件においては、`::grammar-error` は最高の切り札になる。
CSSの進化は早い。こうした一見するとマイナーな擬似要素の仕様の裏側まで理解していると、いざというときに「おっ、この要件ならあのCSSの仕様が使えるぞ」と引き出しからスッとコードを出せるスマートなエンジニアになれる。
さて、理論はここまでだ。さっそく次のタスクにこの知見を組み込んで、周りのメンバーをうならせてやれよ!

コメント