How to Make Custom Price Range Slider using JavaScript

price range slider

Introduction

In this comprehensive guide, we will walk through the process of crafting a sophisticated Custom Price Range Slider using a combination of HTML, CSS, and JavaScript. This slider not only provides an elegant user interface but also incorporates features such as dynamic color gradients and smooth animations. Follow along as we dissect each segment of the code, elucidate the underlying logic, and guide you in implementing this visually appealing price range slider for your website.

HTML Structure

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Price Range Slider</title>
  </head>
  <body>
    <main id="app">
      <h1 class="header">Custom Price Range Slider</h1>
      <div id="custom-slider"></div>
    </main>
  </body>
</html>
HTML

HTML Breakdown:

  • Application Wrapper: The main container for the price range slider.
  • Header: A title for the slider, providing context for users.
  • Slider Container: The element where the custom price range slider will be rendered.

CSS Styling

@import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@300;400;500;600;700&family=Poppins:wght@300;400;500;600;700;800&display=swap");

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Comfortaa", cursive;
}

#CustomGradientSlider {
  --color1: hsl(219, 73%, 65%);
  --color2: hsl(283, 100%, 69%);
  --colorMix: hsl(256, 100%, 59%);
  --range-pip: #ccc;
  --range-pip-in-range: var(--colorMix);
  --spring-duration: 1.5s;
  --spring-easing: linear(
    0,
    0.576 4%,
    0.79,
    0.964,
    1.102,
    1.205,
    1.275 13.6%,
    1.298,
    1.313,
    1.32,
    1.32,
    1.313 19.3%,
    1.299 20.7%,
    1.256 23.4%,
    1.111 30.5%,
    1.047 34.2%,
    1.018,
    0.996,
    0.979,
    0.968 42.9%,
    0.961 46.1%,
    0.962 49.7%,
    0.994 63.9%,
    1.004 72%,
    1.005 79.2%,
    1
  );

  --color: var(--color1);
  --shadow-color: 0deg 0% 0%;
  --shadow-elevation-medium: 0px 0.4px 0.4px
      hsl(var(--shadow-color) / 0.1),
    0px 0.8px 0.8px -0.8px hsl(var(--shadow-color) / 0.09),
    0px 1.6px 1.7px -1.5px hsl(var(--shadow-color) / 0.08),
    0px 3.5px 3.6px -2.3px hsl(var(--shadow-color) / 0.08),
    0px 6.9px 7.2px -3px hsl(var(--shadow-color) / 0.07);

  height: 14px;
}

#CustomGradientSlider .rangeBar {
  height: 100%;
  background: linear-gradient(90deg, var(--color1), var(--color2));
}

#CustomGradientSlider .rangeHandle[data-handle="1"] {
  --color: var(--color2);
}

#CustomGradientSlider .rangeHandle {
  width: 34px;
  height: 34px;
  top: calc(50% - 1px);
  border-radius: 50%;
  background: white;
  border: 2px solid var(--color);
  box-shadow: var(--shadow-elevation-medium);
  perspective: 500px;
}

#CustomGradientSlider .rangeNub {
  display: none;
}

#CustomGradientSlider .rangeFloat {
  border-radius: 0.5em;
  padding: 0.3em 0.6em;
  background: white;
  color: black;
  font-weight: bold;
  border: 2px solid var(--color);
  top: -1em;
  transform-origin: bottom center;
  transform: translate(-50%, -100%) rotateX(100deg) scaleY(0.75);
  transition: all var(--spring-easing) var(--spring-duration);
}

#CustomGradientSlider .rangeFloat:after {
  content: "";
  position: absolute;
  bottom: -2px;
  left: 50%;
  width: 9px;
  height: 9px;
  background: white;
  transform: translate(-50%, 50%) rotate(45deg);
  border-right: 2px solid var(--color);
  border-bottom: 2px solid var(--color);
}

