Prevent overlapping of range sliders in HTML and CSS

I have designed a range slider with two buttons, but they are overlapping each other. I want to ensure that they do not cross over one another - where the value of the first button should be equal to the minimum value of the second button, and the maximum value of the first button should be equal to the value of the second button. Additionally, I only want the selected range to be displayed in brown color, while the rest remains white.

Below is the code snippet:

.range_container {
  display: flex;
  flex-direction: column;
  margin-top: 30px;
}

.sliders-control {
  position: relative;
}

.form_control {
  position: relative;
  display: flex;
  justify-content: space-between;
  font-size: 24px;
  color: #635a5a;
}

input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  pointer-events: all;
  width: 15px;
  height: 15px;
  background-color: #fff;
  border-radius: 50%;
  box-shadow: 1px 1px 1px 1px gray;
  cursor: pointer;
}

input[type=range]::-moz-range-thumb {
  -moz-appearance: none;
  pointer-events: all;
  width: 15px;
  height: 15px;
  background-color: #fff;
  border-radius: 50%;
  box-shadow: 1px 1px 1px 1px gray;
  cursor: pointer;
 }

 input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 10px;
  width: 100%;
  position: absolute;
  background-color: brown;
  pointer-events: none;
  border-radius: 10px;
  border: 1px solid black;
}

.values{
  background-color: #3264fe;
  width: 32%;
  position: relative;
  margin: auto;
  padding: 10px 0;
  border-radius: 5px;
  text-align: center;
  font-weight: 500;
  font-size: 25px;
  color: #ffffff;
}
.values:before{
   content: "";
   position: absolute;
   height: 0;
   width: 0;
   border-top: 15px solid #3264fe;
   border-left: 15px solid transparent;
   border-right: 15px solid transparent;
   margin: auto;
   bottom: -14px;
   left: 0;
   right: 0;
}

#fromSlider {
  height: 0;
  z-index: 1;
  top: 5px;
  background: none;
  border: none;
}

#min-value {
  float: left;
}

#max-value {
  float: right;
}

<span id="min-value">&#x20b9;{{value1}}</span> <span id="max-value">&#x20b9;{{value2}}</span>
<div class="range_container">
  <div class="sliders-control">
    <input id="fromSlider" type="range" step="500" [(ngModel)] = "value1" value="{{value1}}" min="7000" max="100000" />
    <input id="toSlider" type="range" step="500" [(ngModel)] = "value2" value="{{value2}}" min="7000" max="100000" />
  </div>
</div>

Current output:

https://i.sstatic.net/aVLhI.png

Desired output:

https://i.sstatic.net/30Vf6.png

The objective is to prevent the slider buttons from crossing each other.

Answer №1

I trust this meets your requirements. I've incorporated some javascript code to handle the range slider and buttons.

function toggleSlider(fromSlider, toSlider) {
  const [from, to] = getParsed(fromSlider, toSlider);
  customizeSlider(fromSlider, toSlider, '#C6C6C6', 'brown', toSlider);
  if (from >= to) {
    fromSlider.value = to-500;
  }
}

function adjustToSlider(fromSlider, toSlider) {
  const [from, to] = getParsed(fromSlider, toSlider);
  customizeSlider(fromSlider, toSlider, '#C6C6C6', 'brown', toSlider);
  setToggleAccessibility(toSlider);
  if (from <= to) {
    toSlider.value = to;
  } else {
    toSlider.value = from+500;
  }
}

function getParsed(currentFrom, currentTo) {
  const from = parseInt(currentFrom.value, 10);
  const to = parseInt(currentTo.value, 10);
  return [from, to];
}

function customizeSlider(from, to, sliderColor, rangeColor, controlSlider) {
  const rangeDistance = to.max - to.min;
  const fromPosition = from.value - to.min;
  const toPosition = to.value - to.min;
  controlSlider.style.background = `linear-gradient(
      to right,
      ${sliderColor} 0%,
      ${sliderColor} ${(fromPosition)/(rangeDistance)*100}%,
      ${rangeColor} ${((fromPosition)/(rangeDistance))*100}%,
      ${rangeColor} ${(toPosition)/(rangeDistance)*100}%, 
      ${sliderColor} ${(toPosition)/(rangeDistance)*100}%, 
      ${sliderColor} 100%)`;
}

