あまり知られていない、フォームをCSSでスタイルするために役立つ便利なセレクタとその使い方
Post on:2017年11月21日
フォームをCSSでスタイルするのは難しいと思われていました。しかし、input要素とそれに関連する要素をスタイルするためのあまり知られていないセレクタがあります。いくつかは比較的新しいセレクタですが、昔から存在するセレクタもあります。
フォームの見た目だけでなく、機能も強化するCSSの便利なセレクタとその使い方を紹介します。
Advanced CSS-Only Form Styling
by Jonathan Harrell
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- フォームにスタイルを適用したデモ
- :placeholder-shown
- :required
- :optional
- :disabled
- :read-only
- :valid
- :invalid
- :in-range/:out-of-range
- :checked
- フォームの基本スタイルを提供するフレームワーク
フォームにスタイルを適用したデモ
ここで紹介するフォームのスタイルは、下記デモページで実際の動作を確認できます。
:placeholder-shown
最初に紹介する「:placeholder-shown」は比較的新しいセレクタで、IEにはサポートされていません(ブラウザのサポート状況)。しかし、フォームの動作的にはセレクタが機能しなくても、問題はありません。
このセレクタを使用すると、プレースホルダがユーザーに表示されているかどうかを検出できます。input要素に関連づけられたlabel要素を非表示にしたり、表示したりが簡単にできます。
ここではユーザーがinput要素に入力してプレースホルダを非表示にするまで、label要素を隠しています。label要素を表示する際にアニメーション(移動・変形・不透明度)を加えると、CSSだけで実装されているとは思えないほど素敵なエフェクトに見えるかもしれません。実装の注意点は、label要素は必ずinput要素の後にすることです。
1 2 3 4 |
<div class="form-group"> <input type="text" id="dynamic-label-input" placeholder="Enter some text"> <label for="dynamic-label-input">Enter some text</label> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.form-group { position: relative; padding-top: 1.5rem; } label { position: absolute; top: 0; font-size: var(--font-size-small); opacity: 1; transform: translateY(0); transition: all 0.2s ease-out; } input:placeholder-shown + label { opacity: 0; transform: translateY(1rem); } |
:required
このセレクタを使用して、フォームの入力欄が必須であることを明示します。ここでは、空のspan「.help-text」を使用し、::before擬似要素を使用して動的にコンテンツを配置しています。
実際にはJavaScriptで実装することが多いと思いますが、ここではCSSのアプローチを示すために取り上げています。
1 2 3 |
<label for="required-input">Required input</label> <input type="text" id="required-input" required> <span class="help-text"></span> |
1 2 3 |
input:required + .help-text::before { content: '*Required'; } |
:optional
このセレクタは「:required」と反対で、フォームの入力欄がオプションの場合に使用します。HTMLは「:required」と同じ構造で実装し、空のspan「.help-text」を使って、required属性がない場合にはオプションのテキストを表示しています。
1 2 3 |
<label for="optional-input">Optional input</label> <input type="text" id="optional-input"> <span class="help-text"></span> |
1 2 3 |
input:optional + .help-text::before { content: '*Optional'; } |
:disabled
「:disabled」は多くの人に馴染みがあるセレクタだと思いますが、覚えておくことが重要です。
ユーザーの入力を無効にするのが必要になる時が必ずあります。
1 2 |
<label for="disabled-input">Disabled input</label> <input type="text" id="disabled-input" disabled> |
1 2 3 4 5 |
&:disabled { border-color: var(--gray-lighter); background-color: var(--gray-lightest); color: var(--gray-light); } |
:read-only
readonly属性を持つ入力欄は、disabled属性とは意味が少し異なります。両方とも値を編集できない点は同じですが、disabledは値を送信せず、readonlyは値を送信します。ありがたいことに、その助けとなる「:read-only」セレクタが用意されています。
1 |
<input type="text" value="Read-only value" readonly> |
1 2 3 4 5 |
input:read-only { border-color: var(--gray-lighter); color: var(--gray); cursor: not-allowed; } |
:valid
多くのフォームの検証はJavaScriptでおこなわれますが、HTML5 Form Validationとinput要素のスタイルを利用することもできます。「:valid」はその中の一つで、ブラウザがネイティブに備えているValidationルールを通してinput要素をスタイルします。
ここではbackground-imageプロパティを使用して、ユーザーが入力した際にSVGでチェックを表示するようにしました。
1 2 3 |
<label for="valid-email">Valid input</label> <input type="email" id="valid-email" value="email@email.com" required> <span class="help-text"></span> |
1 2 3 4 |
input:valid { border-color: var(--color-primary); background-image: url("data:image/svg+xml,%3Csvg width='45px' height='34px' viewBox='0 0 45 34' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cg transform='translate%28-56.000000, -59.000000%29' fill='%232EEC96'%3E%3Cpolygon points='70.1468531 85.8671329 97.013986 59 100.58042 62.5664336 70.1468531 93 56 78.8531469 59.5664336 75.2867133'%3E%3C/polygon%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A"); } |
:invalid
「:invalid」は、ブラウザがネイティブに備えているValidationルールをパスしていないかどうかをチェックするセレクタです(例えば、メール入力に実際の電子メールが含まれていない場合など)。
今度は、SVGで「x」を表示するようにしました。
1 2 |
<label for="invalid-email">Invalid input</label> <input type="email" id="invalid-email" value="notanemail" required> |
1 2 3 4 |
input:invalid { border-color: var(--color-error); background-image: url("data:image/svg+xml,%3Csvg width='30px' height='30px' viewBox='0 0 30 30' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E%3Cg transform='translate%28-128.000000, -59.000000%29' fill='%23F44336'%3E%3Cpolygon points='157.848404 61.9920213 145.980053 73.8603723 157.848404 85.7287234 154.856383 88.7207447 142.988032 76.8523936 131.119681 88.7207447 128.12766 85.7287234 139.996011 73.8603723 128.12766 61.9920213 131.119681 59 142.988032 70.8683511 154.856383 59'%3E%3C/polygon%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A"); } |
空のspan「.help-text」と::before疑似要素を使用して、入力欄に適したエラーメッセージを表示させることもできます。
1 2 3 |
<label for="invalid-email">Invalid input</label> <input type="email" id="invalid-email" value="notanemail"> <span class="help-text"></span> |
1 2 3 |
input[type='email']:invalid + .help-text::before { content: 'You must enter a valid email.' } |
:in-range/:out-of-range
「:in-range」と「:out-of-range」は、数値入力の値が指定された最小値と最大値の範囲内にあるかどうかを検出します。
1 2 3 |
<label for="out-of-range-input">Out-of-range input</label> <input type="number" id="out-of-range-input" min="1" max="10" value="12"> <span class="help-text"> (value must be between 1 and 10)</span> |
1 2 3 |
input:out-of-range + .help-text::before { content: 'Out of range'; } |
:checked
「:checked」は多くの人が精通しているセレクタだと思います。「checked」を記述すると、チェックボックスやラジオボタンをチェックした状態にすることができます。
チェックボックスを実装する時にわたしが使用するテクニックは、ラッパー要素を作成し、input要素の後にlabel要素を配置します。
1 2 3 4 5 6 7 8 |
<div class="checkbox"> <input type="checkbox" name="checkbox" id="check-option-1" value="1" checked /> <label for="check-option-1">Option 1</label> </div> <div class="checkbox"> <input type="checkbox" name="checkbox" id="check-option-2" value="2"/> <label for="check-option-2">Option 2</label> </div> |
input要素は視覚的に隠されますが、それでもクリック可能です。視覚的に隠したので、「label::before」でチェックボックスを、「label::after」でチェックマークを作成します。これらに「:checked」セレクタを使用して、2つの擬似要素にスタイルを適用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
&:checked + label::before { background-color: var(--color-primary); } &:checked + label::after { display: block; position: absolute; top: 0.2rem; left: 0.375rem; width: 0.25rem; height: 0.5rem; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); content: ''; } |
フォームの基本スタイルを提供するフレームワーク
CSS framework Hi-Qは、チェックボックス、ラジオボタン、無効化されたinput要素など、フォーム入力のための便利な基本スタイルを提供するフレームワークです。
テーマビルダーも用意され、フォームの各要素のスタイルを見ながら変更できます。
しかも軽量で、動的に変更できるCSS変数、特にテーマの切り替え機能が便利です。
sponsors