#CustomGradientSlider.focus .rangeHandle .rangeFloat,
#CustomGradientSlider.hoverable .rangeHandle:hover .rangeFloat,
#CustomGradientSlider.hoverable:hover .rangeFloat {
  top: -1em;
  transform: translate(-50%, -100%) rotateX(0deg);
  opacity: 1;
}

/** move the slider to the left or right while dragging */
#CustomGradientSlider.up .rangeHandle.active .rangeFloat {
  transform: translate(-60%, -100%) rotateZ(-15deg);
}
#CustomGradientSlider.down .rangeHandle.active .rangeFloat {
  transform: translate(-40%, -100%) rotateZ(15deg);
}

/** style the pips when active and in range */
#CustomGradientSlider .pip {
  height: 2px;
  width: 2px;
  border-radius: 2px;
}
#CustomGradientSlider.focus .pip.in-range {
  background: white;
  box-shadow: 0 0 2px 1px var(--range-pip-in-range),
    0 0 5px 2px var(--range-pip-in-range),
    0 0 2px 0px var(--range-pip-in-range);
}

#app {
  margin-top: 150px;
  flex: 1 1 100%;
}

body,
html {
  flex: 0 1 90%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  text-align: center;
  background-color: #1e1c27;
}

h1,
p {
  margin: 0;
}

p {
  font-size: 1.4rem;
  color: #999;
  font-weight: 300;
  margin-bottom: 3em;
}

p:last-child {
  margin-top: 3em;
  margin-bottom: 0em;
}

.header {
  margin-bottom: 60px;
}
CSS

CSS Highlights:

  • Global Styles: Sets global styles, including font-family and box-sizing.
  • Slider Styles: Styles for the color gradients, handles, range, and additional effects.
  • Header Styles: Styles for the title/header section.

JavaScript Logic

import RangeSliderPips from "https://cdn.skypack.dev/svelte-range-slider-pips@2.2.2";

let values = [3000, 7000];
let timer;

const customSlider = document.getElementById("custom-slider");

const currencyFormatter = new Intl.NumberFormat("en", {
  style: "currency",
  currency: "USD",
  maximumFractionDigits: 0,
});

const formatCurrency = (value) => currencyFormatter.format(value);

const stopSlider = () => {
  const slider = document.querySelector("#CustomGradientSlider");
  slider.classList.remove("up", "down");
};

const slideHandler = (event) => {
  const slider = document.querySelector("#CustomGradientSlider");
  const delta = -(event.detail.previousValue - event.detail.value);
  if (delta > 0) {
    slider.classList.add("up");
    slider.classList.remove("down");
  } else {
    slider.classList.add("down");
    slider.classList.remove("up");
  }
  clearTimeout(timer);
  timer = setTimeout(stopSlider, 66);
};

const customRangeSlider = new RangeSliderPips({
  target: customSlider,
  props: {
    id: "CustomGradientSlider",
    min: 0,
    max: 10000,
    values: values,
    pips: true,
    range: true,
    pipstep: 200,
    first: false,
    last: false,
    float: true,
    formatter: formatCurrency,
  },
});

customRangeSlider.$on("change", slideHandler);
customRangeSlider.$on("stop", stopSlider);

setTimeout(() => {
  document.querySelector("#CustomGradientSlider .rangeHandle").focus();
}, 1000);
JavaScript

JavaScript Breakdown:

  • Import Libraries: Importing necessary libraries for the range slider (in this case, Svelte Range Slider Pips).
  • Variable Initialization: Initializing variables, including the minimum and maximum values, and the currency formatter.
  • Slider Configuration: Configuring the custom range slider with specific properties such as minimum, maximum, initial values, pips, range, and formatting options.
  • Event Handling: Managing slider-related events, including changes and stops, and incorporating smooth animations.

Conclusion

With this Custom Price Range Slider, you can enhance the user experience on your website by providing an intuitive and visually appealing way for users to select price ranges. Experiment with the code, customize styles, and integrate additional features to make this slider uniquely fit your website’s design.

Happy coding!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *