最近、簡易なHTMLを書く機会が多かったので、ウン年前に書いたリセットCSSの見直しをしました。
で、かねがねフォーム系のCSSのブラウザ差異に悩まされていたので、ブラウザ差異ができるだけ生じないフォーム用のリセットCSSも書くことにしました。
見た目をがらりと変えてしまうお洒落なCSSはネットを探せばいくらでも出回っていますが、そういうのじゃなくて、洒落にする前のスタート地点。
デフォルトっぽい感じの絵面で、最低限の初期設定を行い、極力ブラウザ差異をなくすことが目標です。
input, textarea, button, select, option, input::file-selector-button{
font-family:var(--gothic-font);
color:var(--main-color);
}最初に、なぜかinput等にはbodyに指定したフォントが当たらないので、明示的にフォントを当てる。
ここではフォントはrootで指定しておいたものを使用します。
label{
display:inline-block;
cursor:pointer;
}ラベルはinline-blockにする。
textarea, input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="image"]){
padding:2px 10px;
border:1px solid #aaa;
border-radius:0;
background-color:#fff;
}
※numberの矢印など各操作部はブラウザ依存のままです。個々の調整は割愛。
テキスト入力系inputの外見を統一。
textarea{
resize:vertical;
}
テキストエリアの変形は縦方向のみ許可。横変形を許可すると往々にしてレイアウトが崩れます。
button, input::file-selector-button, input[type="submit"], input[type="button"], input[type="reset"]{
padding:2px 10px;
background:#eee;
border:1px solid #aaa;
border-radius:2px;
cursor:pointer;
}
:is(button, input::file-selector-button, input[type="submit"], input[type="button"], input[type="reset"]):active:not(:disabled){
background-color:#ddd;
}
ボタン系の外見を統一。active時のスタイルも必ず指定する。
label>input[type=checkbox]{
appearance:none;
border:1px solid #aaa;
background-color:#fff;
width:14px;
height:14px;
border-radius:2px;
box-shadow:none;
accent-color:#ddd;
display:inline-block;
vertical-align:-2px;
margin-right:2px;
position:relative;
cursor:pointer;
}
label>input[type=checkbox]:checked{
background-color:#eee;
}
label>input[type=checkbox]:checked::after{
display:block;
content:'';
width:3px;
height:10px;
border-right:1px solid var(--main-color);
border-bottom:1px solid var(--main-color);
transform:rotate(45deg);
position:absolute;
bottom:1px;
left:4px;
}
チェックボックスを描写し直す。appearance:noneでブラウザ指定の描写を削除し、それっぽいものを書き直します。選択時のチェックマークは疑似要素で描写。
label>input[type=radio]{
appearance:none;
border:1px solid #aaa;
background-color:#fff;
width:14px;
height:14px;
border-radius:14px;
box-shadow:none;
accent-color:#ddd;
display:inline-block;
vertical-align:-2px;
margin-right:2px;
position:relative;
cursor:pointer;
}
label>input[type=radio]:checked{
background-color:#eee;
}
label>input[type=radio]:checked::after{
display:block;
content:'';
width:4px;
height:4px;
background-color:var(--main-color);
border-radius:4px;
position:absolute;
bottom:4px;
left:4px;
}
同様にラジオボタンも再描写。
select{
appearance:none;
-webkit-appearance:none;
-moz-appearance:none;
padding:4px 8px;
padding-right:20px;
border:1px solid #aaa;
border-radius:0;
outline:0;
box-shadow:none;
text-overflow:ellipsis;
cursor:pointer;
background:#fff;
background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24'><path fill='none' stroke='%23666666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M6 9l6 6 6-6'/></svg>");
background-repeat:no-repeat;
background-position:right 4px center;
background-size:18px;
}
option:checked{
background:#eee;
}
最大の敵はselectです。selectはブラウザに依存する部分が大きく、残念ながら統一描写が今のところ不可能。
appearance:base-selectはまあまあ諸刃の剣で、widthと一緒に指定したとき、optionの幅が指定したwidthを超過するとどうしてもどこかしらレイアウトが崩れるため、動的にoptionを生成する場合には不向き。
魔改造しない場合は原始的にappearance:noneの方を使い、ピッカーの部分はブラウザの仕様を許容した方が無難です。
また、selectには疑似要素が使えないので、プルダウンを示す下矢印はSVGで表示させておきます。
text-overflow:ellipsisはsafariとかがまだ対応していないのもあって導入は好き好きで。
:is(textarea, select, input:not([type="file"]):not([type="hidden"]):not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="image"])):disabled{
background-color:#ddd;
cursor:default;
opacity:1;
}
:is(button, input::file-selector-button, input[type="submit"], input[type="button"], input[type="reset"]):disabled{
opacity:0.7;
cursor:default;
}
label:has(:disabled){
cursor:auto;
}最後に、disabled時の描画も統一しておきます。