HTML フォームへのスタイル設定

by 2 contributors:

本記事では、HTML フォームを (できれば) より美しくするために CSS を使用する方法を学びます。意外にも、これは少しコツがいります。歴史的や技術的な理由により、フォームウィジェットは CSS とうまくかみ合いません。このような難しさから、多くの開発者はウィジェットのルックアンドフィールをコントロールできるようにするために、独自の HTML ウィジェットを作成することを選択します。しかし現代のブラウザでは、Web デザイナーがフォーム要素のデザインをより多くコントロールできます。詳しく見ていきましょう。

なぜ CSS によるフォームウィジェットへのスタイル設定は困難であるか?

Web の初期段階 (1995 年頃) に、HTML 2 仕様へフォームコントロールが追加されました。フォームウィジェットの複雑さのため、実装者はそれらの管理や表示に下層のオペレーティングシステムを頼ることを選択しました。

数年後 CSS が作られ、技術的に必要なこと (すなわち、フォームコントロールを実装するためにネイティブウィジェットを使用すること) はスタイルの要件になりました。もっとも、CSS の初期段階ではフォームコントロールへのスタイル設定が優先的ではありませんでした。

ユーザは各自のプラットフォームの視覚的な外見に慣れていましたので、ブラウザベンダーはフォームコントロールをスタイル付け可能にすることに乗り気ではありませんでした。また正直に言うと今に至るまで、すべてのコントロールをスタイル付けできるように再構築することはきわめて困難です。

今日でも、CSS 2.1 を完全実装しているブラウザはありません。ところが、やがてブラウザベンダーはフォーム要素向けの CSS サポートを向上させていき、使いやすさに悪い評判があるとしても現在は HTML フォームへのスタイル設定に CSS を使用できます。

CSS を伴ってもすべてのウィジェットが同等には作成されません

今のところ、フォームで CSS を使用する際に困ることがいまだに存在します。これらの問題は、3 つのカテゴリに分けられます。

良好

いくつかの要素はプラットフォームにまたがる問題があるとしても、ほとんど問題なくスタイルを設定できます。これらは以下の構造的な要素が含まれます:

  1. <form>
  2. <fieldset>
  3. <label>
  4. <output>

また、すべてのテキストフィールドウィジェット (単一行、複数行ともに) やボタンも含まれます。

不良

一部の要素はほとんどスタイル設定ができず、時に CSS3 の高度な知識を必要とする複雑なトリックが必要になるかもしれません。

これには <legend> 要素が含まれます。これはプラットフォーム間で適切に配置できません。加えて、チェックボックスやラジオボタンに直接スタイルを与えることはできません。ただし、CSS3 によって回避することができます。placeholder の内容は、標準的な方法ではスタイルを設定できません。ただし、どのブラウザでもスタイル設定を可能にする独自の疑似要素または疑似クラスを実装しています。

これら特殊なケースをどのように扱うかについては、Advanced styling for HTML forms の記事で見ていきます。

劣悪

一部の要素は、CSS でスタイルを設定できません。これらはすべての高度なユーザインターフェイスのウィジェットが含まれます。例えば範囲、色、日付のコントロールや、<select> 要素、<option> 要素、<optgroup> 要素や <datalist> 要素といったドロップダウンのウィジェットです。ファイルピッカーも、まったくスタイルを設定できないウィジェットとして知られています。新しい要素である <progress><meter> もこのカテゴリに入ります。

これらすべてのウィジェットの主な問題は、それらの構造がとても複雑であるという事実と、現在の CSS ではウィジェットの細かい部分すべてにスタイルを設定できるほどの表現力がないことによります。これらのウィジェットをカスタマイズしたい場合は、スタイルを設定できる DOM ツリーを作成するため JavaScript に頼らなければなりません。その方法については、How to build custom form widgets の記事で説明します。

基本的なスタイル設定

CSS でのスタイル設定が容易な要素は、振る舞いが他の HTML 要素とほとんど同じであるため、問題に直面することはないでしょう。ただし、すべてのブラウザでユーザエージェントのスタイルシートが若干矛盾するかもしれませんので、より簡単にスタイルを設定できるようにするためのトリックがあります。

検索フィールド

