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コンストラクターが使用されます。







行われた変更の中で:









» 例を見る

» 指示とコード








All Articles