CSSとHTMLで一覧要素を絞り込み表示っぽく見せる

CSSのみで一覧にした要素を絞り込み表示させる
CSSのみで一覧にした要素を絞り込み表示させる

以前に試した仕組みを転用すれば実現できるのでは、と思ったことを試作しました。

CSSだけで簡易に絞り込み表示を行えるように検討しているので、動作に制限はあるもののJSもPHPも不要な内容です。

実現したいこと

実現したいことは以下の通り。

  • CSSだけで絞り込みを行う

一覧で表示されたアイテムを絞り込み表示させる場合、JSを使ってページを移動せずクライアント側で処理をさせたり、PHPなどでサーバー側で用意したページに推移させたりが考えられます。

しかし今回はそういった目的と方法ではなく、CSSで絞り込みと似た見せ方ができないかと試しています。CSSのため画面推移がなく処理待ちもほぼないため、ユーザーにとって利便性もあるのではと考えました。

注意点

  • 動的な一覧取得と絞り込みではなく、あくまで静的HTMLの範囲に限る

今回の試作はAjaxなどで動的に一覧を読み込んでいるわけではなく、あくまでHTML上に現在存在する要素に対してのみの動作です。そのため「絞り込み表示っぽく見せる」というタイトルをつけています。

今後はどうかわかりませんが少なとも現時点では、HTMLとCSSのみで動的な一覧取得と絞り込みを行うことは不可能です。

サンプル1

以下がサンプルで上部のボタンを押せば動作します。

なお、画面サイズに合わせた調整はしていないため、スマホサイズの画面では見づらい感じになっていると思います。

Hタグは見出しに使います。
HTML
ifは条件分岐に使います。
PHP
colorは文字色を操作します。
CSS
=は右の値を左のオペランドに代入します。
JS
関数内のreturnは実行を停止させます。
PHP
pタグは段落に使います。
HTML
titleタグはページのタイトルに使います。
HTML
varは変数の宣言に使います。
JS
borderは枠線を操作します。
CSS
aタグはリンクに使います。
HTML
includeはファイルを読み込みます。
PHP

以下HTML。


<div class="refine">
  <input id="refine-0" type="radio" name="refine-btn" checked>
  <label class="refine-btn" for="refine-0">全表示</label>
  <input id="refine-1" type="radio" name="refine-btn">
  <label class="refine-btn" for="refine-1">HTML</label>
  <input id="refine-2" type="radio" name="refine-btn">
  <label class="refine-btn" for="refine-2">CSS</label>
  <input id="refine-3" type="radio" name="refine-btn">
  <label class="refine-btn" for="refine-3">JS</label>
  <input id="refine-4" type="radio" name="refine-btn">
  <label class="refine-btn" for="refine-4">PHP</label>

  <div class="refine-teims html"><p>Hタグは見出しに使います。</p><span class="refine-tag">HTML</span>
  </div>
  <div class="refine-teims php"><p>ifは条件分岐に使います。</p><span class="refine-tag">PHP</span>
  </div>
  <div class="refine-teims css"><p>colorは文字色を操作します。</p><span class="refine-tag">CSS</span>
  </div>
  <div class="refine-teims js"><p>=は右の値を左のオペランドに代入します。</p><span class="refine-tag">JS</span>
  </div>
  <div class="refine-teims php"><p>関数内のreturnは実行を停止させます。</p><span class="refine-tag">PHP</span>
  </div>
  <div class="refine-teims html"><p>pタグは段落に使います。</p><span class="refine-tag">HTML</span>
  </div>
  <div class="refine-teims html"><p>titleタグはページのタイトルに使います。</p><span class="refine-tag">HTML</span>
  </div>
  <div class="refine-teims js"><p>varは変数の宣言に使います。</p><span class="refine-tag">JS</span>
  </div>
  <div class="refine-teims css"><p>Hタグは見出しに使います。</p><span class="refine-tag">CSS</span>
  </div>
  <div class="refine-teims html"><p>aタグはリンクに使います。</p><span class="refine-tag">HTML</span>
  </div>
  <div class="refine-teims php"><p>includeはファイルを読み込みます。</p><span class="refine-tag">PHP</span>
  </div>
</div>

以下CSSですが、レイアウト関連は後述しますのでここでは肝心の動作部分だけ記述します。


