[html+scss]form関連タグを真っ更からデザインするベース

コピペ用

ちゃんと作っておいたのを使い回すのが楽なんだけど、案件またいで被るのもどうなんだろうと思ったりして。大丈夫だろうけど。

HTML

<form action="">

    <!-- テキスト系 -->
    <label>input:text</label>
    <input type="text" placeholder="山田 太郎">

    <label>input:password</label>
    <input type="password" placeholder="パスワード">

    <label>input:email</label>
    <input type="email" placeholder="user@example.com">

    <label>input:url</label>
    <input type="url" placeholder="https://example.com">

    <label>input:tel</label>
    <input type="tel" placeholder="090-0000-0000">

    <label>input:search</label>
    <input type="search" placeholder="キーワードを入力">

    <label>textarea</label>
    <textarea rows="3" placeholder="ご自由にどうぞ"></textarea>

    <!-- 数値・範囲 -->
    <label>input:number</label>
    <input type="number" value="1" min="1" max="99">

    <label>input:range</label>
    <input type="range" min="0" max="100" value="50">

    <!-- 日付・時刻 -->
    <label>input:date</label>
    <input type="date">

    <label>input:time</label>
    <input type="time">

    <label>input:datetime-local</label>
    <input type="datetime-local">

    <label>input:month</label>
    <input type="month">

    <label>input:week</label>
    <input type="week">

    <!-- 選択系 -->
    <label>input:checkbox</label>
    <input type="checkbox" name="check" value="design"> デザイン
    <input type="checkbox" name="check" value="dev"> 開発
    <input type="checkbox" name="check" value="marketing"> マーケティング

    <label>input:radio</label>
    <input type="radio" name="contact" value="email"> メール
    <input type="radio" name="contact" value="tel"> 電話
    <input type="radio" name="contact" value="any"> どちらでも

    <label>select</label>
    <select name="prefecture">
        <option value="">選択してください</option>
        <option value="tokyo">東京都</option>
        <option value="osaka">大阪府</option>
        <option value="aichi">愛知県</option>
    </select>

    <label>select:multiple</label>
    <select name="framework" multiple size="4">
        <option value="react">React</option>
        <option value="vue" selected>Vue</option>
        <option value="svelte">Svelte</option>
        <option value="astro" selected>Astro</option>
    </select>

    <!-- ファイル・その他 -->
    <label>input:file</label>
    <input type="file" accept=".pdf,.png,.jpg">

    <label>input:color</label>
    <input type="color" value="#5b87dd">

    <label>input:hidden</label>
    <input type="hidden" name="token" value="abc123">

    <label>input:text + datalist</label>
    <input type="text" list="cities" placeholder="都市名を入力">
    <datalist id="cities">
        <option value="東京">
        <option value="大阪">
        <option value="京都">
        <option value="福岡">
    </datalist>

    <!-- 状態 -->
    <label>input:text [disabled]</label>
    <input type="text" value="編集できません" disabled>

    <label>input:text [readonly]</label>
    <input type="text" value="変更不可・送信は含まれる" readonly>

    <label>input:text [required]</label>
    <input type="text" placeholder="必ず入力してください" required>

    <label>input:text [autocomplete]</label>
    <input type="text" autocomplete="street-address" placeholder="住所">

    <!-- ボタン系 -->
    <label>input:submit</label>
    <input type="submit" value="送信する">

    <label>input:reset</label>
    <input type="reset" value="リセット">

    <label>input:button</label>
    <input type="button" value="カスタムアクション">

    <label>input:image</label>
    <input type="image" src="button.png" alt="送信">

    <!-- 進捗・メーター -->
    <label>progress</label>
    <progress value="70" max="100"></progress>

    <label>meter</label>
    <meter value="6" min="0" max="10" low="3" high="8" optimum="2"></meter>

</form>

SCSS

グループ分けは要調整

input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="tel"],input[type="search"]{
    &:not([type]){}
}

input[type="number"],input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"],input[type="week"]{
    &:not([type]){}
}

input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="tel"],input[type="search"],input[type="number"],input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"],input[type="week"],textarea{
    &:not([type]){}
}

input[type="checkbox"],input[type="radio"]{
    &:not([type]){}
}

select,select[multiple]{
    &:not([multiple]){}
}

input[type="submit"],input[type="reset"],input[type="button"],input[type="image"],button{
    &:not([type]){}
}

input,textarea,select{
    &:disabled{}
    &:read-only{}
    &:required{}
    &:valid{}
    &:invalid{}
    &:focus{}
    &:placeholder-shown{}
}

input[type="range"]{}
input[type="color"]{}
input[type="file"]{}
input[type="hidden"]{}
progress{}
meter{}

疑似要素まで頑張るなら

input,textarea,select{

    // テキスト入力中のプレースホルダー
    &::placeholder{}

    // テキスト選択時
    &::selection{}

    // フォーカス時(マウス・キーボード両方)
    &:focus{}

    // フォーカス時(キーボード操作のみ)
    &:focus-visible{}

    // プレースホルダーが表示されている間(未入力)
    &:placeholder-shown{}

    // バリデーション
    &:valid{}
    &:invalid{}

    // 必須・任意
    &:required{}
    &:optional{}

    // 活性・非活性
    &:enabled{}
    &:disabled{}

    // 読み取り専用・編集可能
    &:read-only{}
    &:read-write{}

    // 数値の範囲
    &:in-range{}
    &:out-of-range{}

    // ブラウザ自動補完
    &:autofill{}
    &:-webkit-autofill{} // ベンダープレフィックス(Chrome・Safari)
}

// チェック・選択状態(checkbox・radio)
input[type="checkbox"],input[type="radio"]{
    &:checked{}
    &:indeterminate{} // 不定状態(checkboxのみ)
}

// 親要素がフォーカス状態を検知
.form-group{
    &:focus-within{}
}

// ファイル選択ボタン
input[type="file"]{
    &::file-selector-button{}
}

コメント

タイトルとURLをコピーしました