JSFiddle - React, Tailwind, and code Playground

by moob

HTML

<ul>
<li><a href="#" data-filter-primary="all">all</a></li>
<li><a href="#" data-filter-primary="1">filter 1</a><ul>
<li><a href="#" data-filter-secondary="a">a</a></li>
<li><a href="#" data-filter-secondary="b">b</a></li>
<li><a href="#" data-filter-secondary="c">c</a></li>
</ul></li>
<li><a href="#" data-filter-primary="2">filter 2</a><ul>
<li><a href="#" data-filter-secondary="d">d</a></li>
<li><a href="#" data-filter-secondary="e">e</a></li>
</ul></li>
</ul>

<section id="x">
<div data-primary-cat="1" data-cat="a">0</div>
<div data-primary-cat="1" data-cat="a">1</div>
<div data-primary-cat="1" data-cat="a">2</div>
<div data-primary-cat="1" data-cat="a">3</div>
<div data-primary-cat="1" data-cat="a">4</div>
<div data-primary-cat="1" data-cat="a">5</div>
<div data-primary-cat="1" data-cat="b">6</div>
<div data-primary-cat="1" data-cat="b">7</div>
<div data-primary-cat="1" data-cat="b">8</div>
<div data-primary-cat="1" data-cat="b">9</div>
<div data-primary-cat="1" data-cat="b">10</div>
<div data-primary-cat="1" data-cat="c">11</div>
<div data-primary-cat="1" data-cat="c">12</div>
<div data-primary-cat="1" data-cat="c">13</div>
<div data-primary-cat="1" data-cat="c">14</div>
<div data-primary-cat="1" data-cat="c">15</div>
<div data-primary-cat="2" data-cat="d">16</div>
<div data-primary-cat="2" data-cat="d">17</div>
<div data-primary-cat="2" data-cat="d">18</div>
<div data-primary-cat="2" data-cat="d">19</div>
<div data-primary-cat="2" data-cat="d">20</div>
<div data-primary-cat="2" data-cat="e">21</div>
<div data-primary-cat="2" data-cat="e">22</div>
<div data-primary-cat="2" data-cat="e">23</div>
<div data-primary-cat="2" data-cat="e">24</div>
<div data-primary-cat="2" data-cat="e">26</div>
<div data-primary-cat="2" data-cat="e">27</div>
<div data-primary-cat="2" data-cat="e">28</div>
<div data-primary-cat="2" data-cat="e">29</div>
</section>

<div>
results: <b id="count">0</b>.
showing page <b id="page">0</b> of <b id="pages">0</b>
<br/>
<a id="prev"...

CSS

#x {
  display: flex;
  flex-wrap: wrap;
  width: 60%;
  margin: auto;
  border: 1px solid red;
  /*height:220px;*/
}

#x div {
  display: block;
  position: relative;
  height: 100px;
  width: 150px;
  background: #ccc;
  margin: 5px;
  font-size: 2em;
  transition:all .3s;
}

#x div.hidden {
  display: none;
}

#x div.offpage {
  opacity: 0;
  transform:scale(0);
  position:absolute;
  z-index:-1;
  transition:none;
}

.intersecting{
  color:white;
}

#x div[data-cat="a"] {
  background: red;
}

#x div[data-cat="b"] {
  background: blue;
}

#x div[data-cat="c"] {
  background: green;
}

#x div[data-cat="d"] {
  background: purple;
}

#x div[data-cat="e"] {
  background: orange;
}

JavaScript

(function filterBlocks() {
  let nav = document.querySelector("ul"),
    container = document.getElementById("x"),
    cards = document.querySelectorAll("div[data-cat]"),
    count = document.getElementById("count"),
    page = document.getElementById("page"),
    pages = document.getElementById("pages"),
    prev = document.getElementById("prev"),
    next = document.getElementById("next"),
    pagination = {
      itemsPerPage: 6
    };

  (function jumbleDomOrder() {
    for (var i = container.children.length; i >= 0; i--) {
      container.appendChild(container.children[Math.random() * i | 0]);
    }
  })()
  


  nav.addEventListener('click', (e) => {
    if (e.target.dataset){
    if (e.target.dataset.filterPrimary) {
      var filterVal = e.target.dataset.filterPrimary;
      filterTo(filterVal,"primary-cat");
    }
    if (e.target.dataset.filterSecondary) {
      var filterVal = e.target.dataset.filterSecondary;
      filterTo(filterVal,"cat");
    }
    }
  });

  function filterTo(filterVal,filterType) {
    if (filterVal === "all" || filterVal==="") {
      show(cards);
      paginate();
      return;
    }
    hide(cards);
    show(document.querySelectorAll("div[data-"+filterType+"='" + filterVal + "']"));
    paginate();
  }

  function hide(elems) {
    addClass(elems, "hidden");
  }

  function show(elems) {
    removeClass(elems, "hidden");
  }

  function addClass(elems, classname) {
    for (i = 0; i < elems.length; ++i) {
      elems[i].classList.add(classname);
    }
  }

  function removeClass(elems, classname) {
    for (i = 0; i < elems.length; ++i) {
      elems[i].classList.remove(classname);
    }
  }
  


  function paginate() {
    let visibles = document.querySelectorAll("div[data-cat]:not(.hidden)");
    pagination.count = visibles.length;
    pagination.page = 1;
    pagination.pages = Math.ceil(visibles.length / pagination.itemsPerPage);

/*pagination.itemsPerPage =...