本記事では、HTML フォームを (できれば) より美しくするために CSS を使用する方法を学びます。意外にも、これは少しコツがいります。歴史的や技術的な理由により、フォームウィジェットは CSS とうまくかみ合いません。このような難しさから、多くの開発者はウィジェットのルックアンドフィールをコントロールできるようにするために、独自の HTML ウィジェットを作成することを選択します。しかし現代のブラウザでは、Web デザイナーがフォーム要素のデザインをより多くコントロールできます。詳しく見ていきましょう。
なぜ CSS によるフォームウィジェットへのスタイル設定は困難であるか?
Web の初期段階 (1995 年頃) に、HTML 2 仕様へフォームコントロールが追加されました。フォームウィジェットの複雑さのため、実装者はそれらの管理や表示に下層のオペレーティングシステムを頼ることを選択しました。
数年後 CSS が作られ、技術的に必要なこと (すなわち、フォームコントロールを実装するためにネイティブウィジェットを使用すること) はスタイルの要件に変わりました。もっとも、CSS の初期段階ではフォームコントロールへのスタイル設定が優先的ではありませんでした。
ユーザは各自のプラットフォームの視覚的な外見に慣れていましたので、ブラウザベンダーはフォームコントロールをスタイル付け可能にすることに乗り気ではありませんでした。また正直に言うと今に至るまで、すべてのコントロールをスタイル付けできるように再構築することはきわめて困難です。
今日でも、CSS 2.1 を完全実装しているブラウザはありません。ところが、やがてブラウザベンダーはフォーム要素向けの CSS サポートを向上させていき、使いやすさに悪い評判があるとしても現在は HTML フォームへのスタイル設定に CSS を使用できます。
CSS を伴ってもすべてのウィジェットが同等には作成されません
いまだに、フォームで CSS を使用する際に困ることが存在します。この問題は、3 つのカテゴリに分けられます。
良好
いくつかの要素はプラットフォーム間の問題があるとしても、ほとんど問題なくスタイルを設定できます。これらは以下の構造的な要素が含まれます:
また、すべてのテキストフィールドウィジェット (単一行、複数行ともに) やボタンも含みます。
不良
一部の要素はほとんどスタイル設定ができず、時に CSS3 の高度な知識を必要とする、複雑なトリックが必要になるかもしれません。
これには <legend>
要素を含みます。これはプラットフォームに関わらず適切に配置することができません。加えて、チェックボックスやラジオボタンに直接スタイルを与えることはできません。placeholder
の内容は、標準的な方法ではスタイルを設定できません。ただし、どのブラウザでもスタイル設定を可能にする、独自の疑似要素または疑似クラスを実装しています。
これら特殊なケースをどのように扱うかについては、HTML フォームへの高度なスタイル設定の記事で見ていきます。
劣悪
一部の要素は、CSS でスタイルを設定できません。これらはすべての高度なユーザインターフェイスのウィジェットを含みます。たとえば範囲、色、日付のコントロールや、<select>
要素、<option>
要素、<optgroup>
要素や <datalist>
要素といったドロップダウンのウィジェットです。ファイルピッカーも、まったくスタイルを設定できないウィジェットとして知られています。新しい要素である <progress>
と <meter>
もこのカテゴリに入ります。
これらすべてのウィジェットの主な問題は、ウィジェットの構造がとても複雑であるという事実と、現在の CSS ではウィジェットの細かい部分すべてにスタイルを設定できるほどの表現力がないことによります。これらのウィジェットをカスタマイズしたい場合は、スタイルを設定できる DOM ツリーを作成するため JavaScript に頼らなければなりません。その方法については、カスタムウィジェットの作成方法の記事で説明します。
基本的なスタイル設定
CSS でのスタイル設定が容易な要素は、振る舞いが他の HTML 要素とほとんど同じであるため、問題に直面することはないでしょう。ただし、ブラウザ間でユーザエージェントのスタイルシートが若干矛盾するかもしれませんので、より簡単にスタイルを設定できるようにするためのトリックがあります。
検索フィールド
検索ボックスは、スタイル設定に若干のコツが必要になることがある、唯一のテキストフィールドです。WebKit ベースのブラウザ (Chrome、Safari など) では、独自プロパティ -webkit-appearance
で調整しなければならないでしょう。このプロパティについてはこちらの記事で詳しく説明します: HTML フォームへの高度なスタイル設定。
例
<form> <input type="search"> </form>
input[type=search] { border: 1px dotted #999; border-radius: 0; -webkit-appearance: none; }
Chrome の検索フィールドのスクリーンショットでわかるとおり、2 つのフィールドは上記の例のようなボーダーを設定していますが、1 番目のフィールドは -webkit-appearance
プロパティを使用せずに、2 番目は -webkit-appearance:none
を使用してレンダリングしたものです。違いは明らかです。
フォントとテキスト
CSS のフォントやテキストの機能は、任意のウィジェットで容易に使用できます (また、フォームウィジェットで @font-face
も使用できます)。ただし、ブラウザの動作にしばしば矛盾があります。デフォルトで、一部のブラウザは親から font-family
や font-size
を継承しません。代わりに多くのブラウザでは、システムのデフォルトの体裁を使用します。フォームの体裁を他のコンテンツと一致させるには、以下のルールをスタイルシートに追加するとよいでしょう:
button, input, select, textarea { font-family : inherit; font-size : 100%; }
以下のスクリーンショットで違いを示します。左側は Mac OS X の Firefox における要素のデフォルトのレンダリングで、プラットフォームのデフォルトのフォントスタイルを使用しています。右側は同じ要素ですが、フォントを調和させるスタイルルールを適用したものです。
フォームはシステムのデフォルトスタイルを使用するか、コンテンツに合うよう設計されたカスタムスタイルを使用するかについては多くの議論があります。これを決めるのは、設計者としてサイトや Web アプリケーションを作成するあなた次第です。
ボックスモデル
すべてのテキストフィールドは、CSS のボックスモデルに関する全プロパティ (width
、height
、padding
、margin
、および border
) を完全にサポートしています。ただし前述のとおり、ブラウザがウィジェットを表示する際はシステムのデフォルトスタイルに依存します。コンテンツに対してそれらをどのように混ぜ合わせるかを決めるのは、あなた次第です。ウィジェットでネイティブのルックアンドフィールを維持したいのでしたら、ウィジェットのサイズを調和させたい場合に若干の問題に直面するでしょう。
これは各ウィジェットがボーダー、パディング、マージンについて独自のルールを持っているためです。このためさまざまなウィジェットを同じサイズにしたい場合に、box-sizing
プロパティを使用しなければなりません:
input, textarea, select, button { width : 150px; margin: 0; -webkit-box-sizing: border-box; /* 過去の WebKit ベースブラウザ向け */ -moz-box-sizing: border-box; /* 過去の (Firefox <29) Gecko ベースブラウザ向け */ box-sizing: border-box; }
上のスクリーンショットで、左の列は box-sizing
プロパティを使わずに、右の列は同プロパティを値 border-box
と併せて使用して作成したものです。各種のウィジェットにプラットフォームのデフォルトルールがあるにも関わらず、すべての要素が同じ領域を占めるようにすることが可能な点に注目してください。
ポジショニング
HTML フォームウィジェットのポジショニングは、通常は問題になりません。ただし、特に注意すべき要素が 2 つあります:
legend
<legend>
要素はポジショニングを除いて、スタイル設定の問題はありません。どのブラウザでも、<legend>
要素は親 <fieldset>
の上ボーダーの前面に配置されます。これを上ボーダーから離して、HTML フロー内に配置するよう変える方法はまったくありません。position
プロパティを使用して絶対的または相対的に配置できますが、それ以外の場合は fieldset のボーダーの一部になります。
これは <legend>
要素がアクセシビリティのためにとても重要であるため (fieldset 内にある各フォーム要素のラベルの一部として、支援技術によって読み上げられるでしょう)、タイトルと対にしてアクセシブルな方法で隠すことがよくあります:
HTML
<fieldset> <legend>Hi!</legend> <h1>Hello</h1> </fieldset>
CSS
legend { width: 1px; height: 1px; overflow: hidden; }
textarea
デフォルトではどのブラウザも <textarea>
要素を、テキストの下端に揃えるインラインブロックとみなします。これが実際に望む形であることはほとんどありません。inline-block
から block
への変更は、display
プロパティを使用するのがとても簡単です。一方インラインとして使用したい場合は、垂直方向の揃え方を変更するのが一般的です:
textarea { vertical-align: top; }
例
HTML フォームにスタイルを設定する方法の具体例を見ていきましょう。これが、多くのアイデアを明らかにするのに役立つでしょう。以下のような "はがき" 風の連絡フォームを作成します:
HTML
HTML は、ガイドの最初の記事で使用したものより少しだけ複雑です。いくつか ID やタイトルを追加しています。
<form> <h1>to: Mozilla</h1> <div id="from"> <label for="name">from:</label> <input type="text" id="name" name="user_name"> </div> <div id="reply"> <label for="mail">reply:</label> <input type="email" id="mail" name="user_email"> </div> <div id="message"> <label for="msg">Your message:</label> <textarea id="msg" name="user_message"></textarea> </div> <div class="button"> <button type="submit">Send your message</button> </div> </form>
CSS
ここからがおもしろいところです! コードを書き始める前に、ここでは 3 つの追加要素が必要です:
- はがきの背景
- タイプライター風フォント: fontsquirrel.com の "Secret Typewriter"
- 手書き風フォント: fontsquirrel.com の "Journal"
ここからコードを見ていきましょう。始めに、@font-face
規則や <body>
要素と <form>
要素の基本的なスタイルを定義して、下地を用意します。
@font-face{ font-family : "handwriting"; src : url('journal.eot'); src : url('journal.eot?') format('eot'), url('journal.woff') format('woff'), url('journal.ttf') format('truetype'); } @font-face{ font-family : "typewriter"; src : url('veteran_typewriter.eot'); src : url('veteran_typewriter.eot?') format('eot'), url('veteran_typewriter.woff') format('woff'), url('veteran_typewriter.ttf') format('truetype'); } body { font : 21px sans-serif; padding : 2em; margin : 0; background : #222; } form { position: relative; width : 740px; height : 498px; margin : 0 auto; background: #FFF url(background.jpg); }
これで、タイトルやフォーム要素といった各要素を配置できます。
h1 { position : absolute; left : 415px; top : 185px; font : 1em "typewriter", sans-serif; } #from { position: absolute; left : 398px; top : 235px; } #reply { position: absolute; left : 390px; top : 285px; } #message { position: absolute; left : 20px; top : 70px; }
そして、フォーム要素自体に対するスタイル設定を始めます。まずは、<label>
に適切なフォントを割り当てましょう。
label { font : .8em "typewriter", sans-serif; }
テキストフィールドには、共通のルールがいくつか必要です。border
や background
の削除と padding
や margin
の再定義を行います。
input, textarea { font : .9em/1.5em "handwriting", sans-serif; border : none; padding : 0 10px; margin : 0; width : 240px; background: none; }
これらフィールドのひとつがフォーカスを得たときに、ライトグレー色で透過する背景で強調します。一部のブラウザで付加されるデフォルトのフォーカス強調を取り除くため、outline
プロパティを追加することが重要ですので注意してください。
input:focus, textarea:focus { background : rgba(0,0,0,.1); border-radius: 5px; outline : none; }
テキストフィールドのスタイル設定が完了して、次は単一行および複数行のテキストフィールドの表示が同じになるよう調整しなければなりません。これは、一般的にこれらのデフォルト表示が同じでないためです。
単一行のテキストフィールドは、Internet Explorer できれいに表示するための調整が必要です。Internet Explorer は、フォントの自然な高さに基づいてフィールドの高さを決定 (これはその他すべてのブラウザの動作です) しません。これを修正するため、以下のようにフィールドの明示的な高さを付加することが必要です:
input { height: 2.5em; /* IE 向け */ vertical-align: middle; /* こちらは必須ではありませんが、古い IE での表示を改善します */ }
<textarea>
要素はデフォルトでブロック要素としてレンダリングされるようにします。ここで重要なことは、resize
プロパティと overflow
プロパティの 2 つです。ここでは固定サイズでデザインしているため、ユーザが複数行のテキストフィールドをリサイズできないように resize
プロパティを使用します。overflow
プロパティは、ブラウザ間でのフィールドの一貫性を向上させるために使用します。これのデフォルト値が auto
であるブラウザと scroll
であるブラウザが存在します。この例では、すべてのブラウザが auto
になるようにするのがよいでしょう。
textarea { display : block; padding : 10px; margin : 10px 0 0 -10px; width : 340px; height : 360px; resize : none; overflow: auto; }
<button>
要素は、CSS によってより便利になります。疑似要素を含めて、行いたいことが何でもできます!
button { position : absolute; left : 440px; top : 360px; padding : 5px; font : bold .6em sans-serif; border : 2px solid #333; border-radius: 5px; background : none; cursor : pointer; -webkit-transform: rotate(-1.5deg); -moz-transform: rotate(-1.5deg); -ms-transform: rotate(-1.5deg); -o-transform: rotate(-1.5deg); transform: rotate(-1.5deg); } button:after { content: " >>>"; } button:hover, button:focus { outline : none; background: #000; color : #FFF; }
以上です! あなた自身で試してみましょう。ご覧いただけるとおり、動作します!
おわりに
ご覧いただいたとおり、テキストフィールドとボタンだけでフォームを作成する限りでは、CSS を使用したスタイル設定は容易です。フォームウィジェットでの作業を楽にできるようにする、ちょっとした CSS トリックについて詳しく知りたい場合は、the normalize.css プロジェクトのフォーム部分をご覧ください。
次の記事では、"不良" や "劣悪" カテゴリに入っているウィジェットの扱い方を見ていきます。