Slider
Sliders allow users to make selections from a range of values.
Continuous sliders
import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Slider from '@mui/material/Slider'; import VolumeDown from '@mui/icons-material/VolumeDown'; import VolumeUp from '@mui/icons-material/VolumeUp'; export default function ContinuousSlider() { const [value, setValue] = React.useState(30); const handleChange = (event, newValue) => { setValue(newValue); }; return ( <Box sx={{ width: 200 }}> <Stack spacing={2} direction="row" sx={{ mb: 1 }} alignItems="center"> <VolumeDown /> <Slider aria-label="Volume" value={value} onChange={handleChange} /> <VolumeUp /> </Stack> <Slider disabled defaultValue={30} aria-label="Disabled slider" /> </Box> ); }
Sizes
size="small"
.import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; export default function SliderSizes() { return ( <Box width={300}> <Slider size="small" defaultValue={70} aria-label="Small" valueLabelDisplay="auto" /> <Slider defaultValue={50} aria-label="Default" valueLabelDisplay="auto" /> </Box> ); }
Discrete sliders
marks={true}
.import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; function valuetext(value) { return `${value}°C`; } export default function DiscreteSlider() { return ( <Box sx={{ width: 300 }}> <Slider aria-label="Temperature" defaultValue={30} getAriaValueText={valuetext} valueLabelDisplay="auto" step={10} marks min={10} max={110} /> <Slider defaultValue={30} step={10} marks min={10} max={110} disabled /> </Box> ); }
Small steps
import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; function valuetext(value) { return `${value}°C`; } export default function DiscreteSliderSteps() { return ( <Box sx={{ width: 300 }}> <Slider aria-label="Small steps" defaultValue={0.00000005} getAriaValueText={valuetext} step={0.00000001} marks min={-0.00000005} max={0.0000001} valueLabelDisplay="auto" /> </Box> ); }
Custom marks
marks
prop.import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; const marks = [ { value: 0, label: '0°C', }, { value: 20, label: '20°C', }, { value: 37, label: '37°C', }, { value: 100, label: '100°C', }, ]; function valuetext(value) { return `${value}°C`; } export default function DiscreteSliderMarks() { return ( <Box sx={{ width: 300 }}> <Slider aria-label="Custom marks" defaultValue={20} getAriaValueText={valuetext} step={10} valueLabelDisplay="auto" marks={marks} /> </Box> ); }
Restricted values
marks
prop with step={null}
.import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; const marks = [ { value: 0, label: '0°C', }, { value: 20, label: '20°C', }, { value: 37, label: '37°C', }, { value: 100, label: '100°C', }, ]; function valuetext(value) { return `${value}°C`; } function valueLabelFormat(value) { return marks.findIndex((mark) => mark.value === value) + 1; } export default function DiscreteSliderValues() { return ( <Box sx={{ width: 300 }}> <Slider aria-label="Restricted values" defaultValue={20} valueLabelFormat={valueLabelFormat} getAriaValueText={valuetext} step={null} valueLabelDisplay="auto" marks={marks} /> </Box> ); }
Label always visible
valueLabelDisplay="on"
.import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; const marks = [ { value: 0, label: '0°C', }, { value: 20, label: '20°C', }, { value: 37, label: '37°C', }, { value: 100, label: '100°C', }, ]; function valuetext(value) { return `${value}°C`; } export default function DiscreteSliderLabel() { return ( <Box sx={{ width: 300 }}> <Slider aria-label="Always visible" defaultValue={80} getAriaValueText={valuetext} step={10} marks={marks} valueLabelDisplay="on" /> </Box> ); }
Range slider
value
prop.import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; function valuetext(value) { return `${value}°C`; } export default function RangeSlider() { const [value, setValue] = React.useState([20, 37]); const handleChange = (event, newValue) => { setValue(newValue); }; return ( <Box sx={{ width: 300 }}> <Slider getAriaLabel={() => 'Temperature range'} value={value} onChange={handleChange} valueLabelDisplay="auto" getAriaValueText={valuetext} /> </Box> ); }
Minimum distance
onChange
event handler. By default, when you move the pointer over a thumb while dragging another thumb, the active thumb will swap to the hovered thumb. You can disable this behavior with the disableSwap
prop. If you want the range to shift when reaching minimum distance, you can utilize the activeThumb
parameter in onChange
.import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; function valuetext(value) { return `${value}°C`; } const minDistance = 10; export default function MinimumDistanceSlider() { const [value1, setValue1] = React.useState([20, 37]); const handleChange1 = (event, newValue, activeThumb) => { if (!Array.isArray(newValue)) { return; } if (activeThumb === 0) { setValue1([Math.min(newValue[0], value1[1] - minDistance), value1[1]]); } else { setValue1([value1[0], Math.max(newValue[1], value1[0] + minDistance)]); } }; const [value2, setValue2] = React.useState([20, 37]); const handleChange2 = (event, newValue, activeThumb) => { if (!Array.isArray(newValue)) { return; } if (newValue[1] - newValue[0] < minDistance) { if (activeThumb === 0) { const clamped = Math.min(newValue[0], 100 - minDistance); setValue2([clamped, clamped + minDistance]); } else { const clamped = Math.max(newValue[1], minDistance); setValue2([clamped - minDistance, clamped]); } } else { setValue2(newValue); } }; return ( <Box sx={{ width: 300 }}> <Slider getAriaLabel={() => 'Minimum distance'} value={value1} onChange={handleChange1} valueLabelDisplay="auto" getAriaValueText={valuetext} disableSwap /> <Slider getAriaLabel={() => 'Minimum distance shift'} value={value2} onChange={handleChange2} valueLabelDisplay="auto" getAriaValueText={valuetext} disableSwap /> </Box> ); }
Slider with input field
Volume
import * as React from 'react'; import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; import MuiInput from '@mui/material/Input'; import VolumeUp from '@mui/icons-material/VolumeUp'; const Input = styled(MuiInput)` width: 42px; `; export default function InputSlider() { const [value, setValue] = React.useState(30); const handleSliderChange = (event, newValue) => { setValue(newValue); }; const handleInputChange = (event) => { setValue(event.target.value === '' ? '' : Number(event.target.value)); }; const handleBlur = () => { if (value < 0) { setValue(0); } else if (value > 100) { setValue(100); } }; return ( <Box sx={{ width: 250 }}> <Typography id="input-slider" gutterBottom> Volume </Typography> <Grid container spacing={2} alignItems="center"> <Grid item> <VolumeUp /> </Grid> <Grid item xs> <Slider value={typeof value === 'number' ? value : 0} onChange={handleSliderChange} aria-labelledby="input-slider" /> </Grid> <Grid item> <Input value={value} size="small" onChange={handleInputChange} onBlur={handleBlur} inputProps={{ step: 10, min: 0, max: 100, type: 'number', 'aria-labelledby': 'input-slider', }} /> </Grid> </Grid> </Box> ); }
Color
import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; function valuetext(value) { return `${value}°C`; } export default function ColorSlider() { return ( <Box sx={{ width: 300 }}> <Slider aria-label="Temperature" defaultValue={30} getAriaValueText={valuetext} color="secondary" /> </Box> ); }
Customization
iOS
pretto.fr
Tooltip value label
Airbnb
import * as React from 'react'; import PropTypes from 'prop-types'; import Slider, { SliderThumb } from '@mui/material/Slider'; import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import Tooltip from '@mui/material/Tooltip'; import Box from '@mui/material/Box'; function ValueLabelComponent(props) { const { children, value } = props; return ( <Tooltip enterTouchDelay={0} placement="top" title={value}> {children} </Tooltip> ); } ValueLabelComponent.propTypes = { children: PropTypes.element.isRequired, value: PropTypes.number.isRequired, }; const iOSBoxShadow = '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.13),0 0 0 1px rgba(0,0,0,0.02)'; const marks = [ { value: 0, }, { value: 20, }, { value: 37, }, { value: 100, }, ]; const IOSSlider = styled(Slider)(({ theme }) => ({ color: theme.palette.mode === 'dark' ? '#3880ff' : '#3880ff', height: 2, padding: '15px 0', '& .MuiSlider-thumb': { height: 28, width: 28, backgroundColor: '#fff', boxShadow: iOSBoxShadow, '&:focus, &:hover, &.Mui-active': { boxShadow: '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', // Reset on touch devices, it doesn't add specificity '@media (hover: none)': { boxShadow: iOSBoxShadow, }, }, }, '& .MuiSlider-valueLabel': { fontSize: 12, fontWeight: 'normal', top: -6, backgroundColor: 'unset', color: theme.palette.text.primary, '&:before': { display: 'none', }, '& *': { background: 'transparent', color: theme.palette.mode === 'dark' ? '#fff' : '#000', }, }, '& .MuiSlider-track': { border: 'none', }, '& .MuiSlider-rail': { opacity: 0.5, backgroundColor: '#bfbfbf', }, '& .MuiSlider-mark': { backgroundColor: '#bfbfbf', height: 8, width: 1, '&.MuiSlider-markActive': { opacity: 1, backgroundColor: 'currentColor', }, }, })); const PrettoSlider = styled(Slider)({ color: '#52af77', height: 8, '& .MuiSlider-track': { border: 'none', }, '& .MuiSlider-thumb': { height: 24, width: 24, backgroundColor: '#fff', border: '2px solid currentColor', '&:focus, &:hover, &.Mui-active, &.Mui-focusVisible': { boxShadow: 'inherit', }, '&:before': { display: 'none', }, }, '& .MuiSlider-valueLabel': { lineHeight: 1.2, fontSize: 12, background: 'unset', padding: 0, width: 32, height: 32, borderRadius: '50% 50% 50% 0', backgroundColor: '#52af77', transformOrigin: 'bottom left', transform: 'translate(50%, -100%) rotate(-45deg) scale(0)', '&:before': { display: 'none' }, '&.MuiSlider-valueLabelOpen': { transform: 'translate(50%, -100%) rotate(-45deg) scale(1)', }, '& > *': { transform: 'rotate(45deg)', }, }, }); const AirbnbSlider = styled(Slider)(({ theme }) => ({ color: '#3a8589', height: 3, padding: '13px 0', '& .MuiSlider-thumb': { height: 27, width: 27, backgroundColor: '#fff', border: '1px solid currentColor', '&:hover': { boxShadow: '0 0 0 8px rgba(58, 133, 137, 0.16)', }, '& .airbnb-bar': { height: 9, width: 1, backgroundColor: 'currentColor', marginLeft: 1, marginRight: 1, }, }, '& .MuiSlider-track': { height: 3, }, '& .MuiSlider-rail': { color: theme.palette.mode === 'dark' ? '#bfbfbf' : '#d8d8d8', opacity: theme.palette.mode === 'dark' ? undefined : 1, height: 3, }, })); function AirbnbThumbComponent(props) { const { children, ...other } = props; return ( <SliderThumb {...other}> {children} <span className="airbnb-bar" /> <span className="airbnb-bar" /> <span className="airbnb-bar" /> </SliderThumb> ); } AirbnbThumbComponent.propTypes = { children: PropTypes.node, }; export default function CustomizedSlider() { return ( <Box sx={{ width: 320 }}> <Typography gutterBottom>iOS</Typography> <IOSSlider aria-label="ios slider" defaultValue={60} marks={marks} valueLabelDisplay="on" /> <Box sx={{ m: 3 }} /> <Typography gutterBottom>pretto.fr</Typography> <PrettoSlider valueLabelDisplay="auto" aria-label="pretto slider" defaultValue={20} /> <Box sx={{ m: 3 }} /> <Typography gutterBottom>Tooltip value label</Typography> <Slider valueLabelDisplay="auto" components={{ ValueLabel: ValueLabelComponent, }} aria-label="custom thumb label" defaultValue={20} /> <Box sx={{ m: 3 }} /> <Typography gutterBottom>Airbnb</Typography> <AirbnbSlider components={{ Thumb: AirbnbThumbComponent }} getAriaLabel={(index) => (index === 0 ? 'Minimum price' : 'Maximum price')} defaultValue={[20, 40]} /> </Box> ); }
Music player

คนเก่าเขาทำไว้ดี (Can't win)
Chilling Sunday — คนเก่าเขาทำไว้ดี
0:32
-2:48
import * as React from 'react'; import { styled, useTheme } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; import IconButton from '@mui/material/IconButton'; import Stack from '@mui/material/Stack'; import PauseRounded from '@mui/icons-material/PauseRounded'; import PlayArrowRounded from '@mui/icons-material/PlayArrowRounded'; import FastForwardRounded from '@mui/icons-material/FastForwardRounded'; import FastRewindRounded from '@mui/icons-material/FastRewindRounded'; import VolumeUpRounded from '@mui/icons-material/VolumeUpRounded'; import VolumeDownRounded from '@mui/icons-material/VolumeDownRounded'; const WallPaper = styled('div')({ position: 'absolute', width: '100%', height: '100%', top: 0, left: 0, overflow: 'hidden', background: 'linear-gradient(rgb(255, 38, 142) 0%, rgb(255, 105, 79) 100%)', transition: 'all 500ms cubic-bezier(0.175, 0.885, 0.32, 1.275) 0s', '&:before': { content: '""', width: '140%', height: '140%', position: 'absolute', top: '-40%', right: '-50%', background: 'radial-gradient(at center center, rgb(62, 79, 249) 0%, rgba(62, 79, 249, 0) 64%)', }, '&:after': { content: '""', width: '140%', height: '140%', position: 'absolute', bottom: '-50%', left: '-30%', background: 'radial-gradient(at center center, rgb(247, 237, 225) 0%, rgba(247, 237, 225, 0) 70%)', transform: 'rotate(30deg)', }, }); const Widget = styled('div')(({ theme }) => ({ padding: 16, borderRadius: 16, width: 343, maxWidth: '100%', margin: 'auto', position: 'relative', zIndex: 1, backgroundColor: theme.palette.mode === 'dark' ? 'rgba(0,0,0,0.6)' : 'rgba(255,255,255,0.4)', backdropFilter: 'blur(40px)', })); const CoverImage = styled('div')({ width: 100, height: 100, objectFit: 'cover', overflow: 'hidden', flexShrink: 0, borderRadius: 8, backgroundColor: 'rgba(0,0,0,0.08)', '& > img': { width: '100%', }, }); const TinyText = styled(Typography)({ fontSize: '0.75rem', opacity: 0.38, fontWeight: 500, letterSpacing: 0.2, }); export default function MusicPlayerSlider() { const theme = useTheme(); const duration = 200; // seconds const [position, setPosition] = React.useState(32); const [paused, setPaused] = React.useState(false); function formatDuration(value) { const minute = Math.floor(value / 60); const secondLeft = value - minute * 60; return `${minute}:${secondLeft < 9 ? `0${secondLeft}` : secondLeft}`; } const mainIconColor = theme.palette.mode === 'dark' ? '#fff' : '#000'; const lightIconColor = theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.4)' : 'rgba(0,0,0,0.4)'; return ( <Box sx={{ width: '100%', overflow: 'hidden' }}> <Widget> <Box sx={{ display: 'flex', alignItems: 'center' }}> <CoverImage> <img alt="can't win - Chilling Sunday" src="/material-ui-static/images/sliders/chilling-sunday.jpg" /> </CoverImage> <Box sx={{ ml: 1.5, minWidth: 0 }}> <Typography variant="caption" color="text.secondary" fontWeight={500}> Jun Pulse </Typography> <Typography noWrap> <b>คนเก่าเขาทำไว้ดี (Can't win)</b> </Typography> <Typography noWrap letterSpacing={-0.25}> Chilling Sunday — คนเก่าเขาทำไว้ดี </Typography> </Box> </Box> <Slider aria-label="time-indicator" size="small" value={position} min={0} step={1} max={duration} onChange={(_, value) => setPosition(value)} sx={{ color: theme.palette.mode === 'dark' ? '#fff' : 'rgba(0,0,0,0.87)', height: 4, '& .MuiSlider-thumb': { width: 8, height: 8, transition: '0.3s cubic-bezier(.47,1.64,.41,.8)', '&:before': { boxShadow: '0 2px 12px 0 rgba(0,0,0,0.4)', }, '&:hover, &.Mui-focusVisible': { boxShadow: `0px 0px 0px 8px ${ theme.palette.mode === 'dark' ? 'rgb(255 255 255 / 16%)' : 'rgb(0 0 0 / 16%)' }`, }, '&.Mui-active': { width: 20, height: 20, }, }, '& .MuiSlider-rail': { opacity: 0.28, }, }} /> <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mt: -2, }} > <TinyText>{formatDuration(position)}</TinyText> <TinyText>-{formatDuration(duration - position)}</TinyText> </Box> <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', mt: -1, }} > <IconButton aria-label="previous song"> <FastRewindRounded fontSize="large" htmlColor={mainIconColor} /> </IconButton> <IconButton aria-label={paused ? 'play' : 'pause'} onClick={() => setPaused(!paused)} > {paused ? ( <PlayArrowRounded sx={{ fontSize: '3rem' }} htmlColor={mainIconColor} /> ) : ( <PauseRounded sx={{ fontSize: '3rem' }} htmlColor={mainIconColor} /> )} </IconButton> <IconButton aria-label="next song"> <FastForwardRounded fontSize="large" htmlColor={mainIconColor} /> </IconButton> </Box> <Stack spacing={2} direction="row" sx={{ mb: 1, px: 1 }} alignItems="center"> <VolumeDownRounded htmlColor={lightIconColor} /> <Slider aria-label="Volume" defaultValue={30} sx={{ color: theme.palette.mode === 'dark' ? '#fff' : 'rgba(0,0,0,0.87)', '& .MuiSlider-track': { border: 'none', }, '& .MuiSlider-thumb': { width: 24, height: 24, backgroundColor: '#fff', '&:before': { boxShadow: '0 4px 8px rgba(0,0,0,0.4)', }, '&:hover, &.Mui-focusVisible, &.Mui-active': { boxShadow: 'none', }, }, }} /> <VolumeUpRounded htmlColor={lightIconColor} /> </Stack> </Widget> <WallPaper /> </Box> ); }
Vertical sliders
import * as React from 'react'; import Stack from '@mui/material/Stack'; import Slider from '@mui/material/Slider'; function valuetext(value) { return `${value}°C`; } const marks = [ { value: 0, label: '0°C', }, { value: 20, label: '20°C', }, { value: 37, label: '37°C', }, { value: 100, label: '100°C', }, ]; export default function VerticalSlider() { return ( <Stack sx={{ height: 300 }} spacing={1} direction="row"> <Slider aria-label="Temperature" orientation="vertical" getAriaValueText={valuetext} defaultValue={30} /> <Slider aria-label="Temperature" orientation="vertical" defaultValue={30} disabled /> <Slider getAriaLabel={() => 'Temperature'} orientation="vertical" getAriaValueText={valuetext} defaultValue={[20, 37]} marks={marks} /> </Stack> ); }
<Slider orientation="vertical" />
as horizontal (chromium issue #1158217). By applying -webkit-appearance: slider-vertical;
the slider is exposed as vertical.-webkit-appearance: slider-vertical;
keyboard navigation for horizontal keys (Arrow Left, Arrow Right) is reversed (chromium issue #1162640). Usually, up and right should increase and left and down should decrease the value. If you apply -webkit-appearance
you could prevent keyboard navigation for horizontal arrow keys for a truly vertical slider. This might be less confusing to users compared to a change in direction.import * as React from 'react'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; export default function VerticalSlider() { function preventHorizontalKeyboardNavigation(event) { if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') { event.preventDefault(); } } return ( <Box sx={{ height: 300 }}> <Slider sx={{ '& input[type="range"]': { WebkitAppearance: 'slider-vertical', }, }} orientation="vertical" defaultValue={30} aria-label="Temperature" onKeyDown={preventHorizontalKeyboardNavigation} /> </Box> ); }
Track
Removed track
track={false}
.Removed track
Removed track range slider
import * as React from 'react'; import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; const Separator = styled('div')( ({ theme }) => ` height: ${theme.spacing(3)}; `, ); const marks = [ { value: 0, label: '0°C', }, { value: 20, label: '20°C', }, { value: 37, label: '37°C', }, { value: 100, label: '100°C', }, ]; function valuetext(value) { return `${value}°C`; } export default function TrackFalseSlider() { return ( <Box sx={{ width: 250 }}> <Typography id="track-false-slider" gutterBottom> Removed track </Typography> <Slider track={false} aria-labelledby="track-false-slider" getAriaValueText={valuetext} defaultValue={30} marks={marks} /> <Separator /> <Typography id="track-false-range-slider" gutterBottom> Removed track range slider </Typography> <Slider track={false} aria-labelledby="track-false-range-slider" getAriaValueText={valuetext} defaultValue={[20, 37, 50]} marks={marks} /> </Box> ); }
Inverted track
track="inverted"
.Inverted track
Inverted track range
import * as React from 'react'; import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; const Separator = styled('div')( ({ theme }) => ` height: ${theme.spacing(3)}; `, ); const marks = [ { value: 0, label: '0°C', }, { value: 20, label: '20°C', }, { value: 37, label: '37°C', }, { value: 100, label: '100°C', }, ]; function valuetext(value) { return `${value}°C`; } export default function TrackInvertedSlider() { return ( <Box sx={{ width: 250 }}> <Typography id="track-inverted-slider" gutterBottom> Inverted track </Typography> <Slider track="inverted" aria-labelledby="track-inverted-slider" getAriaValueText={valuetext} defaultValue={30} marks={marks} /> <Separator /> <Typography id="track-inverted-range-slider" gutterBottom> Inverted track range </Typography> <Slider track="inverted" aria-labelledby="track-inverted-range-slider" getAriaValueText={valuetext} defaultValue={[20, 37]} marks={marks} /> </Box> ); }
Non-linear scale
scale
prop to represent the value
on a different scale.Storage: 1 MB
import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; function valueLabelFormat(value) { const units = ['KB', 'MB', 'GB', 'TB']; let unitIndex = 0; let scaledValue = value; while (scaledValue >= 1024 && unitIndex < units.length - 1) { unitIndex += 1; scaledValue /= 1024; } return `${scaledValue} ${units[unitIndex]}`; } function calculateValue(value) { return 2 ** value; } export default function NonLinearSlider() { const [value, setValue] = React.useState(10); const handleChange = (event, newValue) => { if (typeof newValue === 'number') { setValue(newValue); } }; return ( <Box sx={{ width: 250 }}> <Typography id="non-linear-slider" gutterBottom> Storage: {valueLabelFormat(calculateValue(value))} </Typography> <Slider value={value} min={5} step={1} max={30} scale={calculateValue} getAriaValueText={valueLabelFormat} valueLabelFormat={valueLabelFormat} onChange={handleChange} valueLabelDisplay="auto" aria-labelledby="non-linear-slider" /> </Box> ); }
Unstyled
import SliderUnstyled from '@mui/base/SliderUnstyled';
import * as React from 'react'; import { styled, alpha, Box } from '@mui/system'; import SliderUnstyled from '@mui/base/SliderUnstyled'; const StyledSlider = styled(SliderUnstyled)( ({ theme }) => ` color: ${theme.palette.mode === 'light' ? '#1976d2' : '#90caf9'}; height: 4px; width: 100%; padding: 13px 0; display: inline-block; position: relative; cursor: pointer; touch-action: none; -webkit-tap-highlight-color: transparent; opacity: 0.75; &:hover { opacity: 1; } & .MuiSlider-rail { display: block; position: absolute; width: 100%; height: 4px; border-radius: 2px; background-color: currentColor; opacity: 0.38; } & .MuiSlider-track { display: block; position: absolute; height: 4px; border-radius: 2px; background-color: currentColor; } & .MuiSlider-thumb { position: absolute; width: 14px; height: 14px; margin-left: -6px; margin-top: -5px; box-sizing: border-box; border-radius: 50%; outline: 0; border: 2px solid currentColor; background-color: #fff; :hover, &.Mui-focusVisible { box-shadow: 0 0 0 0.25rem ${alpha( theme.palette.mode === 'light' ? '#1976d2' : '#90caf9', 0.15, )}; } &.Mui-active { box-shadow: 0 0 0 0.25rem ${alpha( theme.palette.mode === 'light' ? '#1976d2' : '#90caf9', 0.3, )}; } } `, ); export default function UnstyledSlider() { return ( <Box sx={{ width: 300 }}> <StyledSlider defaultValue={10} /> </Box> ); }
Accessibility
- Each thumb has a user-friendly label (
aria-label
,aria-labelledby
orgetAriaLabel
prop). - Each thumb has a user-friendly text for its current value. This is not required if the value matches the semantics of the label. You can change the name with the
getAriaValueText
oraria-valuetext
prop.
Limitations
IE 11
.MuiSlider-valueLabel { left: calc(-50% - 4px); }