-
Notifications
You must be signed in to change notification settings - Fork 1
/
placeholder.html
275 lines (194 loc) · 22.1 KB
/
placeholder.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
<!doctype html>
<meta charset=utf-8>
<title>プレースホルダとHTML5のplaceholder属性</title>
<meta name=description content="HTML5のplaceholder属性についての説明です。適切なプレースホルダテキストのつけ方についても考えています。">
<link rel=stylesheet href="lilium.css">
<link rel=license href="http://creativecommons.org/licenses/by-nc/3.0/">
<link rel=alternate href="https://github.com/myakura/n/commits/gh-pages.atom" type="application/atom+xml">
<script>
if (!!document.addEventListener) {
document.addEventListener('DOMContentLoaded', function () {
var sec = document.querySelectorAll('body > section[id]');
var h = document.querySelectorAll('body > section[id] > h2:first-of-type');
var toc = '';
var l = sec.length;
while (l--) {
toc = '<li><a href="#' + sec[l].id + '">' + h[l].innerHTML + '</a>' + toc;
}
var nav = document.createElement('nav');
nav.innerHTML = '<h2>目次</h2><ol>' + toc + '</ol>';
document.body.insertBefore(nav, sec[0]);
}, false);
}
</script>
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-26017405-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<body>
<h1>プレースホルダとHTML5の<code>placeholder</code>属性</h1>
<p>HTML5で導入された<code>placeholder</code>属性によって、フォームの入力欄にプレースホルダを設定できるようになりました。さて、この「プレースホルダ」とはそもそもなんなのでしょうか。また、プレースホルダにはどのようなテキストを書けばよいのでしょうか。
<section id=intro>
<h2>プレースホルダってなに?</h2>
<p>フォームの入力欄に、薄い灰色のテキストが表示されているものを見かけます。あのテキストや、テキストを提供する仕組みは、プレースホルダと呼ばれています。
<figure>
<img src="placeholder/safari.png" width=480>
<figcaption>Safariではアドレスバーに“Go to this address”、検索バーに“Google”というプレースホルダが設定されている。</figcaption>
</figure>
<p class=note>「プレースホルダ (“placeholder”)」
とは、「実際のものに代わって現れるもの」を意味します。たとえば、Webサイトのテンプレートを作る際に、実際のページにはないテキストを入れることがあります。日本語では「ダミーテキスト」などと呼ばれますが、英語では “placeholder text” と呼ばれることがあります。ですので、「プレースホルダ」はフォーム関連の専門用語というわけではありません。
<p>プレースホルダは、フォーム入力欄に値がなにも入力されていない時に表示されます。そしてフォームになにか入力されると、プレースホルダは消えてしまいます。
<p>ですので、プレースホルダには「フォームの入力前に、その入力欄に関する何らかの情報を示す」目的があると考えられます。
</section>
<section id=html5>
<h2>HTML5の<code>placeholder</code>属性</h2>
<p>冒頭ではプレースホルダの採用例としてSafariのアドレスバーを紹介しましたが、プレースホルダはOSネイティブのソフトウェアだけのものではありません。近年、Webサイトでも、フォーム入力欄にプレースホルダがあるものを見るようになりました。
<p>Webサイト上のプレースホルダは、これまでJavaScriptによって実装されていました。これはHTMLのフォームにプレースホルダをつける機能がなかったためです。しかし、HTML5では<code>placeholder</code>というそのままの名前の属性が、<code><input></code>と<code><textarea></code>に導入されました。この属性を使えば、JavaScriptなしでプレースホルダを設定できます。
<!--<blockquote cite="http://whatwg.org/html#the-placeholder-attribute" lang=en>
<p>The <dfn id="attr-input-placeholder" title="attr-input-placeholder"><code>placeholder</code></dfn>
attribute represents a <em>short</em> hint (a word or short phrase)
intended to aid the user with data entry. A hint could be a sample
value or a brief description of the expected format. The attribute,
if specified, must have a value that contains no U+000A LINE FEED
(LF) or U+000D CARRIAGE RETURN (CR) characters.</p>
<p class="note">For a longer hint or other advisory text, the <code title="attr-title"><a href="http://whatwg.org/html#the-title-attribute">title</a></code> attribute is more appropriate.</p>
<p>The <code title="attr-input-placeholder"><a href="#attr-input-placeholder">placeholder</a></code>
attribute should not be used as an alternative to a
<code><a href="http://whatwg.org/html#the-label-element">label</a></code>.</p>
<div class="impl">
<p>User agents should present this hint to the user, after having
<a href="http://whatwg.org/html#strip-line-breaks" title="strip line breaks">stripped line breaks</a> from it,
when the element's <a href="http://whatwg.org/html#concept-fe-value" title="concept-fe-value">value</a> is
the empty string and/or the control is not focused (e.g. by
displaying it inside a blank unfocused control and hiding it
otherwise).</p>
</div>
</blockquote>-->
<p>仕様書にある<a href="http://whatwg.org/html#the-placeholder-attribute"><code>placeholder</code>属性の定義</a>を簡単に訳してみました。
<blockquote>
<div class=trans>
<p><dfn><code>placeholder</code></dfn>属性は、ユーザーがデータを入力する際に、彼らを手助けする目的で提示される<em>短い</em>ヒント(単語や短いフレーズなど)を表す。ヒントには、入力例や望まれるフォーマットの説明が当てはまるだろう。この属性を指定する場合、値にU+000A LINE FEED (LF)やU+000D CARRIAGE RETURN (CR)を含めてはならない。
<p class=note>長いヒントやその他の補足情報については、<a href="http://whatwg.org/html#the-title-attribute"><code>title</code></a>属性がより適切である。
<p><code>placeholder</code>属性は<a href="http://whatwg.org/html#the-label-element"><code>label</code></a>の代わりに使うべきではない。
<p>UAはこのヒントを、要素の<a href="http://whatwg.org/html#concept-fe-value">値</a>が空文字列である場合に<a href="http://whatwg.org/html#strip-line-breaks">改行を取り除いた</a>うえでユーザーに提示するべきだ。このとき、コントロールはフォーカスされてない状態であってもよいし、フォーカスされていてもよい。
</div>
</blockquote>
<!--<p class=note>改行文字を含んではならないとあるのに、その後UAは改行を取り除き表示すると書かれているので矛盾しているようにも読めますが、前者は製作者の要件、後者はUAの要件になります。-->
<section id=markup>
<h3><code>placeholder</code>属性の使い方</h3>
<p>使い方ですが、表示したいヒントを<code><input></code>, <code><textarea></code>要素の<code>placeholder</code>属性に書くだけです。
<figure>
<pre><code><input placeholder="<var>プレースホルダ</var>">
<textarea placeholder="<var>プレースホルダ</var>"></textarea></code></pre>
</figure>
<p>これだけ。便利な世の中になりました。
<p>なお、改行を含められない仕様なので、複数行のプレースホルダを<code><textarea></code>に表示することはできません。
</section>
</section>
<section id=onfocus-or-oninput>
<h2>プレースホルダの消えるタイミング</h2>
<p>プレースホルダが消えるタイミングについて、仕様書は「コントロールはフォーカスされてない状態であってもよいし、フォーカスされていてもよい」と、曖昧に書いています。ですので、OSやブラウザによって、プレースホルダが消えるタイミングが違います。なぜこのようなことになったのでしょう。
<p>もともとHTML5仕様書では、プレースホルダはフォーカスが当たったときに消えるものと定義されていました。しかし、OSが提供しているネイティブUIのプレースホルダが、必ず同じ挙動をとるかというとそうではありません。
<p>たとえば、iOSのアドレス帳。検索欄にプレースホルダが指定されているのですが、このプレースホルダはフォーカスした際には消えません。フォーカス時は入力状態であることを示すIビームが、プレースホルダに重なって表示されます。プレースホルダが消えるのは、テキストが入力されたときになります。
<figure>
<img src="placeholder/contact.png" width=480>
<figcaption>iOSのプレースホルダは、フォーカス時ではなく入力時に消える。</figcaption>
</figure>
<p>ところがiOS4までのSafariは、当時のHTML仕様の規定どおり、プレースホルダがフォーカス時に消えるようになっていました。しかし、OS側で提供されているものと違う挙動をわざわざ求めることに理由はありません。むしろ、OSの挙動を尊重する方が筋でしょう。こうして、SafariのレンダリングエンジンWebKitに変更が加わり、<code>placeholder</code>属性の挙動をカスタマイズできるようになりました。
<p>iOS5のSafariでは、プレースホルダが入力時に消えるように改められました。また、OS X LionのSafari 5.1も同様の挙動をとるようになりました。こうした実装の変更を受け、HTML仕様書も定義を改めたという経緯があります。
<p>なお、プレースホルダが入力時に消えるのはiOSやOS X LionのSafariに限りません。Chrome 17以降やFirefox 15以降でも、プレースホルダは入力時に消えるようになっています。
<!--
http://trac.webkit.org/changeset/77639
http://html5.org/r/6782
http://trac.webkit.org/changeset/101848
http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2011-July/032555.html
http://trac.webkit.org/changeset/93146
-->
</section>
<section id=hint>
<h2>どんなテキストが「ヒント」になるか?</h2>
<p>さて、<code>placeholder</code>属性やその挙動についてひと通りわかったところで、ここからは属性のよい使い方について考えます。
<p><code>placeholder</code>属性の目的は、入力する内容について「ヒントを与える」ことです。では、どういったテキストが適切な「ヒント」になるのでしょうか。仕様書の定義をもとに考えましょう。
<section id=long>
<h3>長い文は不適当</h3>
<!-- TODO: example? -->
<p>仕様書で「<em>短い</em>ヒント」と短さが強調されていること、長いヒントは<code>title</code>属性でと促していることもあり、長いヒントは不適当なようです。ただ、どれくらいのテキストが「長い」と判断されるのか、具体的な数値はでてきません。
<p>ここで思い出してほしいのが、プレースホルダの挙動です。プレースホルダはフォーカス時、もしくは入力時に消えてしまいます。つまり、入力しているときにプレースホルダの「ヒント」を見ることはできません。ここから、入力している最中に忘れてしまうような長さ、入力前にパッと見られない長さのテキストは<code>placeholder</code>属性の値として不適切と判断できます。
</section>
<section id=label>
<h3>ラベル代わりの利用はダメ</h3>
<p>仕様書では、<code><label></code>要素の代わりに使うべきではないと書いています。何故いけないかというと、<code>placeholder</code>属性だけではそのフィールドが何のためのものか、視覚的にしか伝わらないことがあるからです。
<p>たとえば、次のように<code><label></code>をつけず、その代わりに<code>placeholder</code>属性をつかったフォームがあるとします。
<figure>
<pre><code><input placeholder="名前">
<input type=email placeholder="メールアドレス">
<button>送信</button></code></pre>
<p><input placeholder="名前"><br><input type=email placeholder="メールアドレス"><br><button type=button>送信</button>
<figcaption><code>label</code>を関連づけず、プレースホルダをラベルとして利用する例。</figcaption>
</figure>
<p><code>placeholder</code>属性をサポートしているブラウザでは「名前」「メールアドレス」という文字が見えます。ラベルを表示する場所を別にとらずにすむため、フォームをコンパクトにしたい場合、プレースホルダはとても魅力的なアイデアに思えます。
<p>しかし、<code>placeholder</code>属性をサポートしていないブラウザではなにも表示されず、何を入力すればよいのかわかりません。また、スクリーンリーダーなど支援技術についても、対応していない場合は何を入力すればよいのかが分かりません。また、入力欄が数多くある場合、入力中に何を入力すればいいかがわからなくなるケースも想定されます。
<p>これは、<code>placeholder</code>をラベル代わりに使うというよりも、ラベルを与えていないフォームがそもそも問題という話です。フォームにはまずラベルをつけましょう。その上で、どうしてもプレースホルダのUIをラベルとして利用したい場合、支援技術や非対応ブラウザで支障が出ないように対応することが必要です。
<aside id=a11y>
<h4>参考: <code>placeholder</code>属性の読み上げ</h4>
<p><code>placeholder</code>属性のアクセシビリティ対応ですが、FirefoxとSafariで属性値の読み上げがサポートされているようです。<!-- ref: https://bugzilla.mozilla.org/show_bug.cgi?id=545817 -->しかし、<a href="http://html5accessibility.com/tests/placeholder-labelling.html">HTML5 placeholder attribute tests</a>によると、両者の読み上げ方には違いがあります。Firefoxでは<code>label</code>が優先されますが、Safariでは<code>placeholder</code>が優先されてしまうようです。また、Firefoxでは、<code>label</code>でラベルとコントロールを囲った場合(<code>for</code>で参照しない場合)、ラベルとプレースホルダがどちらも読み上げられてしまうようです。
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=631591 -->
</aside>
</section>
<section id=example>
<h3>入力内容の例示は効果的な場合もある?</h3>
<p>仕様では、ヒントとして入力例が考えられると書かれています。この例とは、いったいどういったものでしょうか。
<p>会員登録フォームなどで、「山田 太郎」「[email protected]」など、名前やメールアドレスの例を書いているものがあります。
<figure>
<pre><code><input type=email placeholder="[email protected]"></code></pre>
<p><label>メールアドレス: <input type=email placeholder="[email protected]" size=40></label>
</figure>
<p>こうした例は、入力するデータの書式を示すために使われていることが多く、ヒントとして機能しているかどうかは微妙なところです。
<p>しかし、入力する情報が特定のカテゴリに限定されない場合、プレースホルダが有用なヒントとなる可能性があります。
<p>たとえば、<a href="http://maps.loco.yahoo.co.jp/">Yahoo!ロコ地図</a>です。Yahoo!ロコ地図の検索フォームには、「入力例:東京都港区赤坂9-7-1、東京ミッドタウン」「大阪駅 居酒屋」というプレースホルダがあります。どれも場所に関係する情報ですが、「東京都港区赤坂9-7-1」は住所、「東京ミッドタウン」はランドマーク、「大阪駅 居酒屋」はランドマーク周辺の情報と、性質がそれぞれ異なっています。
<figure>
<img src="placeholder/mapyahoo.png" alt=""><!-- TODO: alt -->
</figure>
<p>このプレースホルダによって、検索フォームが少なくとも3タイプの情報を受け付けられることを示せます。これは「ヒント」として適切な情報ではないでしょうか。
<p>しかし、入力例が多すぎる、もしくはテキストが長すぎると、「長いヒント」の項で挙げた「入力時に消えてしまう」ことが問題になってくるでしょう。そういう場合はプレースホルダを使うのではなく、フィールドのそばに併記する方がよいかもしれません。
</section>
<section id=format>
<h3>入力書式の表示はフォームそのものの再考を</h3>
<p>最後に、入力書式です。郵便番号や電話番号は一定の桁数で区切るなど、慣習として使われている形式があります。また、入力する文字について「全角英数」や「カタカナ」など、種類を指示するフォームなどがあります。これらの書式を指示する際に、<code>placeholder</code>属性が使えるのでしょう。
<figure>
<pre><code><label>電話番号: <input size=25 placeholder="半角数字、ハイフン無し"></label></code></pre>
<p><label>電話番号: <input size=25 placeholder="半角数字、ハイフン無し"></label>
</figure>
<p>このようなプレースホルダの使い方は、避けたほうがよいでしょう。なぜなら、テキストを入力するとプレースホルダは消え、書式がわからなくなるからです。フォームが特定の書式を求める場合は、入力欄のそばに常に表示しておくほうがよいでしょう。
<p>もっとも、特定の書式を強制するフォームは不便なものです。住所の数字やハイフンが全角でなかったのでエラーが出た、スペースが半角に変換されてしまい何がエラーなのかわからなかったという経験はないでしょうか。
<p>振り仮名のひらがな/カタカナ表記、全角/半角英数、電話番号や郵便番号の区切りなどは、プログラムで比較的簡単に変換できます。利用者に入力させ直すよりは、サーバサイドプログラムで変換し、その内容を確認させるほうがよいでしょう。
<p>それができない場合でも、<code>pattern</code>属性を始めとする検証機能を利用する、JavaScriptで検証し、適切な書式であるか否かをフィールドの横に表示するといった方法も考えられます。プレースホルダで表示するよりも、もっとよい情報の提示方法があるはずです。
</section>
</section>
<section id=polyfilling>
<h2>JavaScriptによるプレースホルダの実装は必要か</h2>
<p>Webサイトのプレースホルダの中には、JavaScriptが使われているものが数多くあります。<code>placeholder</code>属性が導入される前から存在していたものや、古いブラウザでもプレースホルダを表示したいという要求に答えたのでしょう。
<p>JavaScriptでのプレースホルダ実装は、大きく分けて2つのパターンがあります。
<ul>
<li><code>value</code>属性にプレースホルダテキストを書き、入力欄のフォーカス・入力に応じて属性値を書き換える
<li><code>label</code>や<code>title</code>属性にプレースホルダを記述し、スタイルシートで入力欄の上に重ね、フォーカスに応じて表示・非表示を切り替える
</ul>
<p>すでに有志によって、多くのライブラリやjQueryプラグインが公開されているので、古いブラウザにプレースホルダをつけるのは簡単です。
<p>ですがここで、その意義についてちょっと考えてみましょう。プレースホルダはヒントを与えるもので、それがなくてもフィールドに何を入力するかは、プレースホルダなしでも理解できなければいけません。
<p>ちまたにあるプレースホルダつきフォームを調べてみると、「検索ワードを入力」や「Search」といったものが多いことに気づきます。しかしこれらの情報は、フォームのデザインやラベルから自明であり、「ヒント」として有用かどうかは疑問が残ります。こうした情報のために、小規模ではありますがJavaScriptを書くこと、ライブラリを読み込む必要性はあるのでしょうか。
</section>
<section id=summary>
<h2>まとめ</h2>
<p>プレースホルダはフィールドに入力する情報に関し何らかの「ヒント」をユーザーに伝える役割があります。ヒントはプレースホルダの使われる文脈に依存するので、利用する際にはフォームや入力欄について考える必要があります。
<p>プレースホルダは場合によって、良いヒントを提供してくれるかもしれません。しかし、プレースホルダの情報はあくまでヒントです。プレースホルダがなくなると目的が分からなくなるようなフォームであってはいけません。ですから、まず問題なく機能するフォームを作ったうえで、必要あらばプレースホルダでヒントを与えるという設計フローがよいでしょう。
</section>
<footer>
<address>by <a rel=author href="http://profiles.google.com/117261322300109492957">Masataka Yakura</a></address>
<p class=update>Update: June 2, 2012
</footer>