ウェブフォームへのスタイル設定
前回までのいくつかの記事では、HTML でウェブフォームを作成する方法を示しました。これで、CSS でスタイル設定する方法を示します。
フォームウィジェットのスタイル設定の挑戦
歴史
1995 年に HTML 2 仕様書へフォームコントロール(別名「フォームウィジェット」または「フォーム要素」)が導入されました。しかし、CSS は 1996 年後期までリリースされず、その後も数年はブラウザーの対応が充分ではありませんでした。ブラウザーは、フォームコントロールの管理とレンダリングを、オペレーティングシステムに頼っていました。
CSS が利用できるようになっても、ユーザーがそれぞれのブラウザーの外見に慣れていたため、ブラウザーベンダーは最初のうちはフォーム要素をスタイル設定することに消極的でした。しかし状況が変わり、フォームウィジェットはいくつかの例外を除き、これでほとんどがスタイル設定できるようになりました。
ウィジェットの種類
スタイル設定しやすいもの
<form>
<fieldset>
および<legend>
- 単一行のテキストの
<input>
(例えば text, url, email 型)<input type="search">
以外 - 複数行の
<textarea>
- ボタン(
<input>
と<button>
の両方) <label>
<output>
スタイル設定が困難なもの
- チェックボックスとラジオボタン
<input type="search">
これら特殊なケースをどのように扱うかについては、フォームへの高度なスタイル設定の記事で見ていきます。
内部が CSS 単独ではスタイル設定できないもの
<input type="color">
<input type="datetime-local">
のような日時関連コントロール<input type="range">
<input type="file">
- ドロップダウンウィジェットの作成に含まれる要素、
<select>
,<option>
,<optgroup>
,<datalist>
を含む。 <progress>
と<meter>
例えば、日付ピッカーのカレンダーや、クリックするとオプションリストが表示されるボタンなどは、CSS を使用するだけではスタイル設定することができません。
フォームへの高度なスタイル設定およびカスタムウィジェットの作成方法の記事で、これらのスタイル設定の方法を説明します。
メモ:
フォームコントロールの内部コンポーネントにスタイル設定するプロプライエタリな CSS 擬似要素、例えば ::-moz-range-track
がありますが、これはブラウザー同士で整合していないので、これに頼るべきではありません。これについては後程でも触れます。
単純なフォームウィジェットのスタイル設定
フォントとテキスト
CSS のフォントやテキストの機能は、任意のウィジェットで容易に使用できます(また、フォームウィジェットで @font-face
も使用できます)。ただし、ブラウザーの動作にしばしば矛盾があります。デフォルトで、一部のブラウザーは親から font-family
や font-size
を継承しません。代わりに多くのブラウザーでは、システムのデフォルトの体裁を使用します。フォームの体裁を他のコンテンツと一致させるには、以下のルールをスタイルシートに追加するとよいでしょう。
button,
input,
select,
textarea {
font-family: inherit;
font-size: 100%;
}
inherit
のプロパティ値で、プロパティ値は計算された親要素のプロパティ値に一致するようになります。つまり親の値を継承します。
以下のスクリーンショットで違いを示します。左側は Mac OS X の Chrome における <input type="text">
, <input type="date">
, <select>
, <textarea>
, <input type="submit">
, <button>
要素の既定のレンダリングで、プラットフォームのキテイノフォントスタイルを使用しています。右側は同じ要素ですが、フォントを調和させるスタイルルールを適用したものです。
既定はいろいろと変わります。継承により、フォントは親のフォントファミリーに変更されます — ここでは親コンテナーの既定の serif フォントです。ほぼすべてそうですが、例外として Chrome では<input type="submit">
は親段落を継承しません。むしろ、font-family: system-ui
を使います。これは同等な入力タイプの中で <button>
要素を使う理由です。
フォームはシステムの既定のスタイルを使用するか、コンテンツに合うよう設計されたカスタムスタイルを使用するかについては多くの議論があります。これを決めるのは、設計者としてサイトやウェブアプリケーションを作成するあなた次第です。
ボックスモデル
すべてのテキストフィールドは、CSS のボックスモデルに関する全プロパティ (width
、height
、padding
、margin
、border
) を完全にサポートしています。ただし前述のとおり、ブラウザーがウィジェットを表示する際はシステムのデフォルトスタイルに依存します。コンテンツに対してそれらをどのように混ぜ合わせるかを決めるのは、あなた次第です。ウィジェットでネイティブのルックアンドフィールを維持したいのでしたら、ウィジェットのサイズを調和させたい場合に若干の問題に直面するでしょう。
これは各ウィジェットが境界、パディング、マージンについて独自のルールを持っているためです。 このためさまざまなウィジェットを同じサイズにしたい場合に、box-sizing
プロパティを使用しなければなりません。
input,
textarea,
select,
button {
width: 150px;
padding: 0;
margin: 0;
box-sizing: border-box;
}
下のスクリーンショットで、左の列は <input type="radio">
、<input type="checkbox">
、<input type="range">
、<input type="text">
、<input type="date">
、<select>
、<textarea>
、<input type="submit">
、<button>
の既定の描画、右の列は同じ要素に上のルールを使用して作成したものです。各種のウィジェットのプラットフォームのデフォルトルールと比較して、すべての要素が同じ領域を占めるようにすることが可能な点に注目してください。
スクリーンショットではわからないかもしれませんが、ラジオやチェックボックスの操作はそのままで、 width
プロパティで提供される 150px の水平空間に中央配置されています。他のブラウザーでは、ウィジェットが中央に配置されないことがありますが、割り当てられた空間は守られます。
legend の配置
<legend>
要素はスタイル設定では問題ありませんが、その配置を操作するのは少し厄介かもしれません。既定では、常に親である <fieldset>
の上境界の上、左上隅の近くに配置されます。他の場所、例えば fieldset の内部や左下隅の近くに配置するには、位置指定を行う必要があります。
下記の例を見てください。
この方法で legend を配置するには、次の CSS を使います(単純化するため、他の宣言は削除しています)。
fieldset {
position: relative;
}
legend {
position: absolute;
bottom: 0;
right: 0;
}
<fieldset>
も位置指定する必要があり、 <legend>
がそこから相対的に位置指定されます(そうでなければ <legend>
は <body>
に合わせて位置決めされます)。
<legend>
要素はアクセシビリティにとってとても重要です。フィールドセット内の各フォーム要素のラベルの一部として支援技術によって読み上げられます。しかし、上記のようなテクニックを使用しても問題ありません。 legend の内容はこれまでと同じように読み上げられます。見た目の位置が変更されただけです。
メモ: transform
プロパティを使用して <legend>
の位置指定に役立てることもできます。しかし、例えば transform: translateY();
を使って配置すると、移動はするものの <fieldset>
の枠に醜い隙間ができて、簡単には除去できません。
具体的なスタイル設定の例
HTML フォームにスタイルを設定する方法の具体例を見ていきましょう。以下のような「はがき」風の連絡フォームを作成します。完成バージョンはこちら。
この例をやってみるのであれば、 postcard-start.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>
上記のコードを HTML の body に追加します。
資産を揃える
ここからが面白いところです。コードを書き始める前に、ここでは 3 つの追加要素が必要です。
- はがきの背景 — この画像をダウンロードして作業している HTML ファイルと同じディレクトリーに保存してください。
- タイプライター風フォント: dafont.com の "Mom's Typewriter" フォント、TTF ファイルを上記と同じディレクトリーにダウンロードしてください。
- 手書き風フォント: fontsquirrel.com の "Journal" — TTF ファイルを上記と同じディレクトリーにダウンロードしてください。
始める前にフォントの処理が必要です。
- fontsquirrel.com の Webfont Generator に移動します。
- フォームを使って、両方のフォントファイルをアップロードして webfont キットを生成します。キットをコンピューターにダウンロードします。
- zip ファイルを展開します。
- 展開した中身には 2 つの
.woff
ファイルと 2 つの.woff2
ファイルがあります。このファイルを、前と同じ fonts というディレクトリーにコピーします。各フォントの 2 つのファイルはブラウザー互換性を最大化するのに使います; より詳しい情報は Web fonts の記事を見てください。
CSS
ここから例の CSS を見ていきましょう。<style>
要素の中にすべてのコードブロックを一つ一つ追加します。
全体レイアウト
まず、 @font-face
ルールと、すべての <body>
と <form>
要素に設定するスタイルを定義して準備します。 fontsquirrel の出力が上記で述べたものと異なる場合、 stylesheet.css
ファイル内にダウンロード済みの webfont キットの中から正しい @font-face
ブロックを見つけることができます(下記の @font-face
ブロックをそれで置換し、パスをフォントファイルのものに更新する必要があります)。
@font-face {
font-family: "handwriting";
src:
url("fonts/journal-webfont.woff2") format("woff2"),
url("fonts/journal-webfont.woff") format("woff");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "typewriter";
src:
url("fonts/momot___-webfont.woff2") format("woff2"),
url("fonts/momot___-webfont.woff") format("woff");
font-weight: normal;
font-style: normal;
}
body {
font: 1.3rem sans-serif;
padding: 0.5em;
margin: 0;
background: #222;
}
form {
position: relative;
width: 740px;
height: 498px;
margin: 0 auto;
padding: 1em;
box-sizing: border-box;
background: #fff url(background.jpg);
/* we create our grid */
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 10em 1em 1em 1em;
}
注意として、フォームのレイアウトに CSS グリッドとフレックスボックス を使っています。これで、タイトルやフォーム要素といった各要素を配置できます。
h1 {
font:
1em "typewriter",
monospace;
align-self: end;
}
#message {
grid-row: 1 / 5;
}
#from,
#reply {
display: flex;
}
ラベルとコントロール
そして、フォーム要素自体に対するスタイル設定を始めます。まずは、 <label>
に適切なフォントを割り当てましょう。
label {
font:
0.8em "typewriter",
sans-serif;
}
テキストフィールドには、共通のルールがいくつか必要です。 border
や background
の削除と padding
や margin
の再定義を行います。
input,
textarea {
font:
1.4em/1.5em "handwriting",
cursive,
sans-serif;
border: none;
padding: 0 10px;
margin: 0;
width: 80%;
background: none;
}
これらのフィールドのいずれかがフォーカスされると、ライトグレーの透明な背景でハイライトされます(ユーザビリティとキーボードアクセシビリティのために、フォーカススタイルを保有することは常に重要です)。
input:focus,
textarea:focus {
background: rgb(0 0 0 / 10%);
border-radius: 5px;
}
これでテキストフィールドのスタイル設定が完了しましたが、次は単一行および複数行のテキストフィールドの表示が同じになるよう調整しなければなりません。一般に、これらの既定の表示が同じでないためです。
テキストエリアの微調整
<textarea>
要素は既定でブロック要素としてレンダリングされるようにします。ここで重要なことは、 resize
プロパティと overflow
プロパティの 2 つです。ここでは固定サイズでデザインしているため、ユーザーが複数行のテキストフィールドをリサイズできないように resize
プロパティを使用します。 overflow
プロパティは、ブラウザー間でのフィールドの一貫性を向上させるために使用します。これの既定値が auto
であるブラウザーと scroll
であるブラウザーが存在します。この例では、すべてのブラウザーが auto
になるようにするのがよいでしょう。
textarea {
display: block;
padding: 10px;
margin: 10px 0 0 -10px;
width: 100%;
height: 90%;
border-right: 1px solid;
/* resize : none; */
overflow: auto;
}
送信ボタンにスタイル設定する
<button>
要素は、 CSS によってより便利になります。擬似要素を含めて、行いたいことが何でもできます。
button {
padding: 5px;
font: bold 0.6em sans-serif;
border: 2px solid #333;
border-radius: 5px;
background: none;
cursor: pointer;
transform: rotate(-1.5deg);
}
button:after {
content: " >>>";
}
button:hover,
button:focus {
background: #000;
color: #fff;
}
最終結果
スキルテスト
この記事の最後に達しましたが、最も大切な情報を覚えていますか?次に進む前に、この情報が身に付いたかどうかを確認するテストがあります。スキルテスト: スタイル設定の基本をご覧ください。
まとめ
ご覧いただいたとおり、テキストフィールドとボタンだけでフォームを作成する限りでは、CSS を使用したスタイル設定は容易です。次の記事では、「不良」や「劣悪」に分類されているウィジェットの扱い方を見ていきます。