skip to Main Content

So currently I have a UI slider that is changing data on a price-list form as the value changes, the problem I can’t seem to figure out is how to grey out one or more of these boxes if a certain value hits.

I attached an image to explain what I want to achieve when 1 user is selected on the slider and what I want it to show if 2-4 users are selected on the UI slider. Any help would be greatly appreciated I really am struggling with this.

enter image description here I made in photoshop to explain better what I hope to achieve, I removed the code I tried with because it wasn’t working and not sure if I was going at it the right way, any help I would be grateful for as I am really hitting my head against the wall here.

I need to grey out the following div box when the slider moves

<div class="pricing-item">
      <div class="pricing-item-inner">
        <div class="pricing-item-content">
          <div class="pricing-item-header">
            <div class="pricing-item-title">Advanced</div>
            <div
              class="pricing-item-price"
              data-price-output='{
                  "0": ["$", "13", "/m"],
                  "1": ["$", "17", "/m"],
                  "2": ["$", "21", "/m"],
                  "3": ["$", "25", "/m"],
                  "4": ["$", "42", "/m"]
                }'
            >
              <span class="pricing-item-price-currency"></span>
              <span class="pricing-item-price-amount"></span>
              <span class="pricing-item-price-after"></span>
            </div>
          </div>
          <div class="pricing-item-features">
            <ul class="pricing-item-features-list">
              <li class="is-checked">Excepteur sint occaecat</li>
              <li class="is-checked">Excepteur sint occaecat</li>
              <li class="is-checked">Excepteur sint occaecat</li>
              <li class="is-checked">Excepteur sint occaecat</li>
              <li class="is-checked">Excepteur sint occaecat</li>
            </ul>
          </div>
        </div>
        <div class="pricing-item-cta">
          <a class="button" href="#">Buy Now</a>
        </div>
      </div>
    </div>

Here is the link to codepen for the code: https://codepen.io/daniel-smit/pen/ZEQELRa

Any help really would be appreciated.

2

