これは CSS Programming Advent Calendar 2012 の 21 日目の記事です。がすでに 22 日になってしまいました。ごめんなさい。
7 日目の記事(ドラッグをキメる) で、input
要素の value
の値は「CSS で検知できない」と書きましたが、嘘です。ごめんなさい。
Client-Side Form Validation の仕組みを無理やり使います。
input
の pattern
属性と :valid
, :invalid
疑似クラスで、特定の文字列のみに反応してスタイルを適用できます。
pattern
属性に正規表現を指定すると、それと input
の値がマッチした時のみ :valid
疑似クラスのスタイルが適用されます。
Form Validation については、JavaScript API なども含めた詳細な解説が HTML5 Rocks にありました。
:(in)valid
疑似クラスはモダン PC ブラウザ全てで動きますが、IE 10 と WebKit では少し注意が必要です。
次のように隣接・間接セレクタを使うと、対象要素の再描画 (repaint) が適切に行われないことがあるようです(開発者ツールで再スタイルすると適用されます)。
input:invalid ~ #hoge { /* 効かないことがある */ }
しかしこれは CSS だけで回避できます。 常に CSS Animations を走らせて、強制的に再描画してやればいいのです。
@keyframes redraw { /* -webkit- も必要 */
from { min-width: 1px; } /* min-width に限らず何でもいいが、*/
to { min-width: 2px; } /* 描画に影響の少ないものが使いやすい */
}
#hoge {
-webkit-animation: redraw 1s infinite;
-ms-animation: redraw 1s infinite;
}
CSS で極端なことをするとたまに再描画の問題に引っかかりますが、すべてこの方法で解決できました。 7 日目の Demo 3(ドラッグでスライドを切り替える) や 14 日目の Demo 1(sticky の親を transform) でもこっそり同じパターンを使っています。
Form Validation の話に戻ります。
WebKit では、::-webkit-validation-bubble
系の疑似要素を使って、フォームを送信しようとしたときに出るメッセージをまるまる書き換えられます。
ただしこの辺りは独自実装ですし、今後変更されるかもしれません。
以下は Windows 7 + Chrome 25 dev で確認しました。
<style>
#target::-webkit-validation-bubble-heading {
/* デフォルトのメッセージを消去 */
display: none;
}
</style>
<input id="target" pattern="一致させるパターンを書く" required
title="ここに代わりに表示させたいメッセージを書く">
しかしいまの方法では、valid か invalid かの 2 通りの状態しかなく、とても「フォームの値を読んでいる」とは言えませんね。
Firefox ではフォームの値を直接は読めませんが、@document
ルール を使ってクエリ文字列を処理できます!
これはもともとユーザスタイルシートでの使用を想定していたようですが、Firefox 6 で実装された @document regexp()
ルールで、ドキュメントの URI が正規表現とマッチしたかどうかでスタイルを振り分けられるようになりました。
@document
ルールは CSS4 に延期されたので、まだまだ他のブラウザに載るまで時間がかかりそうです……。
ksk1015 さんの 15 日目の記事での方法によって、時間を乱数のように使って CSS でランダム性を実現できるのでした。
さらに実は、時間に依らないランダムな数も CSS だけで作り出すことができます。
@document
ルールと、RSA 暗号鍵を生成する keygen
要素を組み合わせます。
- Demo 5. すごろく(Firefox のみ)
あがる部分が margin 相殺でうまくできないかと思いましたが、間に合いませんでした……。min-width でやりました
毎回暗号鍵を生成する時間がかかって使い物になりません。
まさか keygen
も、こんなくだらない用途に使われるとは思ってもいなかったでしょう。
めでたし、めでたし……。
次はきむらあつとしさんです。