フォームにCSS 2007

目的

対象ブラウザをIE6, IE7, Mozilla Firefox, Opera, Safariとする。IE6は後方互換モードにし、form要素やinput要素にCSSを適用して、以下の背景画像の白い部分に入るように、できるだけフォームの大きさや位置をあわせたいと考える。しばしばグリッドに従ってレイアウトが必要なサイト内検索用の検索フォームを念頭においているが、他でも応用可能だ。

背景画像

HTMLの方は

<form id="" action="">
<p><input class="search" name="search" size="20" value="" />
<input class="searchsubmit" type="submit" value="Search" /></p>
</form>

CSSの方は

form {
    position: relative;
    margin: 0;
    padding: 0;
    width: 320px;
    height: 64px;
    background-image: url(images/back-20071020.gif);
}
form p {
    position: absolute;
    top: 12px;
    left: 32px;
    margin: 0;
    padding: 0;
    width: 256px;
    height: 24px;
}

を基本とする。まず、p要素で白い枠の大きさと場所をposition: absoluteで決めてから入力ボックスとボタンを配置する。

通常のやり方2007

まず、inputでvertical-align: bottom;のみを指定する方法を紹介する。Windows XPではXPスタイルとクラシックスタイルでボタンのデザインが変わる。

#f1 p input {
    vertical-align: bottom;
}

でも、ここでinputにwidthやheightを指定するとはまる。問題となるのは、入力ボックス(input type="text")とボタン(input type="button"またはtype="submit")において、width/heightにborderやpaddingを含めるかどうかが、ブラウザの描画方法によって変わることである。IE6, IE7はボックスとボタンの配置すら微妙に違う。使えない。

#f2 p input {
    vertical-align: bottom;
}
#f2 p .search {
    width: 140px;
    height: 16px; /* content-box */
    padding: 2px;
    border: 2px solid #676363;
}
#f2 p .searchsubmit {
    width: 90px;
    height: 24px; /* border-box */
    padding: 2px;
    border: 2px solid #676363;
}

inputへの解釈が違う

content-boxとborder-box

上記のように、width、height、padding、borderをすべて指定すると

で、結論から言うと、上記の違いにより、大きさ、位置ともにピクセル単位であわせることは基本的に出来ない。フォームの部品の場合は、(CSS2のレベルでは)どちらかが正しくてどちらかが間違い、とも言えないらしい。正しい挙動が決まっていないので、ある日、バージョンがあがったら突然挙動が変わってしまうことも考えられる。

仕方ないので、あきらめましょう、ではなくて、CSSを使ったおすすめ妥協案をふたつ挙げることにする。

CSSを使ったおすすめ妥協案その1 2007

何が正しいかは決まっていないとはいえ、各UAの挙動はバージョンがあがるにつれて入力ボックスはcontent-box、ボタンはborder-boxになるよう収束しつつある。なので、これを前提としてposition: absoluteで白い枠の両脇に置く。

ボタンはブラウザのデフォルトのデザインを使い、幅や高さをborder-boxになるように指定する。borderやbackgroundをいじらなければ、だいたいデフォルトの見た目を受け継いでくれる。CSSのあたまで全称セレクタでリセットを行うときにも、border:0は入れないようにする。MacIE5だけcontent-boxなのでボタンが大きくなってしまうが、やむをえまい。

入力ボックスは、IE6の後方互換モード、Operaの旧版などでは小さくなってしまう。どこかしらでズレが生じることを考え、border、paddingは1pxでとどめておくことが望ましい。現時点でIE6でズレが生じるレイアウトは使いにくいと思うので、IE6よけを使ってIE6のみを救済する(IE6に標準準拠モードで解釈させる場合は不要)。モダンブラウザでは、入力ボックスに:focusが使える(IE7は未対応のようだ)。

#f3 p .search {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 154px;
    height: 24px; /* border-box for IE6 */
    padding: 1px;
    border: 1px solid #676363;
}
head+body #f3 p .search {
    width: 150px;
    height: 20px; /* content-box */
}
#f3 p .search:focus {
    border: 1px solid #974343;
    background-color: #fee8eb;
}
#f3 p .searchsubmit {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 90px;
    height: 24px; /* border-box */
    padding: 0;
}

画面キャプチャ

以下はIE6に標準準拠モードで解釈させる場合の例である。

#f3 p .search {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 150px;
    height: 20px; /* content-box */
    padding: 1px;
    border: 1px solid #676363;
}
#f3 p .search:focus {
    border: 1px solid #974343;
    background-color: #fee8eb;
}
#f3 p .searchsubmit {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 90px;
    height: 24px; /* border-box */
    padding: 0;
}

CSSを使ったおすすめ妥協案その2 2007

borderとpaddingを含むかどうかで悩んでいるんだから、入力ボックスもボタンも、borderとpaddingをゼロにしてしまえばいい。境界線やボタンのデザインはすべて背景画像に任せ、余白はposition: absoluteの位置あわせで調整する。これでズレは解消できる。ただ、デフォルトデザインのままでいこうとするSafari 1などを考えて、レイアウトの仕方に注意する。確認作業は必須かも。

今回のサンプルは、form要素の白い枠を活かして入力ボックスは真っ白にしている。border、paddingともにゼロなので、:focusは使えてもbackground-colorしか変える余地がない。:activeはお好みで。

#f4 {
    background-color: #b4a4a4;
}
#f4 p {
    background-color: white;
}
#f4 p .search {
    position: absolute;
    top: 2px;
    left: 2px;
    padding: 0;
    border: 0;
    width: 161px;
    height: 20px;
}
#f4 p .search:focus {
    background-color: #fee8eb;
}
#f4 p .searchsubmit {
    position: absolute;
    top: 1px;
    right: 1px;
    width: 90px;
    height: 22px;
    padding: 0;
    border: 0;
    background-color: #b4304a;
    background-image: url(images/back-searchsubmit.gif);
    background-position: top;
    font-weight: bold;
    color: #feeeee;
}
#f4 p .searchsubmit:hover {
    background-position: bottom;
}
#f4 p .searchsubmit:active {
    padding: 1px 0 0 1px;
}

画面キャプチャ

背景画像にするので、モダンブラウザではボタンにロールオーバーが使えるようになる。縦に通常時とマウスオーバー時のボタンを並べてひとつのファイルにし、background-positionで入れ替える。

ボタン背景画像

なお、paddingもborderもゼロにしてしまったので、画像表示がoffになっても大丈夫なように、忘れずにbackground-colorを指定する。

画像表示offでも大丈夫