私(そして、私にとっては多くの皆さん)は、サイトデザインと選択の非互換性に何度も遭遇しました。 苦痛は、スタイルを設定できず、各ブラウザで独自のスタイルに見えることです。
もちろん、フレームワーク/ライブラリ(同じブートストラップ)によって提供される膨大な数のソリューションがあります。 しかし、それらはすべてJSaの存在を示唆しています。 もちろん、これは大したことでも悪いことでもありませんが、JSが何らかの理由で壊れた場合のフォールバックとして、JSのない様式化された選択をしようとしました。
選択してください
ツール選択
このコンテキストのツールとは、selectを置き換えるものを意味します。 そして、私の選択は、同様の動作のためにラジオボタンに落ちました。一度に1つのオプションしか選択できません。
<div class="options"> <label> <input type="radio" name="r" value="111" checked> <div class="value">11text11</div> </label> ....
不要なIDとfor-ssを作成しないように、ラジオボタンを<label />でラップしました。
ロジック
選択のように目的のアイテムの選択を実装するには、リストの最上位にいる必要があります。 これを行うには、選択した要素の値を絶対的に配置し(ストリームから抜け出す)、最上部に配置する必要があることを示します。
#dropdown .options :checked + .value{ position: absolute; top: 0; }
また、ルールを遵守する必要があります。各アイテムの高さは、選択したアイテムの「空いている」場所(上からインデント)と等しくなければなりません
#dropdown .options .value{ height: var(--item-height); } #dropdown .options{ padding-top: var(--item-height); }
主な部分は機能します-アイテムを選択すると、先頭に表示されます。 「穏やかな」状態では、選択された項目のみが表示され、リストの残りの部分がクリック時に開かれ、「ミルク」をクリックすると、値を変更せずにリストが閉じられます。
擬似セレクター操作が思い浮かびます:focus 。 その下にある入力を追加します。 [type = text]を選択したのは、サイズ(幅と高さ全体に拡大)に設定でき、選択した先頭の要素を覆い隠すことができるからです。
<div class="dropdown" id="dropdown"> <input type="text"> <div class="options"> ....
ドロップダウンリストを非表示にすると、高さの制限とオーバーフローが表示されます:hidden :
#dropdown .options{ padding-top: var(--item-height); overflow: hidden; height: 0; } #dropdown > :focus + .options{ height: var(--list-height); }
もちろん、入力は表示されるべきではありません(オプションを表すラジオボタンも同様):
#dropdown input{ opacity: 0; }
不透明度を使用:0; 表示の代わりに:なし; 非表示要素( 視覚的に:非表示を含む)がstate :focusを持つことができないという事実のため。
ダーティハック
そして、すべてがうまくいったように思えたとき、私は驚きに出会いました。リストからメニュー項目をクリックすると、リスト項目をクリックするよりもコントロール入力からのフォーカスが速くなります。 つまり、ミルクをクリックしたときとまったく同じことが起こります-リストが閉じます。
ドロップダウンリストを非表示にする前に遅延を増やすには、ダーティハックを使用する必要があります。
#dropdown .options{ ... transition: 0s .1s height; }
完了、例を参照してください(美のためにいくつかのスタイルを追加しました): https : //jsfiddle.net/2k1pvbyt/
複数選択
さらに先に進むと、同じ方法で(JSを使用せずに)複数選択を行います。 すべてのjquery-pluginインテグレーターがJS(JQuery)でこれを行うわけではありませんが、あなたと私は私たちの考えを決めました! よく言った-完了、あなたは泥の中に伏せてはいけない。 これが可能かどうかを把握してみましょう。 そして、そうでない場合、特定の瞬間にjsなしではできないこと。
選択をマルチにするために、前の例で何を変更する必要がありますか? 各項目は、他の項目に関係なく選択できる必要があります。 当然、ラジオボタンをチェックボックスに変更する必要があります。
<label data-value="111"> <input type="checkbox" required> </label>
はい、これがすべてではなく、 requiredは偶然ではありません。その助けを借りて、リストを操作します。
<fieldset> <label data-value="111"> <input type="checkbox" required> </label> </fieldset>
これを<fieldset />でラップすると、次の疑似セレクターを操作できるようになります:valid / :invalid 。
<fieldset/>, <form/> :valid , :valid
正確に何をすべきかを理解するには、問題を明確に述べなければなりません。
強調表示されたアイテムをリストの一番上に置きます。 それと同じ行には、他の強調表示された項目があります。
選択した項目をリストの一番上に配置するのは簡単です。display:flexを親に設定し、 order値で再生します:
#dropdown .options > fieldset:invalid{ order: 2; } #dropdown .options{ display: flex; flex-wrap: wrap; } #dropdown fieldset{ flex-basis: 100%; }
最初の条件が満たされ、選択したすべての要素を1行に配置するために、選択したアイテムに設定します。
#dropdown .options > fieldset:valid{ flex-basis: 10%; z-index: 3; }
出来上がり! 動作するようです。
おわりに
私たちは、jsなしではどこに(タスクのフレームワーク内で)できないのかを見つけることができませんでした。
おそらく(確かに)、これはより複雑な例に当てはまります。
例への重複リンク:
さて、この「大量のマークアップ」を自分の手で書きたくない人のために、私はあなたのためにそれを行うスクリプトを入れました。
アドオンやその他の問題は大歓迎です、間違いなく!
UPD
アイデアは、制御入力を使用するようになりました。 nojsの概念から離れると、初期化にjsコンストラクターが使用されます。
行われた変更の中で:
- フォーカスがある場合、入力を非表示にするのではなく、先頭ポイントの下に移動します
- この事業では、「空席」を増やします
- 初期化するときに、この入力のハンドラーを切断します。これにより、 入力イベントのフィルタリングに必要なcssストリングが生成されます