function setToggleAccessibility(currentTarget) {
  const toSlider = document.querySelector('#toSlider');
  if (Number(currentTarget.value) <= 0) {
    toSlider.style.zIndex = 2;
  } else {
    toSlider.style.zIndex = 0;
  }
}

const fromSlider = document.querySelector('#fromSlider');
const toSlider = document.querySelector('#toSlider');
customizeSlider(fromSlider, toSlider, '#C6C6C6', 'brown', toSlider);
setToggleAccessibility(toSlider);

fromSlider.oninput = () => toggleSlider(fromSlider, toSlider);
toSlider.oninput = () => adjustToSlider(fromSlider, toSlider);
.range_container {
  display: flex;
  flex-direction: column;
  margin-top: 30px;
}

.sliders-control {
  position: relative;
}

.form_control {
  position: relative;
  display: flex;
  justify-content: space-between;
  font-size: 24px;
  color: #635a5a;
}

input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  pointer-events: all;
  width: 15px;
  height: 15px;
  background-color: #fff;
  border-radius: 50%;
  box-shadow: 1px 1px 1px 1px gray;
  cursor: pointer;
}

input[type=range]::-moz-range-thumb {
  -moz-appearance: none;
  pointer-events: all;
  width: 15px;
  height: 15px;
  background-color: #fff;
  border-radius: 50%;
  box-shadow: 1px 1px 1px 1px gray;
  cursor: pointer;
}

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 10px;
  width: 100%;
  position: absolute;
  background-color: brown;
  pointer-events: none;
  border-radius: 10px;
  border: 1px solid black;
}

.values {
  background-color: #3264fe;
  width: 32%;
  position: relative;
  margin: auto;
  padding: 10px 0;
  border-radius: 5px;
  text-align: center;
  font-weight: 500;
  font-size: 25px;
  color: #ffffff;
}

.values:before {
  content: "";
  position: absolute;
  height: 0;
  width: 0;
  border-top: 15px solid #3264fe;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
  margin: auto;
  bottom: -14px;
  left: 0;
  right: 0;
}

#fromSlider {
  height: 0;
  z-index: 1;
  top: 6px;
  background: none;
  border: none;
}

#min-value {
  float: left;
}

#max-value {
  float: right;
}
<span id="min-value">&#x20b9;{{value1}}</span> <span id="max-value">&#x20b9;{{value2}}</span>
<div class="range_container">
  <div class="sliders-control">
    <input id="fromSlider" type="range" step="500" [(ngModel)]="value1" value="{{value1}}" min="7000" max="100000" />
    <input id="toSlider" type="range" step="500" [(ngModel)]="value2" value="{{value2}}" min="7000" max="100000" />
  </div>
</div>

Answer №2

updateSlider(event: any) {

  const value = event.target.value;
  const id = event.target.id;

  
  if ((id === 'fromSlider' && value > this.value2) || (id === 'toSlider' && value < this.value1)) {
    if (id === 'fromSlider') {
      this.value2 = value;
    } else {
      this.value1 = value;
    }
  }
}

Connect the event handler to handle the input event for each slider. Omit the value attribute as it is not needed when using Angular's two-way data binding with [(ngModel)] syntax.

 <input id="fromSlider" type="range" step="500" [(ngModel)]="value1" min="7000" max="100000" (input)="updateSlider($event)" />
<input id="toSlider" type="range" step="500" [(ngModel)]="value2" min="7000" max="100000" (input)="updateSlider($event)" />

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Difficulty in aligning Grid elements in Material UI version 5

Strange enough, the MUI5 Grid is displaying unexpected spacing behavior. Instead of providing proper spacing between items and containers, it seems to be causing them to overlap. To see a live example, visit: https://codesandbox.io/s/green-worker-z44vds? ...

What are the optimal strategies for managing various components within an Angular (2) Web application?

I am seeking advice on Angular 2+ Webapps and have a few questions. What is the recommended approach for managing a publicly available info page, an authentication page, and a protected page for signed-in users? Should I consider separate Angular Apps ...

Firing an Event with a specific target value using Jasmine

