跳到主要内容

对滑块组件 Slider 样式魔改

· 阅读需 5 分钟
编程范儿

最近在浏览网站的时候看到一个有趣的滑动组件的样式,觉得很有趣。一时有兴趣就去用代码实现了一下:

这里我就不从零开始实现了,借用 Material UI Slider 快速实现,基本上就是重新写样式覆盖。

Material UI 上的 Slider 组件默认样式如下:



import Slider from '@mui/material/Slider';

export default function Main() {
<Slider
aria-label="Temperature"
defaultValue={30}
color="secondary"
/>
}

很明显,这个和上面视频中的组件在样式上相差甚远。

首先我们来剖析下组成这个组件所需要的元素有哪些?打开浏览器的元素审查,我们找到和 Slider 组件相关的元素标签,会发现主要结构如下:

<span class="MuiSlider-root">
<span class="MuiSlider-rail"></span>
<span class="MuiSlider-track"></span>
<span class="MuiSlider-thumb"></span>
</span>

这里略去一些无关紧要的元素,主要就是根元素下的类名为 MuiSlider-railMuiSlider-trackMuiSlider-thumb 的三个 span 标签组成。 接下来我们也是主要围绕这三个元素对它们的进行样式进行重写。

接下来的文章内容会通过逐步地修改,展示修改后的样式。

滑块高度

得益于 Material UI 组件的 sx 属性,可以自由地对组件的样式进行覆盖式重写。sx 的值是一个 CSS 对象,可以做到对深层子元素的样式定义。

<Slider
sx={{
height: 28
}}
/>

滑块的颜色

对于滑块的颜色只要设置滑动组件的根元素的 color 属性即可,它的子元素通过设置 currentColor 直接继承过来。 滑块底色通过设置一定的透明度来区分已滑过区域和未滑过的区域。

<Slider
sx={{
height: 28,
color: 'rgba(220,220,220,1)'
}}
/>

稍稍改变下圆角的值,继续在 sx 下追加属性 borderRadius: '5px'

拖拽按钮的样式

原来的拖拽按钮是一个圆形的,我们要将它改为细长条样式。

<Slider
sx={{
height: 28,
color: 'rgba(220,220,220,1)',
borderRadius: '5px',
'& .MuiSlider-thumb': {
width: '2px',
height: '20px',
margin: '0 4px',
borderRadius: 0,
backgroundColor: 'currentColor',
boxShadow: 'none',
border: 'none',
'&::before': { boxShadow: 'none' },
}
}}
/>

增加标签和当前值的显示

对于文字的显示,我们在滑动组件同级,新增元素标签包裹,然后采用绝对定位,让它离开当前的文档流浮动在组件的上方。

Score45

最后,完整代码如下:

import { Box, Slider } from '@mui/material';

export default function CustomSlider() {
const [score, setScore] = useState(45);
return (
<Box sx={{ position: 'relative', display: 'flex' }}>
<Slider
defaultValue={score}
aria-label='Score'
min={1}
step={1}
max={100}
sx={{
height: 28,
color: 'rgba(220,220,220,1)',
borderRadius: '5px',
'& .MuiSlider-thumb': {
width: '2px',
height: '20px',
margin: '0 4px',
borderRadius: 0,
backgroundColor: 'currentColor',
boxShadow: 'none',
border: 'none',
'&::before': { boxShadow: 'none' },
},
'& .MuiSlider-rail': {
position: 'relative'
},
'& .MuiSlider-track': {
border: 'none'
}
}}
onChange={(e, val) => setScore(val)}
/>
<Box sx={{
width: '100%',
display: 'flex',
position: 'absolute',
height: '100%',
top: 0,
zIndex: 1,
alignItems: 'center',
justifyContent: 'space-between',
padding: '0 8px',
pointerEvents: 'none',
fontSize: '11px',
color: 'rgba(0,0,0,0.56)'
}}>
<span>Score</span>
<span>{score}</span>
</Box>
</Box>
)
}

如果你有兴趣,可以根据原理来实现其它样式的滑块组件。

太空编程
分享硬核的前端编程知识。
想及时了解前端相关资讯,请关注作者公众号“太空编程”,回复关键字,获取丰富的学习资料。