Customize Slider ticks label in React Range Slider component

28 Feb 202512 minutes to read

The Slider view can be customized using CSS. By overriding the Slider CSS classes, you can customize the ticks appearance. The ticks in Slider allows you to easily identify the current value/values of the slider. It contains smallStep and largeStep. By default, Slider has the class e-tick for Slider ticks. You can override the class as per your requirement. Refer to the following code snippet to render ticks.

.e-scale .e-tick.e-custom::before {
    content: '\e967';
    position: absolute;
}
#ticks_slider .e-scale :nth-child(1)::before {
    color: red;
}

Here, the color for rendered ticks is applied using the nth-child(child_number). The color is applied to the tick corresponding to the child_number in the slider.

import * as React from 'react';
import * as ReactDOM from "react-dom";
import { SliderComponent } from '@syncfusion/ej2-react-inputs';
function App() {
  let value = [30, 70];
  let icon = { placement: "Before", largeStep: 20 };
  let custom = { placement: "Both", largeStep: 20, smallStep: 5 };
  function iconTicks(args) {
    if (args.tickElement.classList.contains("e-large")) {
      args.tickElement.classList.add("e-custom");
    }
  }
  function customTicks(args) {
    let li = args.ticksWrapper.getElementsByClassName("e-large");
    let remarks = ["Very Poor", "Poor", "Average", "Good", "Very Good", "Excellent"];
    for (let i = 0; i < li.length; ++i) {
      li[i].querySelectorAll(".e-tick-both")[1].innerText = remarks[i];
    }
  }
  return (<div id="container">
    <div className="col-lg-12 control-section">
      <div className="slider-content-wrapper">
        <div className="slider_container" id="slider_wrapper">
          <div className="slider_labelText userselect">Dynamic ticks color</div>
          <SliderComponent id="ticks_slider" type="MinRange" min={0} max={100} step={5} value={30} ticks={icon} renderingTicks={iconTicks.bind(this)} />
        </div>

        <div className="slider_container">
          <div className="slider_labelText userselect">Ticks with legends</div>
          <SliderComponent id="slider" type="MinRange" min={0} max={100} value={value} ticks={custom} renderedTicks={customTicks.bind(this)} />
        </div>
      </div>
    </div>
  </div>);
}
export default App;
ReactDOM.render(<App />, document.getElementById('element'));
import * as React from 'react';
import * as ReactDOM from "react-dom";
import { SliderComponent, SliderTickRenderedEventArgs, SliderTickEventArgs } from '@syncfusion/ej2-react-inputs';

function App() {
  let value: number[] = [30, 70];

  let icon: TicksDataModel = { placement: "Before", largeStep: 20 };

  let custom: TicksDataModel = { placement: "Both", largeStep: 20, smallStep: 5 };

  function iconTicks(args: SliderTickEventArgs): void {
    if (args.tickElement.classList.contains("e-large")) {
      args.tickElement.classList.add("e-custom");
    }
  }

  function customTicks(args: SliderTickRenderedEventArgs): void {
    let li: any = args.ticksWrapper.getElementsByClassName("e-large");
    let remarks: any = ["Very Poor", "Poor", "Average", "Good", "Very Good", "Excellent"];
    for (let i: number = 0; i < li.length; ++i) {
      (li[i].querySelectorAll(".e-tick-both")[1] as HTMLElement).innerText = remarks[i];
    }
  }

  return (
    <div id="container">
      <div className="col-lg-12 control-section">
        <div className="slider-content-wrapper">
          <div className="slider_container" id="slider_wrapper">
            <div className="slider_labelText userselect">Dynamic ticks color</div>
            <SliderComponent
              id="ticks_slider"
              type="MinRange"
              min={0}
              max={100}
              step={5}
              value={30}
              ticks={icon}
              renderingTicks={iconTicks.bind(this) as any}
            />
          </div>

          <div className="slider_container">
            <div className="slider_labelText userselect">Ticks with legends</div>
            <SliderComponent
              id="slider"
              type="MinRange"
              min={0}
              max={100}
              value={value}
              ticks={custom}
              renderedTicks={customTicks.bind(this) as any}
            />
          </div>
        </div>
      </div>
    </div>
  );
}
export default App;
ReactDOM.render(<App />, document.getElementById('element'));
.slider-content-wrapper {
  width: 40%;
  margin: 0 auto;
  min-width: 185px;
}

.userselect {
  -webkit-user-select: none;
  /* Safari 3.1+ */
  -moz-user-select: none;
  /* Firefox 2+ */
  -ms-user-select: none;
  /* IE 10+ */
  user-select: none;
  /* Standard syntax */
}

.slider_labelText {
  text-align: left;
  font-weight: 500;
  font-size: 13px;
  padding-bottom: 40px;
}

.slider_container {
  margin-top: 40px;
}

.e-bigger .slider-content-wrapper {
  width: 80%;
}

#ticks_slider .e-range {
  z-index: unset;
}

@font-face {
  font-family: 'e-customized-icons';
  src: url(data:application/x-font-ttf;charset=utf-8;base64,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) format('truetype');
  font-weight: normal;
  font-style: normal;
}

#ticks_slider .e-scale .e-tick {
  background-image: none;
  visibility: visible;
  font-family: 'e-customized-icons';
}

#ticks_slider .e-scale {
  z-index: 0;
}

#ticks_slider .e-scale .e-custom::before {
  content: '\e967';
  position: absolute;
}

#ticks_slider .e-scale :nth-child(1)::before {
  color: red;
}

#ticks_slider .e-scale :nth-child(2)::before {
  color: blue;
}

#ticks_slider .e-scale :nth-child(3)::before {
  color: green;
}

#ticks_slider .e-scale :nth-child(4)::before {
  color: blueviolet;
}

#ticks_slider .e-scale :nth-child(5)::before {
  color: orange;
}

#ticks_slider .e-scale :nth-child(6)::before {
  color: pink;
}

#ticks_slider .e-scale .e-custom::before {
  font-size: 10px;
}

#ticks_slider .e-scale .e-custom::before {
  top: calc(50% + -2px);
  left: calc(50% - 5px);
}

#slider_wrapper #ticks_slider .e-scale :nth-child(1)::before {
  top: calc(50% + -2px);
  left: calc(0% - 5px);
}

#slider_wrapper #ticks_slider .e-scale :nth-child(6)::before {
  top: calc(50% + -2px);
  left: calc(100% - 6px);
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Range Slider</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-react-inputs/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-react-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-react-buttons/styles/material.css" rel="stylesheet" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='element'>
    </div>
</body>

</html>