Is there a way to trigger a change event in a Jasmine unit test with the inclusion of a target.value? The component being tested contains a method similar to this: @HostListener('change', ['$event']) onChange(event) { const value = e ...

When using npm to install Angular Bootstrap, the versions that are installed do not always match the specific versions

Displayed below is the content of my package.json file. { "name": "MyProject", "private": true, "version": "0.0.0", "scripts": { "test": "karma start ClientApp/test/karma.conf.js" }, "devDependencies": { "@angular/animations": "5.0.2", "@angular/common": ...

Modifying the background color using highcharts.js

I am attempting to customize the background colors of a highcharts scatter plot. While I can easily change the color of a specific section using the code provided, my goal is to apply multiple colors to different ranges within the same plot. Specifically, ...

Uploader and viewer tool for HTML5 documents

My website is currently built using PHP and allows users to add and view documents. The current upload process is basic, requiring users to manually input information and then view the document with minimal formatting on a webpage. I am looking to upgrade ...

Styling with CSS or using tables: What should you choose?

Is there a way to replicate the frame=void functionality in CSS, or will I need to manually add frame=void to each table I create in the future? <table border=1 rules=all frame=void> I attempted to search for a solution online, but unfortunately, m ...

Encountered an error while attempting to compare 'true' within the ngDoCheck() function in Angular2

Getting Started Greetings! I am a novice in the world of Angular2, Typescript, and StackOverflow.com. I am facing an issue that I hope you can assist me with. I have successfully created a collapse animation for a button using ngOnChanges() when the butto ...

Trouble with AJAX communicating with PHP and not rendering fresh data

I have created a row of images that are clickable, and once clicked, a variable is sent via AJAX to a PHP file for a database query. The PHP file receives the variable and executes the correct query. However, instead of updating the HTML on my page, it sim ...

Implementing a configuration file into a client-side web application using asynchronous methods

Currently, I am facing a challenge with an SPA that is being developed using various custom components from different sources. The main issue at hand is how to initialize certain settings (such as Endpoint URLs) using a settings file that can be configure ...

The color of the textbox does not remain when it is focused

I've developed a custom CSS button style, which you can see here: http://jsfiddle.net/karimkhan/SgTy2/ However, when I implement the same CSS within the <style> tags on my page, the effect is not the same. It looks like this: The actual CSS on ...

Angular application navigation does not work as expected when the application is served in Express.js

I have an Angular 7 application that is running on an ExpressJS server. This is how the server part of the app is set up: app.get('/', (req, res) => { console.log(`sending...`); res.sendFile(path.join(__dirname, 'index.html') ...

Encountering the "Local resource can't be loaded" error when attempting to link a MediaSource object as the content for an HTML5 video tag

I'm attempting to make this specific example function properly. Everything runs smoothly when I click the link, but I encounter an error when trying to download the HTML file onto my local machine and repeat the process. An error message pops up sayi ...

Enabling CORS header 'Access-Control-Allow-Origin' in Angular 2 using Typescript

I am currently developing an Angular 2 typescript application on my localhost. I recently encountered an issue when trying to access an external REST API in my application, resulting in the following error message: Cross-Origin Request Blocked: The Same ...

The Bootstrap navbar stubbornly refuses to hide after being clicked on

Is there a way to adjust the data-offset-top for mobile view? Additionally, I am having trouble hiding the menu when clicking on a link. I have tried some code from stackoverflow without success. Can someone please assist with this issue: <nav class= ...

Issue with NgFor nested component not refreshing after @Input modification

When populating a component called ContactUpdatableItem within a NgFor, the code looks like this: <section class="plContactCreation-listItem" *ngFor="let contact of contacts$ | async; index as idx" > <contact-updatable-item [c ...

Could Flexbox CSS be used to create a responsive layout like this?

Appreciate your help in advance. I am facing a challenge with the current layout. <article> <section class="content">1</section> <aside class="ads">2</aside> <section class="comments">3</section> < ...

alignment of text output and label that responds to various screensizes

Here is some html code with a label and an output next to it. <div class="panel-body"> <div class="col-sm-6"> <label class="head6">Company Name : </label><span class="head9 halfR"> ...

Use the constant INLINE with npm commands to specify inline behavior

Today I was working on Angular2 using the template provided at . Following the installation guide, I executed the commands as instructed. I have successfully installed Node.js v6.9.1. npm install --Executed without any issues. npm server --Encountered a ...

JavaScript is failing to execute the DELETE SQL transaction

I've been attempting to clear out my html5 local sql database, but for some reason, it's not working as expected. Below is the code I'm using, and no matter what I try, the alert always shows that the length is greater than 0. Any ideas why ...