<div class="container">
<div class="dropdown-wrapper">
<button class="dropdown-toggle" aria-expanded="false">
<span>Filter Colors</span>
<svg width="24" height="24" clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m16.843 10.211c.108-.141.157-.3.157-.456 0-.389-.306-.755-.749-.755h-8.501c-.445 0-.75.367-.75.755 0 .157.05.316.159.457 1.203 1.554 3.252 4.199 4.258 5.498.142.184.36.29.592.29.23 0 .449-.107.591-.291 1.002-1.299 3.044-3.945 4.243-5.498z" />
</svg>
</button>
<div class="dropdown">
<ul>
<li class="active">
<a id="all" href="">All Colors</a>
</li>
<li>
<a id="red" href="">Red</a>
</li>
<li>
<a id="blue" href="">Blue</a>
</li>
<li>
<a id="pink" href="">Pink</a>
</li>
<li>
<a id="green" href="">Green</a>
</li>
<li>
<a id="yellow" href="">Yellow</a>
</li>
<li>
<a id="black" href="">Black</a>
</li>
<li>
<a id="maroon" href="">Maroon</a>
</li>
<li>
<a id="purple" href="">Purple</a>
</li>
<li>
<a id="gray" href="">Gray</a>
</li>
<li>
<a id="orange" href="">Orange</a>
</li>
</ul>
</div>
<p class="count">Showing <span>28</span> of 28 colors</p>
</div>
<ul class="boxes">
<li class="red" data-type="red"></li>
<li class="gray" data-type="gray"></li>
<li class="blue" data-type="blue"></li>
<li class="green" data-type="green"></li>
<li class="orange" data-type="orange"></li>
<li class="pink" data-type="pink"></li>
<li class="blue" data-type="blue"></li>
<li class="maroon" data-type="maroon"></li>
<li class="yellow" data-type="yellow"></li>
<li class="purple" data-type="purple"></li>
<li class="green" data-type="green"></li>
<li class="red" data-type="red"></li>
<li class="yellow" data-type="yellow"></li>
<li class="blue" data-type="blue"></li>
<li class="orange" data-type="orange"></li>
<li class="pink" data-type="pink"></li>
<li class="gray" data-type="gray"></li>
<li class="black" data-type="black"></li>
<li class="maroon" data-type="maroon"></li>
<li class="green" data-type="green"></li>
<li class="pink" data-type="pink"></li>
<li class="black" data-type="black"></li>
<li class="yellow" data-type="yellow"></li>
<li class="black" data-type="black"></li>
<li class="black" data-type="black"></li>
<li class="orange" data-type="orange"></li>
<li class="green" data-type="green"></li>
<li class="purple" data-type="purple"></li>
</ul>
</div>
<footer class="page-footer">
<span>made by </span>
<a href="https://georgemartsoukos.com/" target="_blank">
<img width="24" height="24" src="https://assets.codepen.io/162656/george-martsoukos-small-logo.svg" alt="George Martsoukos logo">
</a>
</footer>
/* RESET RULES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
:root {
--light-gray: #f5f3f4;
--white: #fff;
/*BOXES*/
--blue: #2349c7;
--pink: #efc3e6;
--gray: #8d99ae;
--maroon: #582f0e;
--red: #d62828;
--green: #2c6332;
--yellow: #ffc300;
--orange: #f08700;
--purple: #b388eb;
--black: #000814;
}
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
font-size: 20px;
margin: 50px 0;
}
.container {
max-width: 1600px;
padding: 0 15px;
margin: 0 auto;
}
/* DROPDOWN STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.dropdown-wrapper {
position: relative;
}
/*actions*/
.dropdown-wrapper.open .dropdown {
display: block;
}
.dropdown-wrapper.open .dropdown-toggle svg {
transform: rotate(180deg);
}
/*actions*/
.dropdown-wrapper .dropdown-toggle,
.dropdown-wrapper .dropdown {
width: 100%;
max-width: 400px;
border-radius: 5px;
border: 1px solid #adb5bd;
background: var(--white);
}
.dropdown-wrapper .dropdown-toggle {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px 0 26px;
text-align: left;
cursor: pointer;
font-size: 100%;
height: 50px;
}
.dropdown-wrapper .dropdown-toggle svg {
transition: transform 0.3s;
}
.dropdown-wrapper .dropdown {
display: none;
position: absolute;
top: 60px;
left: 0;
padding: 10px 10px 10px 0;
z-index: 1;
}
.dropdown-wrapper .dropdown ul {
padding: 0;
margin: 0;
list-style: none;
height: 300px;
overflow-y: auto;
}
.dropdown-wrapper .dropdown ul::scrollbar {
width: 10px;
}
.dropdown-wrapper .dropdown ul::scrollbar-thumb {
background: #e0e0e0;
}
.dropdown-wrapper .dropdown li a {
display: block;
padding: 15px 26px;
color: inherit;
text-decoration: none;
transition: background 0.1s;
}
.dropdown-wrapper .dropdown li.active a,
.dropdown-wrapper .dropdown li a:hover {
background: var(--light-gray);
}
/* BOXES STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.boxes {
padding: 0;
list-style: none;
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.boxes li {
aspect-ratio: 1;
}
.boxes li.hidden {
display: none;
}
.blue {
background: var(--blue);
}
.pink {
color: black;
background: var(--pink);
}
.gray {
background: var(--gray);
}
.maroon {
background: var(--maroon);
}
.red {
background: var(--red);
}
.green {
background: var(--green);
}
.yellow {
background: var(--yellow);
}
.orange {
background: var(--orange);
}
.purple {
background: var(--purple);
}
.black {
background: var(--black);
}
/* FOOTER STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.page-footer {
position: fixed;
right: 0;
bottom: 50px;
display: flex;
align-items: center;
padding: 5px;
z-index: 1;
font-size: 14px;
background: var(--white);
}
.page-footer a {
display: flex;
margin-left: 4px;
}
const dropdownWrapper = document.querySelector(".dropdown-wrapper");
const dropdownToggle = dropdownWrapper.querySelector(".dropdown-toggle");
const dropdownToggleSpan = dropdownToggle.querySelector("span");
const dropdown = dropdownWrapper.querySelector(".dropdown");
const dropdownLinks = dropdown.querySelectorAll("a");
const boxesList = document.querySelector(".boxes");
const boxes = boxesList.querySelectorAll("li");
const total = document.querySelector(".count span");
const HIDDEN_CLASS = "hidden";
const ACTIVE_CLASS = "active";
const OPEN_CLASS = "open";
//filter by default
const params = new URLSearchParams(location.search);
if (params.has("color")) {
const color = params.get("color");
const link = document.getElementById(color);
dropdown.querySelector("li.active").classList.remove(ACTIVE_CLASS);
link.parentElement.classList.add(ACTIVE_CLASS);
dropdownToggleSpan.innerText = link.innerText;
const includedBoxes = boxesList.querySelectorAll(`[data-type="${color}"]`);
const excludedBoxes = boxesList.querySelectorAll(
`li:not([data-type="${color}"])`
);
excludedBoxes.forEach((box) => box.classList.add(HIDDEN_CLASS));
includedBoxes.forEach((box) => box.classList.remove(HIDDEN_CLASS));
total.innerText = includedBoxes.length;
}
dropdownToggle.addEventListener("click", function () {
if (this.getAttribute("aria-expanded") == "true") {
this.setAttribute("aria-expanded", "false");
} else {
this.setAttribute("aria-expanded", "true");
}
dropdownWrapper.classList.toggle(OPEN_CLASS);
});
dropdownLinks.forEach(function (link) {
link.addEventListener("click", function (e) {
e.preventDefault();
const parent = this.parentElement;
const color = this.getAttribute("id");
dropdown.querySelector("li.active").classList.remove(ACTIVE_CLASS);
parent.classList.add(ACTIVE_CLASS);
dropdownWrapper.classList.remove(OPEN_CLASS);
dropdownToggle.setAttribute("aria-expanded", false);
dropdownToggleSpan.innerText = this.innerText;
if (color == "all") {
boxes.forEach((box) => box.classList.remove(HIDDEN_CLASS));
dropdownToggleSpan.innerText = "Filter Colors";
total.innerText = boxes.length;
history.pushState(null, "", location.href.split("?")[0]);
} else {
const includedBoxes = boxesList.querySelectorAll(
`[data-type="${color}"]`
);
const excludedBoxes = boxesList.querySelectorAll(
`li:not([data-type="${color}"])`
);
excludedBoxes.forEach((box) => box.classList.add(HIDDEN_CLASS));
includedBoxes.forEach((box) => box.classList.remove(HIDDEN_CLASS));
total.innerText = includedBoxes.length;
history.pushState(null, "", `?color=${color}`);
}
});
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.