input[name='refine-btn'] {
  position: relative;
  display: none;
}
input[name='refine-btn']:checked + label {
  color: #fff;
  background-color: #db6c34;
}
#refine-1:checked ~ .refine-teims:not(.html),
#refine-2:checked ~ .refine-teims:not(.css),
#refine-3:checked ~ .refine-teims:not(.js),
#refine-4:checked ~ .refine-teims:not(.php) {
  display: none;
}

サンプル2

別バージョン。

Hタグは見出しに使います。
HTML
ifは条件分岐に使います。
PHP
colorは文字色を操作します。
CSS
=は右の値を左のオペランドに代入します。
JS
関数内のreturnは実行を停止させます。
PHP
pタグは段落に使います。
HTML
titleタグはページのタイトルに使います。
HTML
varは変数の宣言に使います。
JS
borderは枠線を操作します。
CSS
aタグはリンクに使います。
HTML
includeはファイルを読み込みます。
PHP

クラスやnameの名称以外のHTML構造は同じなのでCSSだけ。


input[name='refine2-btn'] {
  position: relative;
  display: none;
}
input[name='refine2-btn']:checked + label {
  color: #fff;
  background-color: #db6c34;
}
#refine2-1:checked ~ .html,
#refine2-2:checked ~ .css,
#refine2-3:checked ~ .js,
#refine2-4:checked ~ .php {
  border-color: #db6c34;
}
#refine2-1:checked ~ .refine2-teims:not(.html),
#refine2-2:checked ~ .refine2-teims:not(.css),
#refine2-3:checked ~ .refine2-teims:not(.js),
#refine2-4:checked ~ .refine2-teims:not(.php) {
  opacity:.5;
}

参考サイト

この記事の仕組みは、以前に以下のページの情報を参考にして案件対応した時に思いついたものです。

この方法は「指定した要素を表示させる」という趣旨ですが、これができるなら「指定した要素以外を非表示にする」もできるなと。

問題点

いくつか問題点はありますが、一番面倒なのは「CSSで装飾がやりにくい」ということです。

兄弟要素を指定する仕組みの都合上、ボタンとなるlabelタグをdivタグなどで囲うことができず、そのまま続けて操作対象要素を並べなければなりません。

当記事のサンプルのように横に複数並べるタイプでは無理矢理なCSS設定をしないとなかなか整えられませんでした。

一応ですが、以下がその部分のCSSです。


.refine {
  display: flex;
  flex-wrap: wrap;
}
.refine-btn, .refine-teims {
  box-sizing: border-box;
  margin: 0 4px 10px 4px;
  border-style: solid;
  border-width: 1px;
}
.refine-btn {
  font-size: 14px;
  width: calc(20% - 8px);
  padding: 3px 0;
  text-align: center;
  border-radius: 3px;
  background-color: #fff;
  border-color: #999;
}
.refine-teims {
  position: relative;
  width: calc(25% - 8px);
  padding: 5px;
  border-color: #ccc;
}
.refine-teims p {
  margin: 0 0 2em 0;
}
.refine-tag {
  font-size: 14px;
  position: absolute;
  bottom: 5px;
  display: block;
  width: calc(100% - 10px);
  text-align: center;
  background-color: #eee;
}

ボタンだけが並ぶサイズにwidthを設定することで、divタグなどを使わずに見た目を整えている状態です。

内容や最終的なデザインによってはdisplay:flex;を使わない方が簡易にできるかもしれず、CSSの作り方は適宜検討が必要になります。

結び

一応、当サイトの以下のカテゴリーページで試しに付けています。

見られる場合は、サムネイルの数が多いため表示が重い可能性に留意してください。小さなサイズのサムネイルとはいえさすがに数が多いとそれなりになりますので。

WPのタグを利用しているため事前準備が多少必要ですが、肝心の仕組み部分は同じです。

仕組みよりもレイアウトやデザインで苦労をする手法だなと実感しました..。

補足

今回のサンプルの動作は以下のようにいえるかもしれません。

  • PC閲覧時には、多くの要素が見える都合上、他の要素の位置に影響を与えない点から、サンプル2が良い
  • スマホ閲覧時には、縦一列に並べる前提で、不要な要素を消せば縦方向のスクロール量を減らせる点から、サンプル1が良い

割と使えそうな気配もしてきましたが、いかんせんCSSの当て辛さは残ったままなので微妙です。

51人がこの記事を評価

役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。

連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。

コメント欄