検索ボックスは、スタイル設定に若干のコツが必要になることがある、唯一のテキストフィールドです。WebKit ベースのブラウザ (Chrome、Safari など) では、独自プロパティ -webkit-appearance で調整しなければならないでしょう。このプロパティについてはこちらの記事で詳しく説明します: Advanced styling for HTML forms

<form>
  <input type="search">
</form>
input[type=search] {
  border: 1px dotted #999;
  border-radius: 0;

  -webkit-appearance: none;
}

This is a screenshot of a search filed on Chrome, with and without the use of -webkit-appearance

Chrome での検索フィールドのスクリーンショットでわかるとおり、2 つのフィールドは上記の例のようなボーダーを設定していますが、1 番目のフィールドは -webkit-appearance プロパティを使用せずに、2 番目は -webkit-appearance:none を使用してレンダリングしたものです。違いは明らかです。

フォントとテキスト

CSS のフォントやテキストの機能は任意のウィジェットで容易に使用できます (また、フォームウィジェットで @font-face も使用できます)。ただし、ブラウザの動作にしばしば矛盾があります。デフォルトで、一部のウィジェットは親から font-familyfont-size を継承しません。代わりに多くのブラウザでは、システムのデフォルトの体裁を使用します。フォームの体裁を他のコンテンツと一致させるには、以下のルールをスタイルシートに追加するとよいでしょう:

button, input, select, textarea {
  font-family : inherit;
  font-size   : 100%;
}

以下のスクリーンショットで違いを示します。左側は Mac OS X の Firefox における要素のデフォルトのレンダリングで、プラットフォームのデフォルトのフォントスタイルを使用しています。右側は同じ要素ですが、フォントを調和させるスタイル規則を適用したものです。

This is a screenshot of the main form widgets on Firefox on Mac OSX, with and without font harmonization

フォームはシステムのデフォルトスタイルを使用するか、コンテンツに合うよう設計されたカスタムスタイルを使用するかについては多くの議論があります。これを決めるのは、サイトや Web アプリケーションを設計者として作成するあなた次第です。

ボックスモデル

すべてのテキストフィールドは、CSS のボックスモデルに関する全プロパティ (widthheightpaddingmargin、および border) を完全にサポートしています。ただし前述のとおり、ブラウザがウィジェットを表示する際はシステムのデフォルトスタイルに依存します。コンテンツに対してそれらをどのように混ぜ合わせるかを決めるのは、あなた次第です。ウィジェットでネイティブのルックアンドフィールを維持したいのでしたら、ウィジェットのサイズを調和させたい場合に若干の問題に直面するでしょう。

これは各ウィジェットがボーダー、パディング、マージンについて独自のルールを持っているためです。 このためさまざまなウィジェットを同じサイズにしたい場合に、box-sizing プロパティを使用しなければなりません:

input, textarea, select, button {
  width : 150px;
  margin: 0;

  -webkit-box-sizing: border-box; /* 過去の WebKit ベースブラウザ向け */
     -moz-box-sizing: border-box; /* すべての Gecko ベースブラウザ向け */
          box-sizing: border-box;
}

This is a screenshot of the main form widgets on Chrome on Windows 7, with and without the use of box-sizing.

上のスクリーンショットで、左の列は 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 フォームにスタイルを設定する方法の具体例を見ていきましょう。これが、多くのアイデアを明らかにするのに役立つでしょう。以下のような "はがき" 風の連絡フォームを作成します:

This is what we want to achieve with HTML and CSS

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 つの追加要素が必要です:

  1. はがきの背景
  2. タイプライター風フォント: fontsquirrel.com の "Secret Typewriter"
  3. 手書き風フォント: 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;
}

テキストフィールドには、共通の規則がいくつか必要です。bordersbackgrounds の削除と paddingmargin の再定義を行う定義を単に追加します。

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;
}

And voila!あなた自身で試してみましょう。ご覧いただけるとおり、動作します!

おわりに

ご覧いただいたとおり、テキストフィールドとボタンだけでフォームを作成する限りでは、CSS を使用したスタイル設定は容易です。フォームウィジェットでの作業を楽にできるようにする、ちょっとした CSS トリックについて詳しく知りたい場合は、the normalize.css プロジェクトのフォーム部分をご覧ください。

次の記事では、"不良" や "劣悪" カテゴリに入っているウィジェットの扱い方を見ていきます。

ドキュメントのタグと貢献者

タグ: 
Contributors to this page: ethertank, yyss
最終更新者: ethertank,