JSFiddle - React, Tailwind, and code Playground
Pricing Slider - Pure JS
by Christopher O
HTML
<script src="https://fonts.googleapis.com/css?family=Heebo:400,500&display=swap"></script>
<!DOCTYPE html>
<div class="pricing">
<div class="pricing-slider">
<label class="form-slider">
<span style="white-space: nowrap;">How many Active Contacts per month?</span>
<div class="pricing-slider-value"></div><br>
<input type="range" value="0" data-price-input='{
"0": "200",
"1": "1,000",
"2": "2,500",
"3": "5,000",
"4": "10,000",
"5": "25,000",
"6": "50,000",
"7": "75,000",
"8": "100,000+"
}' />
</label>
<!-- <div class="pricing-slider-value"></div> -->
</div>
<div class="pricing-items">
<div class="pricing-item" id="connectplan">
<div class="pricing-item-inner">
<div class="pricing-item-content">
<div class="pricing-item-header">
<div class="pricing-item-title">Connect</div>
<span class="pricing-item-price-amount">Free</span>
</div>
<div class="bestfor">
<strong>Best for: </strong>Small teams wanting to centralize and collaborate on customer messages
</div>
<div class="pricing-item-features">
<ul class="pricing-item-features-list">
<li class="is-checked">Unlimited users</li>
<li class="is-checked">Unlimited chats <span class="sub">1</span></li>
<li class="is-checked">Unlimited messages</li>
<li class="is-checked">1 inbox</li>
<li class="is-checked">20 contact fields</li>
<li class="is-checked">10,000 contacts storage</li>
...
CSS
*,
*:before,
*:after {
box-sizing: border-box;
}
.smaller{
font-size:12px !important;
color: #ccc !important;
margin: -20px 0 0 0 !important;
}
html {
font-size: 16px;
line-height: 24px;
letter-spacing: -0.1px;
}
body {
color: #607090;
font-size: 1rem;
margin: 0;
padding: 48px;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
}
body,
button,
input,
select,
textarea {
font-family: "Heebo", sans-serif;
font-weight: 400;
}
.button {
display: flex;
width: 100%;
font-size: 14px;
line-height: 22px;
font-weight: 700;
padding: 12px 29px;
text-decoration: none !important;
text-transform: uppercase;
color: #ffffff;
background-color: #00c5cd;
border-width: 1px;
border-style: solid;
border-color: transparent;
border-radius: 2px;
cursor: pointer;
justify-content: center;
text-align: center;
letter-spacing: inherit;
white-space: nowrap;
transition: background 0.15s ease;
}
input[type="range"] {
-moz-appearance: none;
-webkit-appearance: none;
background: #aaa;
border-radius: 3px;
height: 6px;
width: 100%;
margin-top: 15px;
margin-bottom: 15px;
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
appearance: none;
-webkit-appearance: none;
background-color: #00c5cd;
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2212%22%20height%3D%228%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M8%20.5v7L12%204zM0%204l4%203.5v-7z%22%20fill%3D%22%23FFFFFF%22%20fill-rule%3D%22nonzero%22%2F%3E%3C%2Fsvg%3E");
background-position: center;
background-repeat: no-repeat;
border: 0;
border-radius: 50%;
cursor: pointer;
height: 36px;
width: 36px;
}
input[type="range"]::-moz-range-thumb {
background-color: #5f48ff;
background-image:...
JavaScript
(function() {
const pricingSliders = document.querySelectorAll(".pricing-slider");
if (pricingSliders.length > 0) {
for (let i = 0; i < pricingSliders.length; i++) {
const pricingSlider = pricingSliders[i];
// Build the input object
const pricingInput = {
el: pricingSlider.querySelector("input")
};
pricingInput.data = JSON.parse(
pricingInput.el.getAttribute("data-price-input")
);
pricingInput.currentValEl = pricingSlider.querySelector(
".pricing-slider-value"
);
pricingInput.thumbSize = parseInt(
window
.getComputedStyle(pricingInput.currentValEl)
.getPropertyValue("--thumb-size"),
10
);
// Build the output array
const pricingOutputEls = pricingSlider.parentNode.querySelectorAll(
".pricing-item-price"
);
const pricingOutput = [];
for (let i = 0; i < pricingOutputEls.length; i++) {
const pricingOutputEl = pricingOutputEls[i];
const pricingOutputObj = {};
pricingOutputObj.currency = pricingOutputEl.querySelector(
".pricing-item-price-currency"
);
pricingOutputObj.amount = pricingOutputEl.querySelector(
".pricing-item-price-amount"
);
pricingOutputObj.after = pricingOutputEl.querySelector(
".pricing-item-price-after"
);
pricingOutputObj.data = JSON.parse(
pricingOutputEl.getAttribute("data-price-output")
);
pricingOutput.push(pricingOutputObj);
}
pricingInput.el.setAttribute("min", 0);
pricingInput.el.setAttribute(
"max",
Object.keys(pricingInput.data).length - 1
);
!pricingInput.el.getAttribute("value") &&
pricingInput.el.setAttribute("value", 0);
handlePricingSlider(pricingInput, pricingOutput);
window.addEventListener("input", function() {
handlePricingSlider(pricingInput, pricingOutput);
});
...