プレースホルダー周りのセレクター

フォームのプレースホルダー周りのセレクターは、今のところウェブ標準では:placeholder-shown擬似クラスとして定義されている。つまりプレースホルダー文字列が表示されているかどうかという状態を反映するもの。どうやらInternet Explorer 11はこれを踏襲した実装のようだ。対してChrome 31やFirefox 25では擬似要素として実装されており、プレースホルダーそのものを表現するセレクターになっている。できることはあまり変わらないのだけど、例えば背景画像の開始位置とかでズレが生じる。

以下のようなスタイルがあたっている入力ボックスにプレースホルダーが表示されているとする。

input[type="text"] {
  padding-left: 1em;
}

左に1emの余白を取っているだけ。この場合、入力文字列は1emのところから表示されることになる。プレースホルダー文字列もそれに習う。こういった要素にプレースホルダー周りのセレクターを使って、何も入力されていない時だけウォーターマークを背景画像として表示しようとすると以下のようなCSSになる。

input[type="text"]::-moz-placeholder {
  background-image: url("watermark.png");
  background-repeat: no-repeat;
  background-position: left center;
}

input[type="text"]::-webkit-input-placeholder {
  background-image: url("watermark.png");
  background-repeat: no-repeat;
  background-position: left center;
}

input[type="text"]:-ms-input-placeholder {
  background-image: url("watermark.png");
  background-repeat: no-repeat;
  background-position: 1em center;
}

input[type="text"]:placeholder-shown {
  background-image: url("watermark.png");
  background-repeat: no-repeat;
  background-position: 1em center;
}

Firefox 25やChrome 31ではプレースホルダーそのものを指すので、背景画像はpaddingプロパティーの内側に配置される。対してInternet Explorer 10では擬似クラスのようなので、背景画像はpaddingプロパティーの外側に配置されるため、両者を揃えようとする場合はpaddingプロパティーの値と同じだけbackground-positionプロパティーで位置を調節する必要がある。ウェブ標準でも多分同じだろう。

Internet Explorer 10についてはbackground-originプロパティーでcontent-boxを指定してやると揃えることができたので、CSSのコードは増えるもののそっちの方が素直かもしれない。ウェブ標準でも多分これで大丈夫。

background-positionプロパティー以外にもいくつか互換性のないプロパティー等があるので、そのままコピペは通用しない。まだ人類には早いセレクターと言えるかもしれない。とは言うもののinput要素は置換要素で擬似要素を適用できなかったりするので、早いところ統一されて使えるようになってくれないとどうにもしようがなかったりもする。


なお、プレースホルダー周りのセレクターを使うルールセットは、プリフィックス付きであったり未実装のセレクターを使うことになるのでまとめることはできない。いわゆる不明なセレクターというアレ。こういうの見るとベンダー拡張プリフィックスなくす派に改宗したくなる気もする。