mozilla
Your Search Results

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

    本記事では、HTML フォームでカスタマイズが難しい一部のウィジェットで CSS を使用する方法を見ていきます。前の記事で見たように、テキストフィールドやボタンでの CSS 使用はまったく問題がありません。ここからは、HTML フォームへのスタイル設定の影の部分を見ていきます。

    始める前に、2 種類の HTML フォームウィジェットについておさらいしましょう:

    不良
    スタイルの設定が難しく複雑なトリックが必要であり、時に CSS3 の高度な知識が必要である要素。
    劣悪
    これらの要素では、CSS によるスタイル設定はあきらめましょう。あなたが可能なことはせいぜいわずかなものですが、それを各ブラウザに対して当てにすることはできません。また、それら要素の外見を完全にコントロールすることもできません。

    CSS の表現力

    テキストフィールドやボタン以外のフォームウィジェットに存在する大きな問題は多くの場合、CSS には複雑なウィジェットへ適切にスタイルを設定できるほど十分な表現力がないことです。

    最近の HTML および CSS の進化により、CSS の表現力が拡張されてきました:

    これらすべては幸先がよいのですが、問題が 2 つあります: 第一に、必ずしも CSS 2.1 を超える機能を実装しているわけではないブラウザが存在します。第二にこれらは、例えば日付選択のような複雑なウィジェットのスタイル設定には十分ではありません。

    フォームについて、CSS の表現力を拡張するためのブラウザベンダーによる実験的な機能がいくつかあり、場合によってはそれらができることを知っておくとよいでしょう。

    警告: これらの実験的な機能に興味を持ったとしても、標準化されたものではないので当てにはできません。これらを使用する場合 (おそらく頻繁に使用するべきではありません) は、自己責任で行ってください。また、非標準のプロパティを使用することにより Web に対してよくないであろう行為を行っていることになります。

    フォーム要素の外見を制御する

    WebKit (Chrome、Safari) ベースおよび Gecko (Firefox) ベースのブラウザは、HTML ウィジェットについて高水準のカスタマイズを提供します。これらはクロスプラットフォームで使用可能ですから、ネイティブのルックアンドフィールのウィジェットからユーザによるスタイル設定が可能なウィジェットへ切り替える仕組みが必要になります。

    そのために、これらは独自のプロパティを使用します: -webkit-appearance または -moz-appearance です。これらのプロパティは非標準であり、使用するべきではありません。実際は、このプロパティの動作は WebKit と Gecko で異なります。しかし、知っておくとよい値が 1 つあります: none です。この値によって、ウィジェットのスタイルを (ほぼ完全に) コントロールできるようになります。

    よって要素へのスタイル適用で問題を抱えている場合は、この独自プロパティを使用してみましょう。これからいくつか例を見ていきますが、このプロパティのもっとも知られている使い方は、WebKit ブラウザにおける検索フィールドのスタイル設定です:

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

    注意: Web 技術について語る際に将来を予測するのは困難ですが、CSS の表現力を拡張するのは難しく、また将来の展望を示す Shadow DOM といった他の仕様の調査が行われています。十分なスタイル設定を可能にするための探求はまだ終わりません。

    チェックボックスとラジオボタン

    チェックボックスやラジオボタンに、単独でスタイルを設定するのはやや面倒です。例えばチェックボックスやラジオボタンのサイズは変更できないということであり、それを試みたとしてもブラウザはまったく異なる動作をするでしょう。

    シンプルなテストケース

    以下のテストケースについて考えてみましょう:

    <span><input type="checkbox"></span>
    span {
        display: inline-block;
        background: red;
    }
    
    input[type=checkbox] {
        width : 100px;
        height: 100px;
    }

    さまざまなブラウザでの処理方法は以下のとおりです:

    ブラウザ レンダリング
    Firefox 16 (Mac OSX) Rendering of a sized check box on Firefox
    Chrome 22 (Mac OSX) Rendering of a sized check box on Chrome
    Opera 12.01 (Mac OSX) Rendering of a sized check box on Opera
    Internet Explorer 9 (Windows 7) Rendering of a sized check box on IE9
    Internet Explorer 7 (Windows XP) Rendering of a sized check box on IE7

    より複雑な例

    Opera や Internet Explorer は -webkit-appearance-moz-appearance といった機能をサポートしていませんので、それらを使用するのは適していません。幸い、CSS には解決策を見いだせる表現力があります。一般的なサンプルを見てみましょう:

    <form>
      <fieldset>
        <p>
          <input type="checkbox" id="first" name="fruit-1" value="cherry">
          <label for="first">I like cherry</label>
        </p>
        <p>
          <input type="checkbox" id="second" name="fruit-2" value="banana" disabled>
          <label for="second">I can't like banana</label>
        </p>
        <p>
          <input type="checkbox" id="third" name="fruit-3" value="strawberry">
          <label for="third">I like strawberry</label>
        </p>
      </fieldset>
    </form>

    基本的なスタイル設定を伴います:

    body {
      font: 1em sans-serif;
    }
    
    form {
      display: inline-block;
    
      padding: 0;
      margin : 0;
    }
    
    fieldset {
      border : 1px solid #CCC;
      border-radius: 5px;
      margin : 0;
      padding: 1em;
    }
    
    label {
      cursor : pointer;
    }
    
    p {
      margin : 0;
    }
    
    p+p {
      margin : .5em 0 0;
    }

    ここで、独自のチェックボックスを持つようにスタイルを設定してみましょう。

    方針として、ネイティブのチェックボックスを独自の画像で置き換えます。始めに、チェックボックスで必要とされる全状態の画像を用意しなければなりません。その状態は以下のとおりです: 未チェック、チェック済、未チェックで無効、チェック済みで無効。この画像は、CSS スプライトとして使用します:

    Check box CSS Sprite

    元のチェックボックスを隠すことから始めましょう。チェックボックスを、ページのビューポートの外側に移します。ここで注意点が 2 つあります:

    • 後ほど見るようにユーザがチェックボックスを使用できるようにしなければなりませんので、チェックボックスを隠すために display:none を使用してはいけません。display:none を使用するとユーザはチェックボックスにアクセスできなくなり、チェックを入れたり外したりできなくなります。
    • スタイルを設定するために、CSS3 のセレクタをいくつか使用します。古いブラウザをサポートするため、すべてのセレクタの前に :root 疑似クラス付加してもかまいません。現在の実装状況では、私たちが必要とするものをサポートしている全ブラウザが :root 疑似クラスもサポートしており、その一方で他のブラウザはサポートしていません。これは、古い Internet Explorer をフィルタするのに便利な方法の例です。そのようなブラウザは通常のチェックボックスを、新しいブラウザは独自のチェックボックスを表示します。
    :root input[type=checkbox] {
      /* 元のチェックボックスをビューポートの外側に押し出す */
      position: absolute;
      left: -1000em;
    }

    ネイティブのチェックボックスを除去しましたので、独自のチェックボックスを追加しましょう。そのために、元のチェックボックスの後にある <label> 要素の :before 疑似要素を使用します。よって以下のセレクタでは、チェックボックスを示すため属性セレクタを使用します。そして、元のチェックボックスの後に続く label 要素を示すために隣接セレクタを使用します。最終的に :before 疑似要素へアクセスして、独自の未チェックのチェックボックス表示するスタイルを設定します。

    :root input[type=checkbox] + label:before {
      content: "";
      display: inline-block;
      width  : 16px;
      height : 16px;
      margin : 0 .5em 0 0;
      background: url("https://developer.mozilla.org/files/4173/checkbox-sprite.png") no-repeat 0 0;
    
    /* 以下は、チェックボックスの位置をテキストの 
       ベースラインに合わせるために使用します */
    
      vertical-align: bottom;
      position: relative;
      bottom: 2px;
    }

    状況に応じて独自のチェックボックスの状態を変更するため、元のチェックボックスで :checked 疑似クラスと :disabled 疑似クラスを使用します。CSS スプライトを用いるため、行うべきことは背景の位置の変更です。

    :root input[type=checkbox]:checked + label:before {
      background-position: 0 -16px;
    }
    
    :root input[type=checkbox]:disabled + label:before {
      background-position: 0 -32px;
    }
    
    :root input[type=checkbox]:checked:disabled + label:before {
      background-position: 0 -48px;
    }

    最後に (しかしとても重要な) こと: ユーザがウィジェットを渡り歩くのにキーボードを使用するとき、各ウィジェットは視覚的にフォーカスが当たるべきです。ネイティブのチェックボックスを隠すため、ユーザがフォーム内でどこにいるかをわかるようにするには、自身でこの機能を実装しなければなりません。以下の CSS が、独自のチェックボックスのフォーカスを実装します。

    :root input[type=checkbox]:focus + label:before {
      outline: 1px dotted black;
    }

    結果を実際にご覧いただけます:

    select の悪夢に対処する

    <select> 要素はクロスプラットフォームでスタイル設定が不可能であるため、"劣悪な" ウィジェットとされています。ただし、いくつかできることがあります。長い説明はやめて、サンプルを見てみましょう:

    <select>
      <option>Cherry</option>
      <option>Banana</option>
      <option>Strawberry</option>
    </select>
    select {
      width   : 80px;
      padding : 10px;
    }
    
    option {
      padding : 5px;
      color   : red;
    }

    以下の表で、さまざまなブラウザがどのように処理するかを 2 つのケースで示します。始めの 2 列は、サンプルそのものです。後の 2 列はウィジェットの外見をよりコントロールするために、以下のカスタム CSS を使用したものです:

    select, option {
      -webkit-appearance : none; /* WebKit で外見をコントロールするため */
      -moz-appearance : none; /* Gecko で外見をコントロールするため */
    
      /* Presto (Opera) および Trident (IE) で外見をコントロールするため
         これは Gecko でも動作し、また WebKit でも部分的に作用することに注意 */  
      background : none;
    }
    Browser 通常のレンダリング 調整したレンダリング
    閉じた状態 開いた状態 閉じた状態 開いた状態
    Firefox 16 (Mac OSX) Select closed on Firefox on Mac OSX (No tweak) Select open on Firefox on Mac OSX (No tweak) Select closed on Firefox on Mac OSX Select open on Firefox on Mac OSX
    Firefox 16 (Windows 7) Select closed on Firefox on Windows 7 (No tweak) Select open on Firefox on Windows 7 (No tweak) Select closed on Firefox on Windows 7 Select open on Firefox on Windows 7
    Chrome 22 (Mac OSX) Select closed on Chrome on Mac OSX (No tweak) Select open on Chrome on Mac OSX (No tweak) Select closed on Chrome on Mac OSX Select open on Chrome on Mac OSX
    Chrome 22 (Windows 7) Select closed on Chrome on Windows 7 (No tweak) Select open on Chrome on Windows 7 (No tweak) Select closed on Chrome on Windows 7 Select open on Chrome on Windows 7
    Opera 12.01 (Mac OSX) Select closed on Opera on Mac OSX (No tweak) Select open on Opera on Mac OSX (No tweak) Select closed on Opera on Mac OSX Select open on Opera on Mac OSX
    Internet Explorer 9 (Windows 7) Select closed on IE9 on Windows 7 Select open on IE9 on Windows 7 N/A N/A
    Internet Explorer 7 (Windows XP) Select closed on IE7 on Windows XP Select open on IE7 on Windows XP N/A N/A

    ご覧いただけるように、-*-appearance プロパティの力を借りたとしても問題が残ります:

    • padding プロパティの扱いは、オペレーティングシステムやブラウザ間で一貫性がありません。
    • 古い Internet Explorer ではスムーズなスタイル設定ができません。
    • Firefox はドロップダウンの矢印にスタイルを設定できません。
    • ドロップダウンリスト内の <option> 要素にスタイルを設定したい場合、Chrome や Opera の動作はシステムにより大きく異なります。

    またこのサンプルでは、3 つの CSS プロパティにのみ言及しています。さらに多くの CSS プロパティについて考えると混乱すると考えてください。ご覧いただけるように、CSS はこれらのウィジェットのルックアンドフィールを一貫性があるように変更するのに向いていませんが、ブラウザやオペレーティングシステムによる違いがあってもかまわないのであれば、ある程度の調整は可能です。

    私たちはこちらのページで、どのプロパティが適しているかの説明を試みています: Properties compatibility table for form widgets

    よりよいフォームへの道: 役に立つライブラリとポリフィル

    CSS はチェックボックスやラジオボタンには十分な表現力がありますが、より高度なウィジェットについては不十分です。<select> 要素ではいくらか可能なこともありますが、ファイルウィジェットで可能なことはまったくありません。日付選択などでも同様です。

    フォームウィジェットを完全にコントロールしたいのでしたら、JavaScript に頼る以外の選択肢はありません。How to build custom form widgets の記事にて自身でそれを行う方法を見ていきますが、あなたを助けるとても有用なライブラリがあります:

    • Uni-form は、フォームのマークアップや CSS によるスタイル設定を標準化するフレームワークです。jQuery と共同で使用する際の追加機能も提供しますが、こちらの利用は任意です。
    • Formalize はフォームのノーマライズやカスタマイズを支援する、一般的な JavaScript フレームワーク (jQuery、Dojo、YUI など) の拡張機能です。
    • Niceforms は Web フォームの完全なカスタマイズ機能を提供する、スタンドアロンの JavaScript メソッドです。いくつかの内蔵テーマや独自のカスタムテーマを使用できます。

    以下のライブラリはフォームにだけのものではありませんが、HTML フォームを扱う場合にとても興味深い機能を備えています:

    • jQuery UI は日付選択 (アクセシビリティに特別な配慮をしています) などの、とても興味深く高度かつカスタマイズ可能なウィジェットを提供します。
    • Twitter Bootstrap は、フォームをノーマライズしたい場合にとても役に立つでしょう。
    • WebShim はブラウザの HTML5 サポートへの対処に役立つ大規模ツールです。Web フォームの部分が実に役立つでしょう。

    CSS と JavaScript を一体化すると副作用を持たせられることを覚えておいてください。よってこれらのライブラリのいずれかを採用したら、スクリプトが失敗した場合にフォールバックするスタイルシートを用意するべきです。スクリプトが失敗する理由は特にモバイル環境でたくさんありますが、このような場合でも可能な限り最善の対処を行うよう Web サイトやアプリを設計しなければなりません。

    おわりに

    HTML フォームでの CSS 使用には影の部分がいまだにありますが、多くの場合は回避法があります。それらはきれいではありませんが一般的です。ただし、新しいブラウザは新たな可能性を提供します。今のところ最善の解決策は、HTML フォームウィジェットに適用された CSS について、さまざまなブラウザのサポート状況を詳しく知ることです。

    本ガイドの次の記事では、さまざまな HTML フォームウィジェットが重要な CSS プロパティをどれだけサポートしているかを探っていきます: Properties compatibility table for form widgets.

    関連情報

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

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