Enhance your forms with our customizable Angular Range Slider component for advanced range selection.
Available in Other JavaScript Frameworks
CoreUI Angular Range Slider is also available for Bootstrap, React, and Vue. Explore framework-specific implementations below:
Overview
The Angular Range Slider component allows users to select a value or range of values within a predefined range. Unlike the standard <input type="range">, the Range Slider offers enhanced customization options, including multiple handles, labels, tooltips, and vertical orientation. It ensures consistent styling across browsers and provides a rich set of features for advanced use cases.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-overview',
imports: [RangeSliderComponent],
templateUrl: './range-slider-overview.component.html',
styleUrl: './range-slider-overview.component.scss'
})
export class RangeSliderOverviewComponent {
handleValueChange($event: number | number[]) {
console.log('handleValueChange', $event);
}
}<c-range-slider
(valueChange)="handleValueChange($event)"
[labels]="['Low', 'Medium', 'High']"
[value]="[25, 75]"
/>:host {
.range-slider {
margin-bottom: 1rem !important;
}
}Features
- Multiple Handles: Select single or multiple values within the range.
- Custom Labels: Display labels at specific points on the slider.
- Tooltips: Show dynamic tooltips displaying current values.
- Vertical Orientation: Rotate the slider for vertical layouts.
- Clickable Labels: Enable users to click on labels to set slider values.
- Disabled State: Disable the slider to prevent user interaction.
Angular Range Slider Example
Create a simple range slider with default settings.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-example',
imports: [RangeSliderComponent],
templateUrl: './range-slider-example.component.html',
styleUrl: './range-slider-example.component.scss'
})
export class RangeSliderExampleComponent {}<c-range-slider [value]="[50]" />Multiple handles
Enable multiple handles to allow the selection of a range or/and multiple values.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-multiple-handles',
imports: [RangeSliderComponent],
templateUrl: './range-slider-multiple-handles.component.html',
styleUrl: './range-slider-multiple-handles.component.scss'
})
export class RangeSliderMultipleHandlesComponent {}<c-range-slider [value]="[20,40]" />
<c-range-slider [value]="[20,40, 60]" />
<c-range-slider [value]="[20,40, 60, 80]" />:host {
.range-slider:not(:last-child) {
margin-bottom: 1rem !important;
}
}Vertical Range Slider
Rotate the slider to a vertical orientation.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-vertical',
imports: [RangeSliderComponent],
templateUrl: './range-slider-vertical.component.html'
})
export class RangeSliderVerticalComponent {}<div class="d-flex">
<c-range-slider [value]="20" class="me-3" vertical />
<c-range-slider [value]="[20, 80]" class="me-3" vertical />
<c-range-slider [value]="[20, 80, 100]" vertical />
</div>
Disabled
Disable the slider to prevent user interaction.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-disabled',
templateUrl: './range-slider-disabled.component.html',
imports: [RangeSliderComponent],
styleUrl: './range-slider-disabled.component.scss'
})
export class RangeSliderDisabledComponent {}<c-range-slider [value]="50" disabled />
<c-range-slider [value]="[50, 75]" disabled />:host {
.range-slider:not(:last-child) {
margin-bottom: 1rem !important;
}
}Min and max
Angular Range Slider component has implicit values for min and max — 0 and 100, respectively. You may specify new values for those using the min and max attributes.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-min-max',
imports: [RangeSliderComponent],
templateUrl: './range-slider-min-max.component.html',
styleUrl: './range-slider-min-max.component.scss'
})
export class RangeSliderMinMaxComponent {}<c-range-slider [value]="50" max="150" min="-50" />
<c-range-slider [value]="[50, 75]" max="150" min="-50" />:host {
.range-slider:not(:last-child) {
margin-bottom: 1rem !important;
}
}Steps
Range Slider inputs automatically “snap” to whole numbers. To modify this behavior, set a step value.
In the example below:
- we increase the number of steps by specifying
step="0.25" - we decrease the number of steps by specifying
step="5"
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-steps',
imports: [RangeSliderComponent],
templateUrl: './range-slider-steps.component.html',
styleUrl: './range-slider-steps.component.scss'
})
export class RangeSliderStepsComponent {}<c-range-slider [value]="50" step=".25" />
<c-range-slider [value]="[50, 75]" step="5" />:host {
.range-slider:not(:last-child) {
margin-bottom: 1rem !important;
}
}Distance
Sets the minimum distance between multiple slider handles by setting distance and ensures that the handles do not overlap or get too close.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-distance',
imports: [RangeSliderComponent],
templateUrl: './range-slider-distance.component.html'
})
export class RangeSliderDistanceComponent {}<c-range-slider [value]="[50, 75]" distance="10" />Labels
Add labels to specific points on the slider for better context. If you provide an array of strings, as in the example below, then labels will be spaced at equal distances from the beginning to the end of the slider.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-labels',
imports: [RangeSliderComponent],
templateUrl: './range-slider-labels.component.html',
styleUrl: './range-slider-labels.component.scss'
})
export class RangeSliderLabelsComponent {}<c-range-slider [labels]="['Start', 'Middle', 'End']" [value]="[30, 70]" />:host {
.range-slider {
margin-bottom: 1rem !important;
}
}Labels customization
Labels can be configured as an array of strings or objects. When using objects, you can specify additional properties like value, label, class, and style.
import { Component } from '@angular/core';
import { Label, RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-labels-customization',
imports: [RangeSliderComponent],
templateUrl: './range-slider-labels-customization.component.html',
styleUrl: './range-slider-labels-customization.component.scss'
})
export class RangeSliderLabelsCustomizationComponent {
readonly labels: Label[] = [
{
value: -50,
label: '-50°C',
class: 'text-info fst-italic'
},
{
value: 0,
label: '0°C',
style: {
fontWeight: 'bold'
}
},
{
value: 20,
label: '20°C',
class: ['text-warning']
},
{
value: 100,
label: '100°C',
class: { 'text-danger': true }
}
];
readonly tooltipsFormatFn = (value: number) => `${value}°C`;
}<c-range-slider
[labels]="labels"
[tooltipsFormat]="tooltipsFormatFn"
[value]="[-10, 40]"
max="100"
min="-50"
/>:host {
.range-slider {
margin-bottom: 1rem !important;
}
}Clickable labels
By default, users can click on labels to set the slider to specific values. You can disable this feature by setting clickableLabels to false.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-clickable-labels',
imports: [RangeSliderComponent],
templateUrl: './range-slider-clickable-labels.component.html',
styleUrl: './range-slider-clickable-labels.component.scss'
})
export class RangeSliderClickableLabelsComponent {}<c-range-slider
[labels]="['Low', 'Medium', 'High']"
[value]="[25, 80]"
[clickableLabels]="false"
/>:host {
.range-slider {
margin-bottom: 1rem !important;
}
}Tooltips
By default, tooltips display the current value of each handle. You can disable tooltips by setting tooltips to false.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-tooltips',
imports: [RangeSliderComponent],
templateUrl: './range-slider-tooltips.component.html'
})
export class RangeSliderTooltipsComponent {}<c-range-slider [value]="[40, 60]" [tooltips]="false" />Tooltips formatting
Customize the content of tooltips using the tooltipsFormat property. This should be a function that formats the tooltip text based on the current value.
import { Component } from '@angular/core';
import { Label, RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-tooltips-formatting',
imports: [RangeSliderComponent],
templateUrl: './range-slider-tooltips-formatting.component.html',
styleUrl: './range-slider-tooltips-formatting.component.scss'
})
export class RangeSliderTooltipsFormattingComponent {
readonly tooltipsFormatFn = (value: number) => `$${value}`;
readonly labels: Label[] = [
{
value: 0,
label: '$0'
},
{
value: 250,
label: '$250'
},
{
value: 500,
label: '$500'
},
{
value: 1000,
label: '$1000'
}
];
}<c-range-slider
[labels]="labels"
[tooltipsFormat]="tooltipsFormatFn"
[value]="[100, 350]"
max="1000"
/>:host {
.range-slider {
margin-bottom: 1rem !important;
}
}Track
The track property allows you to customize how the slider’s track is displayed. By default, the track property is set to fill enabling dynamic filling of the track based on the slider’s current value(s). This means the filled portion of the track will adjust automatically as the slider handle move, offering a responsive visual representation of the selected range.
Disable filling
If you set track to false, the slider’s track will not display any fill. Only the default track background will be visible, which can be useful for minimalist designs or when you use more then two handles.
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-disable-filling',
imports: [RangeSliderComponent],
templateUrl: './range-slider-disable-filling.component.html',
styleUrl: './range-slider-disable-filling.component.scss'
})
export class RangeSliderDisableFillingComponent {}<c-range-slider [track]="false" [value]="50" />
<c-range-slider [track]="false" [value]="[50,75]" />
<c-range-slider [track]="false" [value]="[25,50,75]" />:host {
.range-slider:not(:last-child) {
margin-bottom: 1rem !important;
}
}Forms
Angular handles user input through reactive and template-driven forms. CoreUI Range Slider supports both approaches.
Reactive
The Angular Range Slider component can be used in reactive forms. You can bind the slider’s value to a form control using the formControlName directive.
import { AsyncPipe, JsonPipe } from '@angular/common';
import { Component } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-reactive',
imports: [RangeSliderComponent, ReactiveFormsModule, JsonPipe, AsyncPipe],
templateUrl: './range-slider-reactive.component.html',
styleUrl: './range-slider-reactive.component.scss'
})
export class RangeSliderReactiveComponent {
readonly formGroup = new FormGroup({
rangeSlider: new FormControl([50, 75]),
singleSlider: new FormControl({ value: 60, disabled: false })
});
readonly formGroup$ = this.formGroup.valueChanges;
}<form [formGroup]="formGroup">
<c-range-slider formControlName="rangeSlider"/>
<c-range-slider formControlName="singleSlider" />
</form>
<hr>
<span > Form value: {{ formGroup$ | async | json }}</span>
:host {
.range-slider:not(:last-child) {
margin-bottom: 1rem !important;
}
}Template-driven
The Angular Range Slider component can be used in template-driven forms. You can bind the slider’s value to a template variable using the ngModel directive.
import { JsonPipe } from '@angular/common';
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-template-driven',
imports: [RangeSliderComponent, JsonPipe, FormsModule],
templateUrl: './range-slider-template-driven.component.html',
styleUrl: './range-slider-template-driven.component.scss'
})
export class RangeSliderTemplateDrivenComponent {
readonly singleValue = signal(60);
readonly rangeValue = signal([40, 75]);
}<form #form="ngForm">
<c-range-slider [(ngModel)]="rangeValue" name="rangeSlider" />
<c-range-slider [(ngModel)]="singleValue" name="singleSlider" />
</form>
<hr>
<span> Form value: {{ form.value | json }}</span>
:host {
.range-slider:not(:last-child) {
margin-bottom: 1rem !important;
}
}Accessibility
The Angular Range Slider component is built with accessibility in mind. Each slider handle includes the following ARIA attributes:
role:slideraria-valuemin: Minimum valuearia-valuemax: Maximum valuearia-valuenow: Current valuearia-orientation:horizontalorvertical
Additionally, ensure that labels and tooltips are clear and descriptive to provide the best experience for all users.
Customizing
CSS variables
Angular CoreUI Range Sliders use local CSS variables on .range-slider class for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
.range-slider {
--cui-range-slider-track-width: #{$range-slider-track-width};
--cui-range-slider-track-height: #{$range-slider-track-height};
--cui-range-slider-track-cursor: #{$range-slider-track-cursor};
--cui-range-slider-track-bg: #{$range-slider-track-bg};
--cui-range-slider-track-border-radius: #{$range-slider-track-border-radius};
--cui-range-slider-track-box-shadow: #{$range-slider-track-box-shadow};
--cui-range-slider-track-in-range-bg: #{$range-slider-track-in-range-bg};
--cui-range-slider-disabled-track-in-range-bg: #{$range-slider-disabled-track-in-range-bg};
--cui-range-slider-label-padding-y: #{$range-slider-label-padding-y};
--cui-range-slider-label-padding-x: #{$range-slider-label-padding-x};
--cui-range-slider-label-font-size: #{$range-slider-label-font-size};
--cui-range-slider-label-color: #{$range-slider-label-color};
--cui-range-slider-thumb-width: #{$range-slider-thumb-width};
--cui-range-slider-thumb-height: #{$range-slider-thumb-height};
--cui-range-slider-thumb-bg: #{$range-slider-thumb-bg};
--cui-range-slider-thumb-border: #{$range-slider-thumb-border};
--cui-range-slider-thumb-border-radius: #{$range-slider-thumb-border-radius};
--cui-range-slider-thumb-box-shadow: #{$range-slider-thumb-box-shadow};
--cui-range-slider-thumb-focus-box-shadow: #{$range-slider-thumb-focus-box-shadow};
--cui-range-slider-thumb-active-bg: #{$range-slider-thumb-active-bg};
--cui-range-slider-thumb-disabled-bg: #{$range-slider-thumb-disabled-bg};
--cui-range-slider-thumb-transition: #{$range-slider-thumb-transition};
--cui-range-slider-tooltip-zindex: #{$zindex-tooltip};
--cui-range-slider-tooltip-padding-y: #{$range-slider-tooltip-padding-y};
--cui-range-slider-tooltip-padding-x: #{$range-slider-tooltip-padding-x};
--cui-range-slider-tooltip-margin-end: #{$range-slider-tooltip-margin-end};
--cui-range-slider-tooltip-margin-bottom: #{$range-slider-tooltip-margin-bottom};
--cui-range-slider-tooltip-font-size: #{$range-slider-tooltip-font-size};
--cui-range-slider-tooltip-color: #{$range-slider-tooltip-color};
--cui-range-slider-tooltip-bg: #{$range-slider-tooltip-bg};
--cui-range-slider-tooltip-border-radius: #{$range-slider-tooltip-border-radius};
--cui-range-slider-tooltip-box-shadow: #{$range-slider-tooltip-box-shadow};
--cui-range-slider-tooltip-transition: #{$range-slider-tooltip-transition};
--cui-range-slider-tooltip-arrow-width: #{$range-slider-tooltip-arrow-width};
--cui-range-slider-tooltip-arrow-height: #{$range-slider-tooltip-arrow-height};
}
.range-slider.vertical {
--cui-range-slider-vertical-track-width: #{$range-slider-vertical-track-width};
--cui-range-slider-vertical-track-height: #{$range-slider-vertical-track-height};
}How to use CSS variables
import { NgStyle } from '@angular/common';
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
selector: 'docs-range-slider-css-variables',
imports: [NgStyle, RangeSliderComponent],
templateUrl: './range-slider-css-variables.component.html'
})
export class RangeSliderCssVariablesComponent {
cssVars: Record<string, any> = {
'--cui-range-slider-thumb-bg': 'green',
'--cui-range-slider-track-bg': 'red',
'--cui-range-slider-track-in-range-bg': 'blue'
};
}@let vars = {
'--cui-range-slider-thumb-bg': 'red',
'--cui-range-slider-track-bg': 'var(--cui-success-bg-subtle)',
'--cui-range-slider-track-in-range-bg': 'var(--cui-success)'
};
<c-range-slider [ngStyle]="vars" [value]="[11, 42]" />SASS variables
$range-slider-track-width: 100% !default;
$range-slider-track-height: .5rem !default;
$range-slider-track-cursor: pointer !default;
$range-slider-track-bg: var(--cui-secondary-bg) !default;
$range-slider-track-border-radius: 1rem !default;
$range-slider-track-box-shadow: var(--cui-box-shadow-inset) !default;
$range-slider-track-in-range-bg: rgba(var(--cui-primary-rgb), .5) !default;
$range-slider-disabled-track-in-range-bg: rgba(var(--cui-secondary-rgb), .375) !default;
$range-slider-label-padding-y: 0 !default;
$range-slider-label-padding-x: 0 !default;
$range-slider-label-font-size: $font-size-sm !default;
$range-slider-label-color: var(--cui-body-color) !default;
$range-slider-thumb-width: 1rem !default;
$range-slider-thumb-height: $range-slider-thumb-width !default;
$range-slider-thumb-bg: $component-active-bg !default;
$range-slider-thumb-border: 0 !default;
$range-slider-thumb-border-radius: 1rem !default;
$range-slider-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;
$range-slider-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;
$range-slider-thumb-active-bg: tint-color($primary, 70%) !default;
$range-slider-thumb-disabled-bg: rgba(var(--cui-secondary-rgb), 1) !default;
$range-slider-thumb-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
$range-slider-tooltip-padding-y: $spacer * .25 !default;
$range-slider-tooltip-padding-x: $spacer * .5 !default;
$range-slider-tooltip-margin-end: .25rem !default;
$range-slider-tooltip-margin-bottom: .25rem !default;
$range-slider-tooltip-font-size: $font-size-sm !default;
$range-slider-tooltip-color: var(--cui-body-color) !default;
$range-slider-tooltip-bg: var(--cui-secondary-bg) !default;
$range-slider-tooltip-border-radius: var(--cui-border-radius) !default;
$range-slider-tooltip-box-shadow: var(--cui-box-shadow) !default;
$range-slider-tooltip-transition: visibility .15s, opacity .15s ease !default;
$range-slider-tooltip-arrow-width: .8rem !default;
$range-slider-tooltip-arrow-height: .4rem !default;
$range-slider-vertical-track-width: .5rem !default;
$range-slider-vertical-track-height: 10rem !default;API reference
Range Slider Module
import { NgModule } from '@angular/core';
import { RangeSliderModule } from '@coreui/angular';
@NgModule({
imports: [RangeSliderModule]
})
export class CustomAppModule {}Range Slider Standalone
import { Component } from '@angular/core';
import { RangeSliderComponent } from '@coreui/angular';
@Component({
template: `<c-range-slider [value]="42" />`,
imports: [RangeSliderComponent],
standalone: true
})
export class CustomAppComponent {}c-range-slider
component
import { RangeSliderComponent } from '@coreui/angular-pro'Props
Events
Types
import { NgCssClass } from '@coreui/angular';
export type Label =
| {
label: number | string;
value: number;
class?: NgCssClass;
style?: Partial<CSSStyleDeclaration>;
}
| string;