JSなしの選択/複数選択

私(そして、私にとっては多くの皆さん)は、サイトデザインと選択の非互換性に何度も遭遇しました。 苦痛は、スタイルを設定できず、各ブラウザで独自のスタイルに見えることです。


もちろん、フレームワーク/ライブラリ(同じブートストラップ)によって提供される膨大な数のソリューションがあります。 しかし、それらはすべて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コンストラクターが使用されます。


行われた変更の中で:



» 例を見る
» 指示とコード



Source: https://habr.com/ru/post/J313958/


All Articles