placeholder 属性でテキストボックスにヒントを書く

HTML5 で、placeholder 属性というものが追加されている。これはフォーム部品の初期値を指定するようなイメージだが、value 属性と違って、任意のテキストが入力されると非表示になる、いわばフォーム部品のヒント文言を書くための属性だ。

<!-- こんな風に使う -->
<input type="text" placeholder="電話番号を入力してください">

Placeholder とは、代用語、とか、代替物、とかいう意味で、プログラミングにおいては「後で正式なモノを挿入するための仮の場所」みたいなイメージで使う。

項目名や見出しを表現するのであれば、placeholder 属性ではなく label 要素を使用するべき。

また、placeholder 属性のユーザビリティ・アクセシビリティの視点での是非については色々あるみたい。

  1. 消えるプレースホルダテキストはユーザーの短期記憶に負荷をかける
  2. ラベルがないと、フォームの送信前にユーザーが自分の入力内容をチェックできない
  3. エラーメッセージが出たときに、問題の解決方法がわからない
  4. 入力フォーム内にカーソルが入るとプレースホルダテキストが消えるのは、キーボードで移動するユーザーをイライラさせる
  5. 入力済みの入力欄が目につきにくい
    • ユーザーの目は空の入力欄にいく。
  6. ユーザーがプレースホルダを自動入力されたデータだと勘違いする恐れがある
    • プレースホルダテキストを手動で削除しなければならない場合がある

  1. デフォルトの薄い灰色のプレースホルダテキストはほとんどの背景に対してコントラストが弱い。視覚障害のあるユーザーは色のコントラストが弱いとテキストが読みづらくなる。
  2. 認知や運動機能に障害のあるユーザーにかかる負担がさらに重くなる。
    • すべてのスクリーンリーダー(画面読み上げソフト)がプレースホルダテキストに対応しているわけではない。

一番いいのは、いつでも見ることのできる明快なラベルを空の入力フォームの外に置くことである。
また、ヒントや説明はずっとそこに出ているべきで、入力欄の外に置くのがよい。

ひとまずこれらの問題は置いといて、とりあえず便利な機能があるっぽいのだから使ってみよう、ということで以下にデモ。

5つほど置いてみた。

CSS でのスタイル指定

現状は標準の擬似クラス :placeholder-shown が効くブラウザが少ない。

現時点では、以下のベンダプレフィックスで指定する。

Firefox の場合、コロン2つで擬似要素扱い (Ver 18 以前はコロン1つで書いていた)。また、ブラウザのデフォルトスタイルに opacity プロパティが指定されている (値は .54 らしい) ので、それを解除しておく。

なお、ベンダプレフィックスを用いたプロパティは、カンマ区切りで複数指定すると有効にならないので、同じスタイルを指定する場合でも別々に書く必要がある。これは不明なセレクタが登場した時の動作によるもの。

JavaScript での再現

Vanilla JS (All About Version)

「Vanilla JS (All About Version)」と題したものは、style 属性と onfocus・onblur 属性を HTML 中にゴリゴリ書いちゃう、昔ながらのやり方。All About で2007年に公開されていた記事のコードを参考に、プレースホルダと同じ文字列を入力した時に文字色が変更されないバグを修正して作成。

なお、このままだとプレースホルダの文言がフォーム送信されてしまうので注意。

Vanilla JS (Use Title Attribution)

「Vanilla JS (Use Title Attribution)」は、title 属性の値を使って placeholder 属性のように動作させる方法。HTML 側は title 属性の記載のみで、全て JavaScript で操作する。以下の jQuery 版でもそうだが、初期値や初期状態の文字色などを変数に抱えておくという作り。

title 属性を使うというアイデアは ah-placeholder という jQuery プラグインより。

こちらも、Submit 時の処理が一切ないので、プレースホルダの文言がフォーム送信されてしまうことに注意されたし。ah-placeholder プラグインではその問題も解消している。

jQuery

jQuery で書いてみましたバージョン。以下のサイトのコードを参考に一部書き換えたモノ。

上述のサイトのコードでは「placeholder 属性がブラウザで有効なら何もしない」ようにしていたり、「Submit 時に placeholder 属性の値を送信しないようにする」ための制御もしている。ブラウザが placeholder 属性に対応しているのであればブラウザの処理に任せ、対応していない時だけ自前のスクリプトで操作、という方が都合が良いだろう。