Answers


  1. To make it work in the way you want, you have to create an overlay <div> with position:absolute inside each pricing-item tag element along with some other styles to position it inside its pricing-item parent, give pricing-item position relative, so that it will be position reference for the overlays. also add unique class for each of the three pricing-item, I give them left, middle and right class, so that we can reference them based on the slider <range> input.

    .pricing-item {
      flex-basis: 280px;
      max-width: 280px;
      box-sizing: content-box;
      padding: 12px;
      position: relative;
    }
    
    .overlay {
      position: absolute;
      left: 12px;
      top: 0;
      background-color: rgba(0, 0, 0, 0.5);
      width: calc(100% - 24px);
      height: calc(100% - 12px);
      display: none;
      z-index: 1;
    }
    

    and inside handlePricingSlider() function I add this code:

    let val = +input.el.value;
    document.querySelectorAll(".pricing-item.overlay").forEach((el) => {
      el.style.display = "none";
    });
    if (val === 0) {
      document
        .querySelectorAll(
          ".pricing-item.left .overlay, .pricing-item.right .overlay"
        )
        .forEach((el) => {
          el.style.display = "block";
        });
    } else if (val === 1) {
      document.querySelectorAll(".pricing-item.right .overlay").forEach((el) => {
        el.style.display = "block";
      });
    } else if (val > 1) {
      document.querySelectorAll(".pricing-item.right .overlay").forEach((el) => {
        el.style.display = "none";
      });
    }
    

    What this code do is first reset/remove the overlay <div> on all element then check for the <range> input value, if the value is 0 it will gray-out left and right columns, if its 1 it will gray-out the right column, else the layout will be removed.

    Here is a snippet:

    (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);
          });
        }
      }
    
      function handlePricingSlider(input, output) {
        // output the current slider value
        if (input.currentValEl)
          input.currentValEl.innerHTML = input.data[input.el.value];
    
        // update prices
        for (let i = 0; i < output.length; i++) {
          const outputObj = output[i];
          if (outputObj.currency)
            outputObj.currency.innerHTML = outputObj.data[input.el.value][0];
          if (outputObj.amount)
            outputObj.amount.innerHTML = outputObj.data[input.el.value][1];
          if (outputObj.after)
            outputObj.after.innerHTML = outputObj.data[input.el.value][2];
        }
        handleSliderValuePosition(input);
        let val = +input.el.value;
        document.querySelectorAll(".pricing-item .overlay").forEach((el) => {
          el.style.display = "none";
        });
        if (val === 0) {
          document
            .querySelectorAll(
              ".pricing-item.left .overlay, .pricing-item.right .overlay"
            )
            .forEach((el) => {
              el.style.display = "block";
            });
        } else if (val === 1) {
          document
            .querySelectorAll(".pricing-item.right .overlay")
            .forEach((el) => {
              el.style.display = "block";
            });
        } else if (val > 1) {
          document
            .querySelectorAll(".pricing-item.right .overlay")
            .forEach((el) => {
              el.style.display = "none";
            });
        }
      }
    
      function handleSliderValuePosition(input) {
        const multiplier = input.el.value / input.el.max;
        const thumbOffset = input.thumbSize * multiplier;
        const priceInputOffset =
          (input.thumbSize - input.currentValEl.clientWidth) / 2;
        input.currentValEl.style.left =
          input.el.clientWidth * multiplier - thumbOffset + priceInputOffset + "px";
      }
    })();
    *,
    *:before,
    *:after {
    	box-sizing: border-box;
    }
    
    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: #5f48ff;
    	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: #eef1f6;
    	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: #5f48ff;
    	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: 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: none;
    	border-radius: 50%;
    	cursor: pointer;
    	height: 36px;
    	width: 36px;
    }
    
    input[type="range"]::-ms-thumb {
    	background-color: #5f48ff;
    	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-focus-outer {
    	border: 0;
    }
    
    .pricing-slider {
    	max-width: 280px;
    	margin: 0 auto;
    }
    
    .form-slider span {
    	display: block;
    	font-weight: 500;
    	text-align: center;
    	margin-bottom: 16px;
    }
    
    .pricing-slider {
    	margin-bottom: 48px;
    }
    
    .pricing-slider {
    	max-width: 280px;
    	margin-left: auto;
    	margin-right: auto;
    	position: relative;
    }
    
    .pricing-slider input {
    	width: 100%;
    }
    
    .pricing-slider .pricing-slider-value {
    	position: absolute;
    	font-size: 14px;
    	line-height: 22px;
    	font-weight: 500;
    	color: #909cb5;
    	margin-top: 8px;
    	--thumb-size: 36px;
    }
    
    .pricing-items {
    	display: flex;
    	flex-wrap: wrap;
    	justify-content: center;
    	margin-right: -12px;
    	margin-left: -12px;
    	margin-top: -12px;
    }
    
    .pricing-item {
    	flex-basis: 280px;
    	max-width: 280px;
    	box-sizing: content-box;
    	padding: 12px;
    	position: relative;
    }
    
    .overlay {
    	position: absolute;
    	left: 12px;
    	top: 0;
    	background-color: rgba(0, 0, 0, 0.5);
    	width: calc(100% - 24px);
    	height: calc(100% - 12px);
    	display: none;
    	z-index: 1;
    }
    
    .pricing-item-inner {
    	display: flex;
    	flex-wrap: wrap;
    	flex-direction: column;
    	height: 100%;
    	padding: 24px;
    	box-shadow: 0 8px 16px rgba(46, 52, 88, 0.16);
    }
    
    .pricing-item-title {
    	font-weight: 500;
    }
    
    .pricing-item-price {
    	display: inline-flex;
    	align-items: baseline;
    	font-size: 20px;
    }
    
    .pricing-item-price-amount {
    	font-size: 36px;
    	line-height: 48px;
    	font-weight: 500;
    	color: #191e2a;
    }
    
    .pricing-item-features-list {
    	list-style: none;
    	padding: 0;
    }
    
    .pricing-item-features-list li {
    	margin-bottom: 0;
    	padding: 14px 0;
    	position: relative;
    	display: flex;
    	align-items: center;
    }
    
    .pricing-item-features-list li::before {
    	content: "";
    	position: absolute;
    	top: 0;
    	left: 0;
    	width: 100%;
    	display: block;
    	height: 1px;
    	background: #e9ecf8;
    }
    
    .pricing-item-features-list li::after {
    	content: "";
    	display: block;
    	width: 24px;
    	height: 24px;
    	margin-right: 12px;
    	background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%2011h14v2H5z%22%20fill%3D%22%239298B8%22%20fill-rule%3D%22nonzero%22%2F%3E%3C%2Fsvg%3E");
    	background-repeat: no-repeat;
    	-webkit-box-ordinal-group: 0;
    	order: -1;
    }
    
    .pricing-item-features-list li.is-checked::after {
    	background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20fill-rule%3D%22nonzero%22%20fill%3D%22none%22%3E%3Ccircle%20fill%3D%22%2300C2A9%22%20cx%3D%2212%22%20cy%3D%2212%22%20r%3D%2212%22%2F%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M10.5%2012.267l-2.5-1.6-1%201.066L10.5%2016%2017%209.067%2016%208z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
    }
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <meta http-equiv="X-UA-Compatible" content="ie=edge" />
            <title>Pricing Switcher</title>
            <link href="https://fonts.googleapis.com/css?family=Heebo:400,500&display=swap" rel="stylesheet" />
            <link rel="stylesheet" href="style.css" />
            <style></style>
        </head>
        <body>
            <div class="pricing">
                <div class="pricing-slider">
                    <label class="form-slider">
                        <span>How many users do you have?</span>
                        <input
                            type="range"
                            value="1"
                            data-price-input='{
                    "0": "1",
                    "1": "2-4",
                    "2": "5-9",
                    "3": "10-24",
                    "4": "25+"                       
                  }'
                        />
                    </label>
                    <div class="pricing-slider-value"></div>
                </div>
    
                <div class="pricing-items">
                    <div class="pricing-item left">
                        <div class="overlay"></div>
                        <div class="pricing-item-inner">
                            <div class="pricing-item-content">
                                <div class="pricing-item-header">
                                    <div class="pricing-item-title">Basic</div>
                                    <div
                                        class="pricing-item-price"
                                        data-price-output='{
                        "0": ["", "Free", ""],
                        "1": ["$", "13", "/m"],
                        "2": ["$", "17", "/m"],
                        "3": ["$", "21", "/m"],
                        "4": ["$", "25", "/m"]
                      }'
                                    >
                                        <span class="pricing-item-price-currency"></span>
                                        <span class="pricing-item-price-amount"></span>
                                        <span class="pricing-item-price-after"></span>
                                    </div>
                                </div>
                                <div class="pricing-item-features">
                                    <ul class="pricing-item-features-list">
                                        <li class="is-checked">
                                            <div
                                                class="pricing-item-price"
                                                data-price-output='{
                        "0": ["Demo text 1"],
                        "1": ["Demo text 2"],
                        "2": ["Demo text 3"],
                        "3": ["Demo text 4"],
                        "4": ["Demo text 5"]
                      }'
                                            >
                                                <span class="pricing-item-price-currency"></span>
                                            </div>
                                        </li>
    
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li>Excepteur sint occaecat</li>
                                        <li>Excepteur sint occaecat</li>
                                    </ul>
                                </div>
                            </div>
                            <div class="pricing-item-cta">
                                <a class="button" href="#">Buy Now</a>
                            </div>
                        </div>
                    </div>
    
                    <div class="pricing-item middle">
                        <div class="overlay"></div>
                        <div class="pricing-item-inner">
                            <div class="pricing-item-content">
                                <div class="pricing-item-header">
                                    <div class="pricing-item-title">Advanced</div>
                                    <div
                                        class="pricing-item-price"
                                        data-price-output='{
                          "0": ["$", "13", "/m"],
                          "1": ["$", "17", "/m"],
                          "2": ["$", "21", "/m"],
                          "3": ["$", "25", "/m"],
                          "4": ["$", "42", "/m"]
                        }'
                                    >
                                        <span class="pricing-item-price-currency"></span>
                                        <span class="pricing-item-price-amount"></span>
                                        <span class="pricing-item-price-after"></span>
                                    </div>
                                </div>
                                <div class="pricing-item-features">
                                    <ul class="pricing-item-features-list">
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                    </ul>
                                </div>
                            </div>
                            <div class="pricing-item-cta">
                                <a class="button" href="#">Buy Now</a>
                            </div>
                        </div>
                    </div>
    
                    <div class="pricing-item right">
                        <div class="overlay"></div>
                        <div class="pricing-item-inner">
                            <div class="pricing-item-content">
                                <div class="pricing-item-header">
                                    <div class="pricing-item-title">Enterprise</div>
                                    <div
                                        class="pricing-item-price"
                                        data-price-output='{
                          "0": ["$", "22", "/m"],
                          "1": ["$", "33", "/m"],
                          "2": ["$", "42", "/m"],
                          "3": ["$", "88", "/m"],
                          "4": ["$", "105", "/m"]
                        }'
                                    >
                                        <span class="pricing-item-price-currency"></span>
                                        <span class="pricing-item-price-amount"></span>
                                        <span class="pricing-item-price-after"></span>
                                    </div>
                                </div>
                                <div class="pricing-item-features">
                                    <ul class="pricing-item-features-list">
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                        <li class="is-checked">Excepteur sint occaecat</li>
                                    </ul>
                                </div>
                            </div>
                            <div class="pricing-item-cta">
                                <a class="button" href="#">Buy Now</a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <script></script>
        </body>
    </html>
    Login or Signup to reply.
  2. Here is the updated code:
    https://codepen.io/tahabayi/pen/ExPaOKW

    HTML (mask div should be added under each inner div, and mask div can be enhanced according to needs)

        <div class="pricing-item">
            <div class="pricing-item-inner">
                <div class="pricing-item-inner pricing-item-inner-mask"></div>
                    .
                    .
            </div>
        </div>
    

    CSS

        .pricing-item-inner {
            .
            .
            position: relative;
        }
        .mask {
            display: block !important;
        }
        .pricing-item-inner-mask {
            background: gray;
            opacity: 80%;
            position: absolute;
            width: 100%;
            height: 100%;
            left: 0;
            top: 0;
            z-index: 1;
            display: none;
        }
    

    JS

        .
        .
        pricingOutputObj.after = pricingOutputEl.querySelector(
            ".pricing-item-price-after"
        );
        pricingOutputObj.mask = pricingOutputEl.parentNode.parentNode.parentNode.querySelector(
            ".pricing-item-inner-mask"
        );
        .
        .
        if (outputObj.after)
            outputObj.after.innerHTML = outputObj.data[input.el.value][2];
        if (outputObj.mask) {
            outputObj.mask.classList.remove("mask");
            if ((input.el.value == '0' && (i == 0 || i ==3)) || (input.el.value == '1' && i == 3)) {
              outputObj.mask.classList.add("mask");
            }
        }
        .
        .
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search