ラジオボタンとCSSを使ってソート機能を実装する

Tips

ラジオボタンとCSSを使ってソート機能を実装する

ラジオボタンとCSSを使って、特定の規則に従ってデータを並び替えるソート機能を実装するサンプルです。
ソート機能を実装しようと思ったらとりあえずJSを利用するのを考える人も多いと思いますが、本当に簡易的なものであればCSSでもそれっぽい動きが実装できます。

See the Pen CSS Sort Elements by Naoya (@nxworld)on CodePen.

上のデモのように、ページ上部にある「Reset」「Red」「Blue」「Yellow」をそれぞれ選択することによって、その下に並んでいる赤や青の要素が並び替えられる動きを実装していきます。
以前にもラジオボタンとCSSを組み合わせてちょっとした動きを実装するものとして「ラジオボタンとCSSを使ってレイアウトを切り替える」を紹介したのですが、今回も同様でラジオボタンの:checkedと間接セレクタ(~)を利用します。

まず、HTMLでソートの切り替えやリセットに利用するラジオボタン(<input type="radio">)とソートの対象となる要素(今回のサンプルの場合はli要素)をそれぞれ配置し、ラジオボタンにはソート時に利用するidを、ソート対象要素にはdata属性を利用して値を指定しておきます。
今回は「特定のカラーを持つ要素をソートする」動きの実装になるので、それぞれの値には「red」や「blue」といったカラーを表す命名を用いて、HTMLは下記のようなものを使用します。

HTML

<div class="sort-contents">
  <input id="sort-reset" type="radio" name="sort" checked><label for="sort-reset">Reset</label>
  <input id="sort-red" type="radio" name="sort"><label for="sort-red">Red</label>
  <input id="sort-blue" type="radio" name="sort"><label for="sort-blue">Blue</label>
  <input id="sort-yellow" type="radio" name="sort"><label for="sort-yellow">Yellow</label>

  <ul>
    <li data-color="red"></li>
    <li data-color="blue"></li>
    <li data-color="yellow"></li>
    <li data-color="red-blue"></li>
    <li data-color="blue"></li>
    <li data-color="red-yellow"></li>
    <li data-color="red"></li>
    <li data-color="blue-yellow"></li>
    ・
    ・
    ・
  </ul>
</div>

装飾に関する記述も多いですが、上記HTMLに対して下記のようなCSSを指定することでデモのようなソートの動きを実装することができます。

CSS

:root {
  --color-red: #e74c3c;
  --color-blue: #3498db;
  --color-yellow: #f1c40f;
}
.sort-contents {
  padding: 1em;
  text-align: center;
}
input[name="sort"] {
  display: none;
}
label {
  display: inline-block;
  margin: 0 1em;
  font-size: 1.2rem;
  font-family: 'Open Sans', sans-serif;
  font-weight: 300;
  cursor: pointer;
}
label:hover,
input[name="sort"]:checked + label {
  color: #000;
  border-bottom: 2px solid currentColor;
}
input[name="sort"]:checked + label {
  cursor: default;
}
label[for="sort-red"]:hover,
#sort-red:checked + label {
  color: var(--color-red);
}
label[for="sort-blue"]:hover,
#sort-blue:checked + label {
  color: var(--color-blue);
}
label[for="sort-yellow"]:hover,
#sort-yellow:checked + label {
  color: var(--color-yellow);
}
ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -20px;
  padding: 1em 0 0;
  list-style: none;
  text-align: left;
}
ul li {
  width: calc(20% - 40px);
  min-height: 150px;
  margin: 40px 20px 0;
}
[data-color="red"] {
  background: var(--color-red);
}
[data-color="blue"] {
  background: var(--color-blue);
}
[data-color="yellow"] {
  background: var(--color-yellow);
}
[data-color="red-blue"] {
  background: linear-gradient(var(--color-red) 50%, var(--color-blue) 50%);
}
[data-color="red-yellow"] {
  background: linear-gradient(var(--color-red) 50%, var(--color-yellow) 50%);
}
[data-color="blue-yellow"] {
  background: linear-gradient(var(--color-blue) 50%, var(--color-yellow) 50%);
}
[data-color="blue-red"] {
  background: linear-gradient(var(--color-blue) 50%, var(--color-red) 50%);
}
[data-color="yellow-red"] {
  background: linear-gradient(var(--color-yellow) 50%, var(--color-red) 50%);
}
[data-color="yellow-blue"] {
  background: linear-gradient(var(--color-yellow) 50%, var(--color-blue) 50%);
}
#sort-red:checked ~ ul [data-color*="red"],
#sort-blue:checked ~ ul [data-color*="blue"],
#sort-yellow:checked ~ ul [data-color*="yellow"] {
  order: -1;
}

実装のポイントになるのがul要素に指定しているdisplay: flexとコード下部のorder: -1で、具体的にはFlexboxを利用して配置された要素をorderを変更することで並び替えるというものになります。
各ラジオボタンが選択された際、間接セレクタ(~)と:checkedを使用して兄弟関係で且つソート対象要素の親要素であるul要素へスタイル指定し、そこで特定のdata属性を持つ要素のorder値を変更させることでデモのような動きを実装することができます。
また、order: -1を指定しているセレクタにある[data-color*="red"]のように特定のdata属性指定に部分一致を用いることで、今回のサンプルにあるdata-color="red-blue"data-color="yellow-red"のような複数の値を持つものも対象にすることができます。

もっと複雑な条件とか動きをつけたいとなるとやはりJSを利用することになりますが、先述したように本当に簡易的なものであればJSを利用しなくともこのような動きが実装できるので、覚えておくと使えそうな場面があると思います。

Posted on

Category : Tips

Close the search window,
please press close button or esc key.